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) %>
精彩评论