14

如果我有一个有模型的视图,可以说 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 无关的不同数据。

4

5 回答 5

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

    然后在视图中创建一个绑定到以下实例的助手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)将正确接收数据。

于 2014-02-28T18:25:15.770 回答
6

您的模型名称和您的操作之间存在差异。在示例中,您已显示模型被调用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>
}
于 2013-02-26T16:28:27.180 回答
3
My question is can I post data to NewModel from my form? 

简短的回答是肯定的,您可以将表单发布到与应用程序中的任何模型相关的任何控制器上的任何控制器操作。

例如,让您的表单发布到控制器Add上的“”操作NewModel

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

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

关于CarController' 的Add动作(发布):

[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 映射到模型上,反之亦然。

于 2013-02-26T18:43:47.310 回答
1

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

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

看法:

@model Add

控制器:

[HttpPost]
public PartialViewResult Add(Add model)
于 2013-02-26T16:29:25.747 回答
-6

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

于 2013-02-27T08:03:48.223 回答