从ASP.NET MVC中的表单发布到另一个模型

如果我有一个有模型的视图,那就说Car ..

@model Project.Car 

在该视图中,我想创建一个将数据发送到新模型的表单

  @using (Html.BeginForm("Add", "Controller")) { @Html.Hidden("ID", "1") @Html.Hidden("UserID", "44") @Html.TextArea("Description") } 

我注意到如果我的动作是用我的ViewModel定义的,它就不起作用(模型总是为null):

  [HttpPost] public PartialViewResult Add(ViewModels.NewModel model) 

但是,如果我使用FormCollection它可以工作:

  [HttpPost] public PartialViewResult Add(FormCollection formCollection) 

这是ViewModel:

 public class NewModel { public int ID { get; set; } public int UserID { get; set; } public string Description { get; set; } } 

我的问题是我可以从表单中将数据发布到NewModel吗? 它所处的视图与Project.Car绑定是正确的。 它是页面上的一个小表单,需要发布与Project.Car无关的不同数据集。

您的模型名称与操作之间存在差异。 在示例中,您显示的模型名为Add而在您的操作中,您使用的是ViewModels.NewModel 。 更糟糕的是,您的视图强烈地键入了名为Car的模型。 凌乱这一切。

首先定义一个正确的视图模型:

 public class CarViewModel { public int ID { get; set; } public int UserID { get; set; } public string Description { get; set; } } 

然后是一个控制器:

 public class CarsController: Controller { public ActionResult Add() { var model = new CarViewModel { // don't ask me, those are the values you hardcoded in your view ID = 1, UserID = 44, }; return View(model); } [HttpPost] public PartialViewResult Add(CarViewModel model) { ... } } 

以及视图模型的相应强类型视图:

 @model CarViewModel @using (Html.BeginForm()) { @Html.HiddenFor(x => x.ID) @Html.HiddenFor(x => x.UserID) @Html.TextAreaFor(x => x.Description)  } 
 My question is can I post data to NewModel from my form? 

简而言之,您可以将表单发布到与应用程序中任何模型相关的任何控制器上的任何控制器操作。

例如,要将表单发布到NewModel控制器上的“ Add ”操作:

 @using (Html.BeginForm("Add", "NewModel")) { @Html.Hidden("ID", "1") @Html.Hidden("UserID", "44") @Html.TextArea("Description") } 

由于您的视图是对您的Car模型的强类型,您可以更改此设置并将ViewModel发送到您的类型与更新模型匹配的视图(如Darin所示 ),或者您需要将发布数据从Car映射到NewModel在你的控制器中:

CarControllerAdd动作(Post)上:

 [HttpPost] public PartialViewResult Add(Car model) { //now map attribute values from the Car model onto //corresponding attributes of an instance of NewModel NewModel new = new NewModel(); new.ID = model.ID; new.UserID = model.UserID; new.Desc = model.Description; //etc... //update your model/db _db.Add(new); //Redirect however you wish... } 

另外,查看AutoMapper ,这是一个对象到对象的映射器,可以自动将ViewModel映射到Models上,反之亦然。

是的,您可以强烈键入一个模型的视图并将其发布到另一个模型。

这样做有两个选择:

  1. 手动为每个输入字段提供正确的名称,以便默认绑定器可以理解它并创建模型( 示例 )。

    虽然这有效,但这也意味着您必须密切关注拼写错误,如果拼错了属性名称,您将不会遇到任何编译时错误。

  2. 在绑定到新模型类型的视图中手动创建HTML帮助程序。 然后它会为您正确生成HTML。

    为了构造帮助器,您需要一个包装器对象,它将以IViewDataContainer接口的forms公开模型的实例。 您可以在任何地方定义该包装器,包括模型本身:

     public class NewModel { public int ID { get; set; } public int UserID { get; set; } public string Description { get; set; } public class WrapperForHtmlHelper : System.Web.Mvc.IViewDataContainer { public System.Web.Mvc.ViewDataDictionary ViewData { get; set; } public WrapperForHtmlHelper(NewModel value) { this.ViewData = new System.Web.Mvc.ViewDataDictionary(value); } } } 

    然后在视图中创建一个绑定到NewModel实例的NewModel

     var ModelToPost = new YourApp.Models.NewModel() { ID = 1, UserID = 43, Description = "" } var hlp = new HtmlHelper (this.ViewContext, new YourApp.Models.NewModel.WrapperForHtmlHelper(ModelToPost) ); 

    然后像往常一样使用帮助器:

     @hlp.HiddenFor(m => m.ID) @hlp.HiddenFor(m => m.UserID) @hlp.TextAreaFor(m => m.Description) 

    然后您的PartialViewResult Add(ViewModels.NewModel model)将正确接收数据。

您的视图设置为使用Project.Car类型的模型, 但是您的action方法采用ViewModels.NewModel类型的ViewModels.NewModel但是您发布的模型类的类型是Add

将它们全部更改为匹配(假设Add正确):

视图:

 @model Add 

控制器:

 [HttpPost] public PartialViewResult Add(Add model) 

您还可以为此目的创建自定义模型绑定器。