从 MVC 中的窗体发布到另一个模型 ASP.NET

本文关键字:另一个 模型 ASP NET MVC 窗体 | 更新日期: 2023-09-27 18:01:18

如果我有一个模型的视图,让我们说Car。

@model Project.Car

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

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

我注意到,如果我的操作是用我的 ViewModel 定义的,它不起作用(模型始终为空(:

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

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

    [HttpPost]
    public PartialViewResult Add(FormCollection formCollection)

下面是视图模型:

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

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

从 MVC 中的窗体发布到另一个模型 ASP.NET

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

这样做时,您有两种选择:

  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);
        }
      }
    }
    

    然后在视图中创建一个绑定到 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)
             );
    

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

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

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

模型名称和操作之间存在差异。在您展示的示例中,模型称为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)
    <button type="submit">Add</button>
}
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操作(帖子(:

[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,这是一个对象到对象的映射器,它可以自动将ViewModels映射到模型上,反之亦然。

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

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

视图:

@model Add

控制器:

[HttpPost]
public PartialViewResult Add(Add model)

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