1
\$\begingroup\$

I've tried to create application with MVC N-layer pattern. I asked my buddy for a shot review, and he said, "You should separate logic from controller". But my controller only work as a ViewModel creator. I'm sure I must not create ViewModel from BusinessLayer. I need to pass data in DTO like I did here. But what about logic that takes data from DTO and puts it in ViewModel with some rules? I completely misunderstand and need assistance.

public class HomeController : Controller
{
    public ActionResult Index()
    {
        var uploadedImages = UploadedImageHandler.GetAllUploadedImages();
        var model = new IndexViewModel(uploadedImages);
        return View(model);
    }

    [HttpPost]
    public void SetDescription(string description, int id)
    {
        UploadedImageHandler.SetDescription(description, id);
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public JsonResult UploadImage(HttpPostedFileBase file)
    {
        var result = UploadedImageHandler.UploadFile(file);
        JsonResult json;

        if (result != null)
        {
            var uploadImageViewModel = new UploadedImagesViewModel
            {
                Compression = result.Compression,
                DateTime = result.DateTime.HasValue ? result.DateTime.Value.ToString("f") : null,
                Description = result.Description ?? "",
                ExifVersion = result.ExifVersion,
                ExposureTime = result.ExposureTime,
                GpsLatitude = result.GpsLatitude,
                GpsLongitude = result.GpsLongitude,
                ImagePath = result.ImagePath,
                Manufacturer = result.Manufacturer,
                Model = result.Model,
                UploadedImageId = result.UploadedImageId
            };
            var uploadResult = new UploadResultViewModel
            {
                Preview = new PreviewViewModel {Id = result.UploadedImageId, PreviewPath = result.PreviewPath},
                UploadedImage = uploadImageViewModel
            };
            json = new JsonResult
            {
                Data = uploadResult,
                ContentType = "text/html"
            };
        }
        else
        {
            json = new JsonResult
            {
                ContentType = "text/html"
            };
        }

        return json;
    }
}
\$\endgroup\$
2
\$\begingroup\$

"You should separate logic from controller"

Honestly if a colleague said that to me then I would immediately say. Great thanks. What do you think I could move out and why.

It's great to offer feedback but generic feedback like that for me was never useful and I personally always prefer specific help to follow.

Looking at that code it doesn't look like you any logic there to play with, so unless he is meaning the Model -> ViewModel mapping then yes, you could move that to a Mapping layer but I don't consider that a necessity. If you were considering that the code would probably benefit from using a tool such as AutoMapper to achieve this.

Using AutoMapper

The trick here is you define your mapping rules in the AutoMapper configuration so they can be reused whenever you need to map X -> Y.

public JsonResult UploadImage(HttpPostedFileBase file)
{
    var result = UploadedImageHandler.UploadFile(file);

    if(result == null)
    {
        return new JsonResult { ContentType = "text/html" };
    }

        // Assuming ResultModel is the class type for result
    var uploadResult = Mapper.Map<UploadResultViewModel, ResultModel>(result);

    return new JsonResult
    {
        Data = uploadResult,
        ContentType = "text/html"
    };  
}

Not using AutoMapper

No mapping framework with If statements inverted to reduce nesting as well as remove need for additional variables.

public JsonResult UploadImage(HttpPostedFileBase file)
{
    var result = UploadedImageHandler.UploadFile(file);

    if(result == null)
    {
        return new JsonResult { ContentType = "text/html" };
    }

    var uploadImageViewModel = new UploadedImagesViewModel
    {
        Compression = result.Compression,
        DateTime = result.DateTime.HasValue ? result.DateTime.Value.ToString("f") : null,
        Description = result.Description ?? "",
        ExifVersion = result.ExifVersion,
        ExposureTime = result.ExposureTime,
        GpsLatitude = result.GpsLatitude,
        GpsLongitude = result.GpsLongitude,
        ImagePath = result.ImagePath,
        Manufacturer = result.Manufacturer,
        Model = result.Model,
        UploadedImageId = result.UploadedImageId
    };

    var uploadResult = new UploadResultViewModel
    {
        Preview = new PreviewViewModel 
        {   
            Id = result.UploadedImageId, 
            PreviewPath = result.PreviewPath 
        },
        UploadedImage = uploadImageViewModel
    };

    return new JsonResult
    {
        Data = uploadResult,
        ContentType = "text/html"
    };  
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.