编辑代码改进后保存

时间:2011-10-25 08:48:26

标签: asp.net-mvc-3

我正在开发一个简单的应用程序,并希望了解CodeFirst EF方法。到目前为止一切都很好。

我已设法获得创建并删除已排序并且已进行编辑工作。事情是我认为编辑代码可以改进;我只是不确定如何。所以这就是:

 public ActionResult Edit(int id, CreateResourceViewModel model)
        {
            if (ModelState.IsValid)
            {
                // save the changes
                //UpdateModel(model.Resource);
                //resourceAdminManager.SaveChanges();

                Resource current = resourceAdminManager.Resources.Find(id);
                current.ResourceTypeID = model.Resource.ResourceTypeID;
                current.Name = model.Resource.Name;
                current.Description = model.Resource.Description;
                current.Email = model.Resource.Email;
                current.TurnAroundTime = model.Resource.TurnAroundTime;


                resourceAdminManager.SaveChanges();

                return RedirectToAction("Index");
            }
            else
            {
                return View(model);
            }
        }

我知道周围没有异常处理,我需要解决这个问题,但我主要担心的是我手动更新了模型。我担心的是: 这是在控制器中 2.这是硬编码的,因此对模型的任何更改都需要重新编写代码

有人可以提出更好的方法吗。

非常感谢 森

所以继续使用AutoMapper建议:

这非常有帮助,我已经开始玩这个了。我遇到了一点麻烦。

控制器现在看起来像:

if (ModelState.IsValid)
            {
                try
                {
                    var current = resourceAdminManager.Resources.Find(id);
                    current = Mapper.Map<CreateResourceViewModel, Resource>(model);
                    resourceAdminManager.SaveChanges();
                    return RedirectToAction("Index");
                }
                catch (Exception exc)
                {
                    ModelState.AddModelError("Error", exc); // or, use a generic error.
                }
            }

            return View(model);

单击“保存”时视图中出现错误。我在以下内容中得到null异常:

<%: Html.DropDownListFor(model => model.Resource.ResourceTypeID, new SelectList(Model.ResourceTypes, "ResourceTypeId", "Title"), "-- Select Resource Type --")%>

关于我在这里可能缺少的任何想法?

2 个答案:

答案 0 :(得分:0)

您使用的是ViewModel,这是一种非常好的做法。

1]对于异常处理,建议继承您的Controller 从您的自定义“BaseControllor”而不是System.Web.Mvc.Controller

public class YourController : BaseController

在“BaseControllor”中覆盖OnException,以便控制器操作中的所有操作都将被捕获。

public class BaseController: Controller
{

    protected override void OnException(ExceptionContext filterContext)
    {
        base.OnException(filterContext);
    }

}

2]您需要将“保存”代码重构为同一项目中的不同类或不同的项目和不同的类

3]对于您需要在viewmodel和保存逻辑中进行更改的模型中的任何更改,都是,

答案 1 :(得分:0)

一个字: AutoMapper

将这5条从左到右的样板线转为一条。

我发现的最好的MVC(好吧,C#)附加组件之一。

如果正确实施(我认为您的ViewModel可能需要更改tad),您的操作将如下所示:

public ActionResult Edit(int id, CreateResourceViewModel model)
{
   if (ModelState.IsValid) 
   {   
      try
      {
         var current = resourceAdminManager.Resources.Find(id);
         current = Mapper.Map<CreateResourceViewModel,Resource>(model);
         resourceAdminManager.SaveChanges();
         return RedirectToAction("Index");
      }
      catch (Exception exc)
      {
         ModelState.AddModelError("Error", exc); // or, use a generic error.
      }
   }

   return View(model);

}

警告:这基本上会取代整个实体。因此,如果您只想更改某些字段,只包括ViewModel中的字段,那么其他字段将保持不变。您还可以在AutoMapper中指定“忽略”,以便不会触及这些字段。

并解决您的疑虑:

  
      
  1. 这是在控制器中
  2.   

实际上,应该。事实上,这是控制器工作 - 更新模型。 你有样板L-R代码的事实很糟糕,这就是AutoMapper帮助的原因。

  
      
  1. 这是硬编码的,因此对模型的任何更改都需要重新编写代码
  2.   

Yup,再次 - AutoMapper解决了这个问题。它适用于约定(如MVC),因此如果您在ViewModel中具有与目标模型(域对象)同名的属性,则不必显式映射 - &gt;它会起作用。此外,映射是一个静态类,因此可以很容易地维护。