如何使您的MVC控制器DRY保持Edit-> Save-> ValidateFail

Dav*_*ave 5 asp.net-mvc-4

我有一个管理用户事件,它采用可选的用户ID并显示用户编辑屏幕.这个屏幕有一个manageUserViewModel.

我的"管理"页面有一些依赖项 - 例如,PageTitle,要提交的方法等.

如果我验证失败,我需要再次显示管理屏幕,但这一次,使用传递到同一方法的视图模型.

在失败场景中提供这些依赖关系并不是很干.

如何重复依赖关系?我尝试将它们放入一个单独的方法中,但这感觉不对.

public ActionResult Manage(Guid? UserID)
    {
        User user = this._UserLogic.GetUser(UserID);

        ViewBag.Title = "User List";
        ViewBag.OnSubmit = "Save";
        ManageUserViewModel uvm = Mapper.Map<User, ManageUserViewModel>(user);

        return View("Manage", uvm);
    }


    [AcceptVerbs("POST")]
    public ActionResult Save(ManageUserViewModel uvm)
    {
        User user = this._UserLogic.GetUser(uvm.UserID);


        if (!ModelState.IsValid)

            // This is not very DRY!!!
            ViewBag.Title = "Manage User";
            ViewBag.OnSubmit = "Save";
            return View("Manage", uvm);
        }

        Mapper.Map<ManageUserViewModel, User>(uvm, user );

        this._UserLogic.SaveUser(user);

        return RedirectToAction("Manage", new { UserID = user.ID });

    }
Run Code Online (Sandbox Code Playgroud)

Rya*_*ars 1

您可以将“Manager User”标题和“Save”OnSubmit 字符串添加为 ManageUserViewModel 的属性。这意味着您不必每次调用 Save 时都将它们添加到 ViewBag 中。

您还可以创建一个 ManageUserService 来负责 AutoMapper 映射并保存用户。

您的代码将如下所示:

public ActionResult Manage(Guid? UserID)
{
    var uvm = _userService.GetById(UserId);

    return View("Manage", uvm);
}


[AcceptVerbs("POST")]
public ActionResult Save(ManageUserViewModel uvm)
{
    if (!ModelState.IsValid)
    {
        return View("Save", uvm);
    }

    _userService.Save(uvm);

    return RedirectToAction("Manage", new { UserID = uvm.ID });

}
Run Code Online (Sandbox Code Playgroud)

只需将 CRUD 逻辑和 AutoMapping 功能放入名为 UserService 的类中,即可使用控制反转将其实例注入到控制器中。

如果您不想将字符串值硬编码到视图模型本身中,则可以将这些值添加到 ApplicationResources 文件中并从视图模型中引用这些值。