简体   繁体   中英

Posting a view that contains multiple partial views

I'm having a problem with posting a view that has multiple partial views within it using one submit button

This is my A model,

:UPDATED:

public class AModel
{
    public int AID { get; set; }

    public int BID { get; set; }

    public int CID { get; set; }

    public int ANumber { get; set; }

    public BModel BModel { get; set; }

    public CModel CModel { get; set; }
}

this is my B model

public class BModel
{       
    public int BID { get; set; }
    public int BName { get; set; }

    public IList<DModel> DModel { get; set; }
}    

this is the D model

public class DModel
{
    public int DID { get; set; }

    public int? Number { get; set; }
}

this is the c Model

public class CModel
{
    public int CID { get; private set; }

    public IList<HModel> HModels { get; set; }
}

and so on this is the main view

@model Project.Web.Models.AModel    
@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()
    @Html.Partial("CreateB",Model.BModel);
    @Html.Partial("CreateC",Model.CModel);
    <input style="border-radius:4px;width:100px;" type="button" value="next" id="next" class="btn btn-default" />
}

this is the Get action

public ActionResult Create(){
Models.AModel model = new Models.AModel(){
BModel = new BModel(){
DModel = new List<Models.DModel>(){ new Models.DModel() },

CModel = new CModel(){
HModel = new List<HModel>(){ new Models.HModel() },
};
return View(model);
}

this is the Post action

[HttpPost]
public ActionResult Create(Models.AModel model)
{
   //doing things with data 
   //when I reach this point all object are null  
   return RedirectToAction("index", model);
}

public void SetNumber(Models.BModel model){
model.DModel.Add(new Models.DModel());
}

Partial View For BModel, and CModel is similar to BModel Partial view Note: the SetNumber method only create a new Object and add it to the list

@model Project.Web.Models.BModel

@Html.TextBoxItemFor(x => x.BName)

@for ( int i=0; i< Model.DModel.Count; i++){
@Html.TextBoxItemFor( x => x.DModel[i].Number)
 <a id="addNumber" href="/AController/SetNumber/" data-ajax="true" data-
 ajax-method="GET" >Add Another Number</a>
}

What can I do? What Am I missing?

Would be nice to see your partials as well. You should remember to put those partials names (as properties from main model) to "name" attribute of input as well. So for your case your PartialView should contain inputs like these: <input name="AModel.BModel.BID" ... />

UPDATE:

Try to replace your

@Html.Partial("Name", Model.PartialModel)

to

@{ Html.RenderPartial("Name", Model.PartialModel, new ViewDataDictionary { TemplateInfo = new System.Web.Mvc.TemplateInfo { HtmlFieldPrefix = prefix } }); }

where prefix is Model property name (holding that partial model, ex "BModel"). So your view for AModel would look like this:

@model Project.Web.Models.AModel
@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()
    @{ Html.RenderPartial("CreateB",Model.BModel, new ViewDataDictionary { TemplateInfo = new System.Web.Mvc.TemplateInfo { HtmlFieldPrefix = "BModel" } }) }
    @{ Html.RenderPartial("CreateC",Model.CModel, new ViewDataDictionary { TemplateInfo = new System.Web.Mvc.TemplateInfo { HtmlFieldPrefix = "CModel" } }) 
    <input style="border-radius:4px;width:100px;" type="button" value="next" id="next" class="btn btn-default" />
}

UPDATE 2:

In order to work with arrays (which you have in your BModel) you will need to modify this prefix a bit, so view for your BModel would contain:

@{
    for (var i = 0; i < Model.DModel.Count(); i++)
    {
        Html.RenderPartial("Name", Model.DModel[i], new ViewDataDictionary { TemplateInfo = new System.Web.Mvc.TemplateInfo { HtmlFieldPrefix = "DModel["+i+"]" } });
    }
}

UPDATE 3:

Here's a complete example for your case (or pretty similar to your) without JavaScript. Controller:

    public ActionResult Test()
    {
        return View("Test1", new AModel());
    }

    [HttpPost]
    public ActionResult Save(AModel model)
    {
        if (model.PostType == "Add")
        {
            model.BModel.DModels.Add(new DModel());

            return View("Test1", model);
        }

        // Do something with this final model

        return View("Test1");
    }

Models:

public class DModel
{
    public string Name { get; set; }
}

public class CModel
{
    public string SomeName { get; set; }
}

public class BModel
{
    public List<DModel> DModels { get; set; }

    public BModel()
    {
        DModels = new List<DModel>();
    }
}

public class AModel
{
    public BModel BModel { get; set; }

    public CModel CModel { get; set; }

    public string PostType { get; set; }

    public AModel()
    {
        BModel = new BModel();
        CModel = new CModel();
    }
}

AModel View:

@model MVC.Models.AModel
@if (Model == null)
{
    <span>Model saved</span>
}
else
{
    using (Html.BeginForm("Save", "Home", FormMethod.Post))
    {
        Html.RenderPartial("Partials/CModel", Model.CModel, new ViewDataDictionary { TemplateInfo = new TemplateInfo { HtmlFieldPrefix = "CModel" } });
        <hr />
        Html.RenderPartial("Partials/BModel", Model.BModel, new ViewDataDictionary { TemplateInfo = new TemplateInfo { HtmlFieldPrefix = "BModel" } });

        <input type="submit" name="PostType" value="Add"/><br />
        <input type="submit" name="PostType" value="Save"/>
    }
}

BModel Partial View:

@model MVC.Models.BModel

@{
    for (var i = 0; i < Model.DModels.Count(); i++)
    {
        Html.RenderPartial("Partials/DModel", Model.DModels[i], new ViewDataDictionary { TemplateInfo = new TemplateInfo { HtmlFieldPrefix = $"{ViewData.TemplateInfo.HtmlFieldPrefix}.DModels[{i}]" } });
    }
}

DModel Partial View:

@model MVC.Models.DModel

Name: @Html.EditorFor(x => x.Name) <br/>

CModel Partial View:

@model MVC.Models.CModel

SomeName: @Html.EditorFor(x => x.SomeName) <br/>

If you can use jQuery then those 2 submit inputs could be replaced with some buttons and onclick event handlers which will take current form and post to different actions on controller.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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