我正在开发一个简单的应用程序,并希望了解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 --")%>
关于我在这里可能缺少的任何想法?
答案 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中指定“忽略”,以便不会触及这些字段。
并解决您的疑虑:
- 这是在控制器中
醇>
实际上,应该。事实上,这是控制器工作 - 更新模型。 你有样板L-R代码的事实很糟糕,这就是AutoMapper帮助的原因。
- 这是硬编码的,因此对模型的任何更改都需要重新编写代码
醇>
Yup,再次 - AutoMapper解决了这个问题。它适用于约定(如MVC),因此如果您在ViewModel中具有与目标模型(域对象)同名的属性,则不必显式映射 - &gt;它会起作用。此外,映射是一个静态类,因此可以很容易地维护。