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

Ale*_*lex 12 c# asp.net asp.net-mvc razor

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

@model Project.Car
Run Code Online (Sandbox Code Playgroud)

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

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

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

    [HttpPost]
    public PartialViewResult Add(ViewModels.NewModel model)
Run Code Online (Sandbox Code Playgroud)

但是,如果我使用FormCollection它的工作原理:

    [HttpPost]
    public PartialViewResult Add(FormCollection formCollection)
Run Code Online (Sandbox Code Playgroud)

这是ViewModel:

public class NewModel
{
    public int ID { get; set; }
    public int UserID { get; set; }
    public string Description { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

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

GSe*_*erg 7

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

在这样做时,您有两个选择:

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

    虽然这有效,但这也意味着您必须注意拼写错误,并且如果您拼错属性名称,则不会出现任何编译时错误。

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

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

    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<NewModel>(value);
        }
      }
    }
    
    Run Code Online (Sandbox Code Playgroud)

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

    var ModelToPost = new YourApp.Models.NewModel() { ID = 1, UserID = 43, Description = "" }
    
    var hlp = new HtmlHelper<YourApp.Models.NewModel>
             (this.ViewContext,
              new YourApp.Models.NewModel.WrapperForHtmlHelper(ModelToPost)
             );
    
    Run Code Online (Sandbox Code Playgroud)

    然后像往常一样使用助手:

    @hlp.HiddenFor(m => m.ID)
    @hlp.HiddenFor(m => m.UserID)
    @hlp.TextAreaFor(m => m.Description)
    
    Run Code Online (Sandbox Code Playgroud)

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


Dar*_*rov 6

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

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

public class CarViewModel
{
    public int ID { get; set; }
    public int UserID { get; set; }
    public string Description { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

然后是一个控制器:

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)
    {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

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

@model CarViewModel
@using (Html.BeginForm())
{
    @Html.HiddenFor(x => x.ID)
    @Html.HiddenFor(x => x.UserID)
    @Html.TextAreaFor(x => x.Description)
    <button type="submit">Add</button>
}
Run Code Online (Sandbox Code Playgroud)