简体   繁体   English

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

[英]Posting to another model from a form in ASP.NET MVC

If I have a view that has a model, lets say Car.. 如果我有一个有模型的视图,那就说Car ..

@model Project.Car

inside that view I want to create a form that sends data to a new model 在该视图中,我想创建一个将数据发送到新模型的表单

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

I've noticed that if my action is defined with my ViewModel it does not work (model is always null): 我注意到如果我的动作是用我的ViewModel定义的,它就不起作用(模型总是为null):

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

However, if I use a FormCollection it works: 但是,如果我使用FormCollection它的工作原理:

    [HttpPost]
    public PartialViewResult Add(FormCollection formCollection)

Here is the ViewModel: 这是ViewModel:

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

My question is can I post data to NewModel from my form? 我的问题是我可以从表单中将数据发布到NewModel吗? The View that it sits on is correct to be tied to Project.Car. 它所在的视图与Project.Car绑定是正确的。 Its a small form on the page that needs to post a different set of data that has nothing to do with Project.Car. 它是页面上的一个小表单,需要发布与Project.Car无关的不同数据集。

You have a discrepancy between the name of your model and your action. 您的模型名称与您的操作之间存在差异。 In the example you have shown the model is called Add whereas in your action you are using ViewModels.NewModel . 在示例中,您显示的模型名为Add而在您的操作中,您使用的是ViewModels.NewModel Even worse, your view is strongly typed to a model called Car . 更糟糕的是,您的视图强烈地键入了名为Car的模型。 Messy all this. 凌乱这一切。

So start by defining a correct view model: 首先定义一个正确的视图模型:

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

and then a controller: 然后是一个控制器:

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)
    {
        ...
    }
}

and a corresponding strongly typed view to your view 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? 

The short answer is yes you can post the form to any controller action on any controller related to any Model in your application. 简短的回答是肯定的,您可以将表单发布到与应用程序中任何模型相关的任何控制器上的任何控制器操作。

For example, for your form to post to the " Add " action on the NewModel controller: 例如,要将表单发布到NewModel控制器上的“ Add ”操作:

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

Since your view is strongly typed to your Car model, You can either change this and send a ViewModel to your view whose type matches the model your updating (as Darin demonstrated ), or you'll need to map the post data from Car onto NewModel in your controller: 由于您的视图是对您的Car模型强烈输入的,因此您可以更改此设置并将ViewModel发送到您的类型与更新模型匹配的视图(如Darin所示 ),或者您需要将发布数据从Car映射到NewModel在你的控制器中:

On the CarController 's Add action (Post) : 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...
}

Also, check out AutoMapper , an object-to-object mapper which automates mapping of ViewModels onto Models and vice versa. 另外,查看AutoMapper ,一个对象到对象的映射器,它可以自动将ViewModel映射到Models上,反之亦然。

Yes, you can strongly type a view to one model and POST it to another model. 是的,您可以强烈键入一个模型的视图并将其发布到另一个模型。

In doing so you have two options: 这样做有两种选择:

  1. Manually provide correct names for each input field, so that the default binder will understand it and create the model ( example ). 手动为每个输入字段提供正确的名称,以便默认绑定器可以理解它并创建模型( 示例 )。

    While this works, it also means you have to keep an eye on typos and you will not get any compile-time errors if you misspell a property name. 虽然这有效,但这也意味着您必须密切关注拼写错误,如果拼错了属性名称,您将不会遇到任何编译时错误。

  2. Manually create a HTML helper in the view bound to the new model type. 在绑定到新模型类型的视图中手动创建HTML帮助程序。 It will then properly generate the HTML for you. 然后它会为您正确生成HTML。

    In order to construct the helper, you need a wrapper object that would expose the instance of your model in the form of the IViewDataContainer interface. 为了构造帮助器,您需要一个包装器对象,它将以IViewDataContainer接口的形式公开模型的实例。 You can define that wrapper anywhere, including the model itself: 您可以在任何地方定义该包装器,包括模型本身:

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

    Then in a view you create a helper bound to an instance of NewModel : 然后在视图中创建一个绑定到NewModel实例的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) ); 

    And then you use the helper as usual: 然后像往常一样使用助手:

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

    Then your PartialViewResult Add(ViewModels.NewModel model) will properly receive the data. 然后您的PartialViewResult Add(ViewModels.NewModel model)将正确接收数据。

Your view is set up to use a model of type Project.Car however your action method takes a model of type ViewModels.NewModel , but also your model class posted is of type Add ? 您的视图设置为使用Project.Car类型的模型, 但是您的操作方法采用ViewModels.NewModel类型的ViewModels.NewModel但是您发布的模型类的类型是Add

Change them all to match (assuming Add is correct): 将它们全部更改为匹配(假设Add正确):

View: 视图:

@model Add

Controller: 控制器:

[HttpPost]
public PartialViewResult Add(Add model)

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM