2010-03-11 6 views
3

Je veux poster des produits qui a un ID et certaines catégories avec jQuery. Mais j'obtiens une erreur dans: Microsoft.Web.Mvc.DataAnnotations.DataAnnotationsModelBinder.BindProperty (NullReferenceException), lorsque j'ajoute les catégories.Comment faire pour publier un tableau d'objets complexes (qui a un tableau d'objets complexes) avec jQuery

Le ModelBinder par défaut ne devrait-il pas pouvoir lier ceci (sans ActionFilter ou ModelBinder personnalisé)?

J'ai essayé d'appliquer un ActionFilter (désérialiser) que j'ai trouvé dans un autre thread SO, mais il ne fonctionne jamais. J'ai aussi essayé avec jQuery.ajaxSettings.traditional = true ;, jQuery 1.3.2 et 1.4.2. Et dans les autres exemples que j'ai trouvés, ils affichent simplement ID, Name, etc., pas un autre tableau d'objets complexes.

Des idées?

Classes

public class Product 
{ 
    public int ID { get; set; } 
    public Category[] Categories { get; set; } 
} 

public class Category 
{ 
    public int ID { get; set; } 
} 

HTML

<input id="Product[0]_ID" name="Product[0].ID" type="hidden" value="9" /> 
<input id="Product[0]_Categories[0]_ID" name="Product[0].Categories[0].ID" type="hidden" value="99" /> 
<input id="Product[1]_ID" name="Product[1].ID" type="hidden" value="8" /> 
<input id="Product[1]_Categories[0]_ID" name="Product[1].Categories[0].ID" type="hidden" value="88" /> 

contrôleur

[JsonFilter(Parameter = "p")] 
public JsonResult GetProductPrice([Bind(Prefix = "Product")] Product[] p) 
{ 
    // TODO: Implement some checking... 
    return Json(true); 
} 

jQuery

$.post(getProductPriceUrl, $("form").serializeArray(), function(data) { 
    $("#Price").html(data); 
}); 

JsonFilter

public class JsonFilter : ActionFilterAttribute 
{ 
    public string Parameter { get; set; } 
    //public Type JsonDataType { get; set; } 

    private JavaScriptSerializer serializer; 

    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     serializer = new JavaScriptSerializer(); 

     if (filterContext.HttpContext.Request.ContentType.Equals("application/json")) 
     { 
      string inputContent; 

      using (var sr = new StreamReader(filterContext.HttpContext.Request.InputStream)) 
      { 
       inputContent = sr.ReadToEnd(); 
      } 

      var result = serializer.Deserialize<Product>(inputContent); 
      filterContext.ActionParameters[Parameter] = result; 
     } 
    } 
} 

POST # 1

__RequestVerificationToken=sz%2BLKCzTmdGMrH3TdOYipS5z%2BJ3uVyzBtJRZrruJoUohoGaH2O3DU5%2FcuU6hX1E%2F&Product%5B0%5D.ID=9&Product%5B0%5D.Categories%5B0%5D.ID=99&Product%5B1%5D.ID=8&Product%5B1%5D.Categories%5B0%5D.ID=88 

POST # 2

__RequestVerificationToken=sz+LKCzTmdGMrH3TdOYipWTERHSdtCvGUhuw/dGIkgSL3rjcSLO7RJJN/rcssVwv&Product[0].ID=9&Product[0].Categories[0].ID=99&Product[1].ID=8&Product[1].Categories[0].ID=88 

POST # 3

[{"name":"__RequestVerificationToken","value":"sz+LKCzTmdGMrH3TdOYipcqr8WKC2eL7CRS5BZUtwzD60WkqfnjdeAcO3DQg5ss6"},{"name":"Product[0].ID","value":"9"},{"name":"Product[0].Categories[0].ID","value":"99"},{"name":"Product[1].ID","value":"8"},{"name":"Product[1].Categories[0].ID","value":"88"}] 
+0

Vous ne devriez pas avoir besoin d'un ActionFilter. Pouvez-vous montrer les données 'POST'? –

+0

Er, les messages 1 et 2 sont des clés/valeurs régulières, "post" 3 est JSON. Lequel avez-vous l'intention, et pourquoi le faire de deux façons?En général, préférez les POST standard dans MVC, car JSON nécessite une gestion spéciale. –

+0

Je veux utiliser un POST standard, mais après quelques heures de test et de ne pas le faire fonctionner. J'ai commencé à douter que c'était possible, j'ai donc essayé avec JSON et le "JsonFilter" après avoir lu quelques thread SO avec cette solution. –

Répondre

0

Il y a deux façons que je peux penser pour accomplir la objectif d'envoyer un graphique d'objet complexe à un le serveur correctement câblé. L'un est la façon dont vous essayez à l'origine, c'est d'exprimer la relation en html. L'autre est de passer aux vues partielles les objets enfants.

Ainsi, vous créez une vue partielle pour une liste de catégories et vous lui transmettez les catégories de produits. Cela devrait prendre soin de le câbler correctement pour vous.

Il serait

@Html.Partial("_myCategoriesPartialView", Model.Categories) 

Ce point de vue bien sûr serait itérer sur la collection. Je crois que si vous voulez le faire dans l'autre sens avec html, il ressemblerait.

<input id="Product[0]_ID" name="Product[0].ID" type="hidden" value="9" /> 

devrait être

<input id="Product[0].ID" name="Product[0].ID" type="hidden" value="9" />, 

mais la façon de dire à coup sûr est de regarder les données Response.Form

Questions connexes