简体   繁体   English

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

[英]How to improve DRY in Create GET and POST actions in an ASP.NET MVC controller

I'm looking for some help as to how I can make my MVC code more efficient, as I am reusing the same code in my Create GET and POST actions which goes against the DRY principles of MVC. 我正在寻求一些有关如何提高我的MVC代码效率的帮助,因为我在与MVC的DRY原理背道而驰的Create GET和POST操作中重用了相同的代码。

Specifically I'm using EntityFramework and have a controller that populates a ViewModel with the following code: 具体来说,我正在使用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);
    }

In my POST function, I'm checking for the model validity, and then writing out the same code again to repopulate my ViewModel if the model is not valid, which is what is shown in the ASP.NET music tutorial at http://www.asp.net/mvc/tutorials/mvc-music-store/mvc-music-store-part-5 . 在我的岗位职能,我检查了模型的有效性,然后再写出相同的代码重新填充我的ViewModel如果模型是无效的,而这一点正是在ASP.NET的音乐教程中所示的http:// www.asp.net/mvc/tutorials/mvc-music-store/mvc-music-store-part-5

    [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);

    }

Can someone please suggest a better way of doing this? 有人可以建议一种更好的方法吗? Preferably without adding a seperate ORM layer, as the project is quite small. 最好不要添加单独的ORM层,因为项目很小。

Just put all the reused code in a method and call from both action methods, something like 只需将所有重用的代码放在一个方法中,然后从两个动作方法中调用,例如

  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;
        }

Its what I do anyway, save typing the same stuff twice 无论如何,这是我要做的,省去了两次键入相同内容的麻烦

Well, seeing as you're using the same set of users for each group in your model, this is a little simpler: 好吧,看到您为模型中的每个组使用相同的用户集,这会稍微简单一些:

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()
};

If you're using this as a form model, you could also create the model like so: 如果将其用作表单模型,则还可以像这样创建模型:

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)
};

Assuming, of course, that the various lists are SelectList s and that you have string model properties corresponding to the selected user for each role. 当然,假设各种列表都是SelectList ,并且您具有与每个角色的所选用户相对应的字符串模型属性。 Assuming you want to have one method that fills the select lists, you could do something like this: 假设您要使用一种方法来填充选择列表,则可以执行以下操作:

[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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM