2010-03-22 2 views
4

J'ai un problème en essayant de créer une entité avec un formulaire de création modélisé par vue personnalisée. Voici mon modèle de vue personnalisé pour le formulaire de création de catégorie.ViewModel personnalisé avec MVC 2 Les helpers HTML fortement typés renvoient un objet nul sur Create?

public class CategoryFormViewModel 
{ 
    public CategoryFormViewModel(Category category, string actionTitle) 
    { 
     Category = category; 
     ActionTitle = actionTitle; 
    } 

    public Category Category { get; private set; } 
    public string ActionTitle { get; private set; } 
} 

et ceci est mon contrôle utilisateur lorsque l'interface utilisateur est

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

     <h2> 
      <span><%= Html.Encode(Model.ActionTitle) %></span> 
     </h2> 
     <%=Html.ValidationSummary() %> 
     <% using (Html.BeginForm()) {%> 
     <p> 
      <span class="bold block">Başlık:</span> 
      <%=Html.TextBoxFor(model => Model.Category.Title, new { @class = "width80 txt-base" })%> 
     </p> 
     <p> 
      <span class="bold block">Sıra Numarası:</span> 
      <%=Html.TextBoxFor(model => Model.Category.OrderNo, new { @class = "width10 txt-base" })%> 
     </p>   
     <p> 
      <input type="submit" class="btn-admin cursorPointer" value="Save" /> 
     </p> 
     <% } %> 

Lorsque je clique sur le bouton Enregistrer, il ne marche pas lier la catégorie pour moi à cause de je suis en utilisant le modèle de vue personnalisée et fortement typé html aides comme ça

<%=Html.TextBoxFor(model => Model.Category.OrderNo) %> 

Ma source HTML ressemble à ceci

<form action="/Admin/Categories/Create" method="post"> 
     <p> 
      <span class="bold block">Başlık:</span> 
      <input class="width80 txt-base" id="Category_Title" name="Category.Title" type="text" value="" /> 
     </p> 
     <p> 
      <span class="bold block">Sıra Numarası:</span> 
      <input class="width10 txt-base" id="Category_OrderNo" name="Category.OrderNo" type="text" value="" /> 
     </p>   
     <p> 
      <input type="submit" class="btn-admin cursorPointer" value="Kaydet" /> 
     </p> 
     </form> 

Comment puis-je résoudre ce problème?

Répondre

8

Votre Voir le modèle a besoin d'un constructeur par défaut sans paramètres et vous avez besoin de méthodes d'ensembles publics pour chacune des propriétés. Le classeur de modèle par défaut utilise les paramètres publics pour remplir l'objet.


Le classeur de modèle par défaut a certaines règles qu'il suit. Il choisit les données à lier dans l'ordre suivant:

  1. paramètres de forme d'un poste
  2. données d'itinéraire Url définies par vos définitions d'itinéraire dans Global.asax.cs
  3. paramètres de chaîne de requête

Le modèle de liaison par défaut utilise ensuite plusieurs stratégies pour se lier à des modèles/paramètres dans vos méthodes d'action:

  1. exact nom correspond
  2. matchs avec prefix.name où préfixe est la classe parente et son nom est la sous-classe/propriété
  3. nom sans préfixe (tant qu'il n'y a pas de collision vous n'avez pas à vous soucier de fournir le préfixe)

Vous pouvez remplacer le comportement par plusieurs options de l'attribut Bind. Ceux-ci comprennent:

  • [Bind (prefix = "someprefix")] - Force une carte à une classe parent spécifique identifiée par le préfixe.
  • [Bind (Inclure = "val1, val2")] - liste blanche des noms de se lier à
  • [Bind (Exclure = "val1, val2")] - noms à exclure du comportement par défaut
+1

En outre, vous devrez vous assurer que le paramètre de votre méthode d'action s'appelle category (ou, si ce n'est pas le cas, utilisez l'attribut [Bind] pour définir le préfixe sur "Category" afin qu'il lie correctement les valeurs). –

+0

Salut Brad, merci. Mettre [Bind] en-dehors de la catégorie n'a pas fonctionné mais changer le nom du paramètre en catégorie a très bien fonctionné. Donc j'ai besoin de nommer les paramètres mêmes que ViewModel.ParameterName si je veux qu'ils soient liés lors de l'utilisation du modèle de vue personnalisé, non? –

+0

Assurez-vous que vous avez un constructeur par défaut. Il serait probablement utile si vous avez posté le code du contrôleur afin que nous puissions voir ce que vous entendez par "Il ne lie pas". – Haacked

2

Vous pouvez utiliser des modèles d'éditeur. Mettez votre contrôle ascx dans ~/Views/Shared/EditorTemplates/SomeControl.ascx. Ensuite, dans votre principale vue (page ASPX) comprennent le modèle comme si (en supposant que votre opinion est fortement typée à CategoryFormViewModel):

<%= Html.EditorForModel("SomeControl") %> 

au lieu de

<% Html.RenderPartial("SomeControl", Model) %> 
+0

Merci pour la réponse mais cela n'a pas fonctionné. Ma vue principale ne rend pas le contrôle de l'utilisateur avec EditorForModel –

+0

Avez-vous un message d'erreur? –

+0

Non, juste obtenir la page html normalement sans le formulaire de création –

2

Faire un constructeur par défaut pour votre viewmodel et initialiser la catégorie il

public CategoryFormViewModel() 
{ 
    Category = new Category() 
} 

et à votre action de commande reçoivent le viewmodel

public ActionResult ActionName(CategoryFormViewModel model) 
{ 
    //here you can access model.Category.Title 
} 
Questions connexes