开发者

Model is null?

I've read a lot of similar posts about null model but my case is very very simple and still the model on Create action is null. What am I doing wrong???

Here is the situation: One main view, two strongly typed partial views inside, each binded to a public property of the main model. Any help is appreciated. models:

public class SimpleModel1
{
    public IEnumerable<string> SomeStrings1 { get; set; }
}

public class SimpleModel2
{
    public IEnumerable<string> SomeStrings2 { get; set; }
}

public class ComplexModel
{
    public SimpleModel1 model1 { get; set; }
    public SimpleModel2 model2 { get; set; }
    public IEnumerable<string> SomeStringsComplex { get; set; }
}

int he controller:

public ActionResult Create()
    {
        ComplexModel complex = new ComplexModel();
        complex.model1 = new SimpleModel1();
        complex.model1.SomeStrings1 = new List<string> { "a1", "a2", "a3"};

        complex.model2 = new SimpleModel2();
        complex.model2.SomeStrings2 = new List<string> { "b1", "b2", "b3" };

        complex.SomeStringsComplex = new List<string> { "c1", "c2", "c3" };
        return View(complex);
    }

    [HttpPost]
    public ActionResult Create(ComplexModel model)
    {
        if (ModelState.IsValid)
        {
            var test = model.SomeStringsComplex;
        }
        return View();
    }

Views: 2 strong partial views -each for model

<%@ Control Language="C#"     
Inherits="System.Web.Mvc.ViewUserControl<MvcApp1.Models.SimpleModel2>" %>

<fieldset>
    <legend>Fields</legend>
    <% foreach (string item in Model.SomeStrings2)
            {%>
            <p>
            <label for="Title">Item Title:</label>
            <%= Html.TextBox(item,item)%>               
            </p>
            <%
            }
         %>
</fieldset>

1 main view:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master"
    Inherits="System.Web.Mvc.ViewPage<MvcApp1.Models.ComplexModel>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
 Create
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

<h2>Create</h2>
 <% using (Html.BeginForm()) {%>
 <fieldset>
<div> Own values
<% foreach (string item in Model.SomeStringsComplex)
            {%>
            <p>
            <label for="Title">Item Title:</label&开发者_如何学编程gt;
            <%= Html.TextBox(item,item) %>          
            </p>
            <%
            }
         %>
</div>
<div>Simple values 1
<%Html.RenderPartial("SimpleModelView1", this.ViewData.Model.model1, new ViewDataDictionary()); %>
</div>

<div>Simple values 2
<%Html.RenderPartial("SimpleModelView2", Model.model2, new ViewDataDictionary()); %>
</div>
<p>
            <input type="submit" value="Create" />
        </p>
</fieldset>
 <% } %>


I'm going to take a wild stab and say your Model validation is failing when posting a ComplexModel back to the server

Your Model validation doesn't have to fail at all. You're not returning anything from inside the if block so you're always returning a View with no Model associated:

if (ModelState.IsValid)
{
    var test = model.SomeStringsComplex;
}
return View(); // View is called with no Model data

Judging by your code, that would cause the Create view to be instantiated with no Model. That can be fixed fairly simply:

[HttpPost]
public ActionResult Create(ComplexModel model)
{
    if (ModelState.IsValid)
    {
        var test = model.SomeStringsComplex;
        // Do something to Create the object

        RedirectToAction("Index");
    }

    // Model State is invalid, return so the user can correct
    return View(model);
}


Aren't you supposed to send something to the view, on that line?

return View();


I think the problem is how you are specifying your text fields - the model binder does not know how to assign them back to the properties that they came from.

You may want to read this Haacked article that describes how to use model binding for enumerable properties:

http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx


Finally I found a solution. The data posted to Create method should look s.th. like this:

[HttpPost]
public ActionResult Create(ComplexModel mainModel, SimpleModel nestedModel, SimpleModel2 nested2Model)
{
    if (ModelState.IsValid)
    {
        var main = mainModel;
        var nested1 = nestedModel;
        var nested2 = nested2Model;
    }

    return View();
}

The nested parameters are not null when the models are binded to partial views. If used in the main form through main model than the values are in the instance of the main model. I've also changed IEnumerable<string> to IList<string> and then rendered the string values with

for (int i = 0; i < Model.Strings.Count; i++)
{ %>
    <%: Html.EditorFor(m => m.Strings[i])%>
<% }

Thanks all

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜