mvc validating binded to entitiy with reference to

2019-08-31 07:21发布

问题:

Hi just thought about mapping and binding my entity in controller. How should i correctly bind entity in model so i can use modelstate

I am creating new MenuItem using MenuItemModel.

public class MenuItemModel
{
    public List<SelectListItem> Menus { get; set; }
    public MenuItem MenuItem { get; set; }
}

where my MenuItem class is defined as follows:

public class MenuItem:Entity
{

    public virtual int MenuItemId { get; set; }
    public virtual Menu Menu { get; set; }
    [Required]
    public virtual string Name { get; set; }
    public virtual int ItemOrder { get; set; }
    public virtual string ExternalUrl { get; set; }
    public virtual DateTime Created { get; set; }
    public virtual bool Deleted { get; set; }
    public virtual DateTime? DisplayUntil { get; set; }
    public virtual User Author { get; set; }

}

now when i bind my entity in controller.

    //
    // POST: /Administrator/MenuItem/Create

    [HttpPost]
    public ActionResult Create(MenuItem menuItem)
    {
        if (ModelState.IsValid)
        {
            // do saving logic
        menuItem.Created = DateTime.Now;
        menuItem.Author = this._userProvider.GetCurrentUser();
        menuItem.Menu = _menuRepository.Load(menuItem.Menu.MenuId);

        }
        //restore
        MenuItemModel menuItemModel = new MenuItemModel();
        menuItemModel.MenuItem = menuItem;
        menuItemModel.Menus =
            this._menuRepository.All.Select(x => new SelectListItem() { Text = x.Name, Value = x.MenuId.ToString() }).ToList();

        return View(menuItemModel);
    }

the only problem is i am getting validation not for only MenuItem but for Menu, User too.

How shall set this validation to accept validation only for MenuItem Entity ?

PS i know that i can go into modelstate items and find only the entities that i need and check if they are valid but i believe there will be better way of doing this...

Any idea is appreciated.

回答1:

How shall set this validation to accept validation only for MenuItem Entity ?

You should use a view model which contains only the properties that are needed to be validated in your controller action (usually those are the properties contained on the form and entered by the user). View models are classes which are specifically designed for the requirements of a given view. A controller action should never pass/take a domain model to/from a view. A controller action should always pass/take a view model to/from a view. For example:

public class MenuItemViewModel
{
    public int MenuItemId { get; set; }

    [Required]
    public string Name { get; set; }

    ... put any properties that are contained on the form with their
        respective validation
}

then have your POST controller action take this view model as argument:

[HttpPost]
public ActionResult Create(MenuItemViewModel viewModel)
{
    if (!ModelState.IsValid)
    {
        // there were some validation errors => redisplay the view
        // so that the user can fix them
        return View(viewModel);
    }

    // at this stage validation went fine
    // TODO: map the view model back to a domain model 
    // (MenutItem or whatever you are willing to update)
    // I would recommend you AutoMapper for this task: http://automapper.codeplex.com/

    // TODO: once you get the domain model pass it to a service layer
    // method in order to perform the necessary business operation with it
    // (in your case creating a menu item)

    return RedirectToAction("Success");
}