如何在ASP.NET MVC控制器中创建GET和POST操作中的DRY

时间:2013-09-04 04:42:43

标签: c# asp.net-mvc entity-framework

我正在寻找一些关于如何使我的MVC代码更高效的帮助,因为我在我的Create GET和POST操作中重用相同的代码,这违反了MVC的DRY原则。

具体来说,我正在使用EntityFramework,并且有一个控制器使用以下代码填充ViewModel:

public ActionResult Create()
    {

        var fileManagers = from x in db.UserProfiles
                            select x;

        var estimators = from x in db.UserProfiles
                                select x;

        var projectManagers = from x in db.UserProfiles
                            select x;

        var jobStatuses = from x in db.JobStatuses
                            select x;           

        JobViewModel viewModel = new JobViewModel
        {
            Job = new Job(),
            FileManagers = fileManagers.Select(x => new SelectListItem
            {
                Value = x.UserName,
                Text = x.FirstName + " " + x.LastName
            }).ToList(),
            Estimators = estimators.Select(x => new SelectListItem
            {
                Value = x.UserName,
                Text = x.FirstName + " " + x.LastName
            }).ToList(),
            ProjectManagers = projectManagers.Select(x => new SelectListItem
            {
                Value = x.UserName,
                Text = x.FirstName + " " + x.LastName
            }).ToList()
        };

        return View(viewModel);
    }

在我的POST函数中,我正在检查模型的有效性,然后再次写出相同的代码,以便在模型无效的情况下重新填充我的ViewModel,这是在{@的ASP.NET音乐教程中显示的内容{3}}

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create(Job job, string action)
    {

        if (ModelState.IsValid)
        {
            db.Jobs.Add(job);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        var fileManagers = from x in db.UserProfiles
                           select x;

        var estimators = from x in db.UserProfiles
                         select x;

        var projectManagers = from x in db.UserProfiles
                              select x;

        var jobStatuses = from x in db.JobStatuses
                          select x;

        JobViewModel viewModel = new JobViewModel
        {
            Job = job,
            FileManagers = fileManagers.Select(x => new SelectListItem
            {
                Value = x.UserName,
                Text = x.FirstName + " " + x.LastName
            }).ToList(),
            Estimators = estimators.Select(x => new SelectListItem
            {
                Value = x.UserName,
                Text = x.FirstName + " " + x.LastName
            }).ToList(),
            ProjectManagers = projectManagers.Select(x => new SelectListItem
            {
                Value = x.UserName,
                Text = x.FirstName + " " + x.LastName
            }).ToList()
        };

        return View(viewModel);

    }

有人可以建议一个更好的方法吗?最好不要添加单独的ORM层,因为项目非常小。

2 个答案:

答案 0 :(得分:3)

只需将所有重用的代码放入方法中,然后从两种操作方法调用,例如

  public ActionResult Create()
        {

            return View(createViewModel(new Job()));
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create(Job job, string action)
        {

            if (ModelState.IsValid)
            {
                db.Jobs.Add(job);
                db.SaveChanges();
                return RedirectToAction("Index");
            }            

            return View(createViewModel(job));
        }

        private JobViewModel createViewModel(Job job)
        {
            var fileManagers = from x in db.UserProfiles
                               select x;

            var estimators = from x in db.UserProfiles
                             select x;

            var projectManagers = from x in db.UserProfiles
                                  select x;

            var jobStatuses = from x in db.JobStatuses
                              select x;

            JobViewModel viewModel = new JobViewModel
            {
                Job = job,
                FileManagers = fileManagers.Select(x => new SelectListItem
                {
                    Value = x.UserName,
                    Text = x.FirstName + " " + x.LastName
                }).ToList(),
                Estimators = estimators.Select(x => new SelectListItem
                {
                    Value = x.UserName,
                    Text = x.FirstName + " " + x.LastName
                }).ToList(),
                ProjectManagers = projectManagers.Select(x => new SelectListItem
                {
                    Value = x.UserName,
                    Text = x.FirstName + " " + x.LastName
                }).ToList()
            };

            return viewModel;
        }

无论如何我还要做什么,除了两次输入相同的东西

答案 1 :(得分:2)

好吧,看到你在模型中为每个组使用相同的用户集时,这有点简单:

var users = db.UserProfiles
.ToArray()
.Select(x => new SelectListItem
{
    Value = x.UserName,
    Text = x.FirstName + " " + x.LastName
});

var jobStatuses = from x in db.JobStatuses
                  select x;

JobViewModel viewModel = new JobViewModel
{
    Job = job,
    FileManagers = users.ToList(),
    Estimators = users.ToList(),
    ProjectManagers = users.ToList()
};

如果您将此作为表单模型使用,您也可以像这样创建模型:

var viewModel = new JobViewModel
{
    Job = job,
    FileManagers = new SelectList(users, "Value", "Text", model.FileManager),
    Estimators = new SelectList(users, "Value", "Text", model.Estimator),
    ProjectManagers = new SelectList(users, "Value", "Text", model.ProjectManager)
};

当然,假设各个列表都是SelectList,并且您拥有与每个角色的所选用户相对应的字符串模型属性。假设您想要一个填充选择列表的方法,您可以这样做:

[HttpGet]
public ActionResult YourActionName()
{
    var model = new JobViewModel
    {
        Job = job,
        FileManager = "some value",
        Estimator = "some value",
        ProjectManager = "some value"
    };

    PopulateModel(model);

    return View(model);
}

[HttpPost]
public ActionResult YourActionName(JobViewModel model)
{
    if(ModelState.IsValid)
    {
        // do something...
        return RedirectToAction("your success action");
    }

    PopulateModel(model);

    return View(model);
}

private void PopulateModel(JobViewModel model)
{
    model.FileManagers = new SelectList(users, "Value", "Text", model.FileManager);
    model.Estimators = new SelectList(users, "Value", "Text", model.Estimator);
    model.ProjectManagers = new SelectList(users, "Value", "Text", model.ProjectManager);
}