开发者

ASP.NET Model Binder and base type

My model inherits from an interface:

public interface IGrid
{
    ISearchExpression Search { get; set; }
    .
    .
}

public interface ISearchExpression 
{
    IRelationPredicateBucket Get();
}

The model:

public class Project : IGrid
{
      public ISearchExpression Search { get; set; }

      public Project()
      {
            this.Search = new ProjectSearch();
      }  
}

The ProjectSearch:

public class ProjectSearch: ISearchExpression 
{
    public string Name { get; set; }
    public string Number { get; set; }

    public IRelationPredicateBucket Get()
    {...}
}

And the strong typed partialview in the main view:

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

       <%= Html.TextBoxFor(x=>x.Name)%>

       <%= Html.TextBoxFor(x => x.Number)%>

       ....

When I submit the form, the Search property don't get bound properly. Everything is empty.The action takes 开发者_StackOverflow社区an argument of ProjectSearch type.

Why the Search don't get bound as supposed ?

EDIT

The action

public virtual ActionResult List(Project gridModel)
{..}


You need to specify the correct prefix in order to bind sub types. For example if you want to bind to Name property of the Search property of the Model your textbox must be named: Search.Name. When you use Html.TextBoxFor(x=>x.Name) your textbox is named Name and the model binder doesn't work. One workaround is to explicitly specify the name:

<%= Html.TextBox("Search.Name") %>

or use editor templates which is a new feature in ASP.NET MVC 2.0


UPDATE:

Based on the additional details provided in the comments section here's a sample that should work:

Model:

public interface IRelationPredicateBucket
{ }

public interface ISearchExpression
{
    IRelationPredicateBucket Get();
}

public interface IGrid
{
    ISearchExpression Search { get; set; }
}

public class ProjectSearch : ISearchExpression
{
    public string Name { get; set; }
    public string Number { get; set; }

    public IRelationPredicateBucket Get()
    {
        throw new NotImplementedException();
    }
}

public class Project : IGrid
{
    public Project()
    {
        this.Search = new ProjectSearch();
    }

    public ISearchExpression Search { get; set; }
}

Controller:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View(new Project());
    }

    [HttpPost]
    public ActionResult Index(ProjectSearch gridModel)
    {
        // gridModel.Search should be correctly bound here
        return RedirectToAction("Index");
    }
}

View - ~/Views/Home/Index.aspx:

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

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
    <% using (Html.BeginForm()) { %>
        <% Html.RenderPartial("~/Views/Home/SearchTemplate.ascx", Model.Search); %>
        <input type="submit" value="Create" />
    <% } %>
</asp:Content>

View - ~/Views/Home/SearchTemplate.ascx:

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

<%= Html.TextBoxFor(x => x.Name) %>
<%= Html.TextBoxFor(x => x.Number) %>
0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜