使用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无关的实现细节。

+0

这看起来很有前途。我一定会尽量让我的程序更加RESTful。然而,我仍然不知道如何使它更通用,因此它可以更新AddressType之外的对象,比如UserType或EventType,它们也具有ID和Name组件。我试图避免像AddressController或AddressType这样的硬编码,因为当我想更新UserType时,我将使用完全相同的代码,除了AddressType的所有实例都将被UserType替换。 – JimF 2010-12-14 22:05:05

+0

在上面显示的Update方法中,我无法保存地址,因为在传递给视图时丢失了原始数据库上下文。我尝试使用_repository.Attach(地址)来重新应用其数据上下文,但会引发异常。这是我回到数据库以获取原始AddressType对象的原始原因,为了使对象具有执行UpdateModel(...)所需的上下文 – JimF 2010-12-15 02:20:34