Modèle ASP.NET Binder et le type de base
-
21-09-2019 - |
Question
Mon modèle hérite d'une interface:
public interface IGrid
{
ISearchExpression Search { get; set; }
.
.
}
public interface ISearchExpression
{
IRelationPredicateBucket Get();
}
Le modèle:
public class Project : IGrid
{
public ISearchExpression Search { get; set; }
public Project()
{
this.Search = new ProjectSearch();
}
}
Le ProjectSearch:
public class ProjectSearch: ISearchExpression
{
public string Name { get; set; }
public string Number { get; set; }
public IRelationPredicateBucket Get()
{...}
}
Et la forte PartialView typée dans la vue principale:
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<ProjectSearch>" %>
<%= Html.TextBoxFor(x=>x.Name)%>
<%= Html.TextBoxFor(x => x.Number)%>
....
Quand je soumets la forme, la propriété Search
ne soit pas lié correctement. Tout est erronée.Le action prend un argument de type ProjectSearch
.
Pourquoi ne soit pas Search
lié comme on le suppose?
EDIT
L'action
public virtual ActionResult List(Project gridModel)
{..}
La solution
Vous devez spécifier le préfixe correct pour lier sous-types. Par exemple, si vous voulez lier à Name
propriété de la propriété Search
du modèle de votre zone de texte doit être nommé: Search.Name
. Lorsque vous utilisez votre Html.TextBoxFor(x=>x.Name)
est nommé Name
zone de texte et le liant de modèle ne fonctionne pas. Une solution de contournement consiste à spécifier explicitement le nom:
<%= Html.TextBox("Search.Name") %>
ou utilisez éditeur modèles qui est une nouvelle fonctionnalité dans ASP.NET MVC 2.0
Mise à jour:
Sur la base des informations supplémentaires fournies dans la section commentaires est ici un échantillon qui devrait fonctionner:
Modèle:
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; }
}
Contrôleur:
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");
}
}
Vue - ~ / Vues / Accueil / 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>
Vue - ~ / Vues / Accueil / SearchTemplate.ascx:
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Models.ProjectSearch>" %>
<%= Html.TextBoxFor(x => x.Name) %>
<%= Html.TextBoxFor(x => x.Number) %>