views:

237

answers:

1

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 an argument of ProjectSearch type.

Why the Search don't get bound as supposed ?

EDIT

The action

public virtual ActionResult List(Project gridModel)
{..}
+2  A: 

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) %>
Darin Dimitrov
I tried both ways,niether worked. I think it has something to do with the base type of the Search property. Its ISearchExpression. Maybe while the binding is happening the Search is of type ISearchExpression,therefore the model binder can't se the Name property. Makes this sense ?
Can you show the code for the action you are posting to?
Darin Dimitrov
I edited the post and I added the action code.
`ProjektGridModel`?
Darin Dimitrov
Sorry, it was a typo.
Is the main view (aspx) strongly typed? If yes to what type?
Darin Dimitrov
I'm sorry,there was an another typo. The main view is strongly typed.The type is `Project`.The action method take an argument of the same type(`Project`),not ProjectSearch. The nested partialview is of `ProjectSearch` type.
Please see my update for a sample code.
Darin Dimitrov
Thank you very much for your extensive response. But there is one small think.In the action method I need a parameter of type `Project` because there are more properties I need.I left them out for the sake of readability.