HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Is this appropriate way to pass data from presentation to application layer?

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
thislayerpresentationpassapplicationwayappropriatefromdata

Problem

What is the best practices to pass data from presentation to application layer?

Currently I have something like this:

in presentation layer:

the controller:

public class ProductController : Controller
{
    private readonly IProductService _productService;

    public ProductController(IProductService productService)
    {
        _productService = productService;
    }

    public ActionResult ProductCreateAction(ProductCreateViewModel vm)
    {
        _productService.CreateProduct(vm);
        return Json(new { Ok = true });
    }
}


and the view model:

public class ProductCreateViewModel : ICreateProductCommand
{
    public string Name { get; set; }
    public int Price { get; set; }
}


in application layer:

public class ProductService : IProductService
{
    public void Create(ICreateProductCommand command)
    {
        var product = new Product(command.Name, command.Price);
        //... add to repositoey and call SaveChanges ...
    }
}

public interface ICreateProductCommand
{
    string Name { get; set; }
    int Price { get; set; }
}


(using FluentValidation here)

public class CreateProductCommandValidator : AbstractValidator
{
    public CreateProductCommandValidator()
    {
        RuleFor(x => x.Name)
            .NotEmpty();

        RuleFor(x => x.Price)
            .NotEmpty();
    }
}


  • Is it ok to continue using this approach or there are better practices?



  • Is it better to have one save action in controller or separate create/update actions?



i.e.:

public ActionResult Save(SomeViewModel vm)
{
    if(vm.Id.HasValue)
    {
        //update
    }
    else
    {
        //create
    }
}


vs.

public ActionResult Create(SomeViewModel vm)
{
    //create
}

public ActionResult Update(SomeViewModel vm)
{
    //update
}

Solution

Overall, your code is very good, there is not much to review..

In your ViewModel, you might want to use DataAnnotations to do client (using jquery unobstrusive script)/server validation ex :

public class ProductCreateViewModel : ICreateProductCommand
{
    [Required]
    public string Name { get; set; }

    [Required]
    public int Price { get; set; }
}

public ActionResult ProductCreateAction(ProductCreateViewModel vm)
{
    if(ModelState.IsValid) //Server validation of the data annotations.
    {
        _productService.CreateProduct(vm);
        return Json(new { Ok = true });
    }
}


To answer your second question, I believe it is better to use two separated actions to separate the use cases of when you will use Create vs. Update. Plus one day you might have different roles for adding and updating (it's a little hardcore but it could happen), you would want your actions to be marked with different authentication attributes (If you use MVC membership)

Code Snippets

public class ProductCreateViewModel : ICreateProductCommand
{
    [Required]
    public string Name { get; set; }

    [Required]
    public int Price { get; set; }
}

public ActionResult ProductCreateAction(ProductCreateViewModel vm)
{
    if(ModelState.IsValid) //Server validation of the data annotations.
    {
        _productService.CreateProduct(vm);
        return Json(new { Ok = true });
    }
}

Context

StackExchange Code Review Q#8549, answer score: 5

Revisions (0)

No revisions yet.