使用ASP.NET,MVC和实体框架创建通用编辑视图
问题描述:
在我的数据库中,我有40个只包含ID号和名称的表。我的数据库使用实体框架进行访问。虽然我没有任何困难,通过为每个对象生成强类型视图和回发方法来编辑它们,我想创建一个更通用的方法和视图来查看和编辑这些对象。使用ASP.NET,MVC和实体框架创建通用编辑视图
我正在使用下面的代码来访问每个对象。在这种情况下,它是“地址类型”的对象:
public ActionMethod EditAddressType(int ID)
{
var result = database.AddressType.Single(a => a.ID == ID);
View(result);
}
[HttpPost]
public ActionMethod EditAddressType(int ID, FormCollection formValues)
{
var result = database.AddressType.Single(a => a.ID == ID);
UpdateModel(result);
database.SaveChanges();
return View("SaveSuccess");
}
视图“EditAddressType”是强类型和工作正常,但有很多重复的代码(每个对象的这一个实例)。我被告知我需要使用反射,但是我对如何实现这一点不知所措。我的理解是我需要检索对象类型,以便可以将硬编码引用替换为对象,但我不确定如何从回发中获取此信息。
我已经成功地将信息绑定到控制器中的ViewData并将其传递给知道查找此ViewData的ViewPage视图,但我不知道如何将更改回发给控制器。
感谢您给我的任何帮助!
答
如果您要编辑对象,则不需要在POST操作中从数据库中重新获取对象。当然,第一件事是到抽象我的数据访问代码从控制器:
public class AddressesController: Controller
{
private readonly IAddressesRepository _repository;
public AddressesController(IAddressesRepository repository)
{
_repository = repository;
}
public ActionMethod Edit(int id)
{
var result = _repository.GetAddress(id);
return View(result);
}
[HttpPut]
public ActionMethod Update(AddressViewModel address)
{
_repository.Save(address);
return View("SaveSuccess");
}
}
你会发现,我已改名为一些行动,并接受动词,使该控制器多一点RESTFul。
相关的观点可能是这样的:
<% using (Html.BeginForm<AddressesController>(c => c.Update(null))) { %>
<%: Html.HttpMethodOverride(HttpVerbs.Put) %>
<%: Html.HiddenFor(model => model.Id) %>
<%: Html.TextBoxFor(model => model.Name) %>
<input type="submit" value="Save" />
<% } %>
至于这个IAddressesRepository
接口的实现而言,这完全取决于你:实体框架,NHibernate的,XML文件,远程Web服务调用, ...,这是一个与ASP.NET MVC无关的实现细节。
这看起来很有前途。我一定会尽量让我的程序更加RESTful。然而,我仍然不知道如何使它更通用,因此它可以更新AddressType之外的对象,比如UserType或EventType,它们也具有ID和Name组件。我试图避免像AddressController或AddressType这样的硬编码,因为当我想更新UserType时,我将使用完全相同的代码,除了AddressType的所有实例都将被UserType替换。 – JimF 2010-12-14 22:05:05
在上面显示的Update方法中,我无法保存地址,因为在传递给视图时丢失了原始数据库上下文。我尝试使用_repository.Attach(地址)来重新应用其数据上下文,但会引发异常。这是我回到数据库以获取原始AddressType对象的原始原因,为了使对象具有执行UpdateModel(...)所需的上下文 – JimF 2010-12-15 02:20:34