2013-01-14 2 views
0

J'ai des problèmes quand j'essaye de désérialiser json dans un objet dans MVC4.Json désérialisation Mvc 4 Knockout js

J'ai viewmodel:

public class TestViewModel 
{ 
    public string Code { get; set; } 

} 

Sur la vue que je reçois le modèle et sérialiser l'objet en utilisant Json.net

var Vm = function(data) { 
     var self = this; 

     ko.mapping.fromJS(data, {}, self); 

     self.GetResults = function() { 
      $.ajax({ 
       type: "POST", 
       url: '@Url.Action("Action", "Controller")', 
       data: ko.mapping.toJSON(self), 
       success: function(data) { 
        alert('OK'); 
       } 
      }); 
     }; 
    }; 

    var viewModel = new Vm(@Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Model))); 
    ko.applyBindings(viewModel); 

Mon problème est quand je l'appelle GetResults l'action dans le contrôleur , toutes les propriétés sont nulles.

Mon JSON est:

{"Code":"TestCode"} 

J'ai la même structure dans un projet MVC3 et fonctionne très bien. Il me manque quelque chose dans MVC4?

À la votre!

+0

Avez-vous essayé d'utiliser Fiddler pour voir à quoi ressemblent la requête et la réponse? – Rich

+0

Oui, la demande semble bien, il a Content-Type: application/json Accepter: application/json, text/javascript, */*; q = 0,01, et le json dans la question {"Code": "TestCode"} – estebane97

Répondre

1

Nous avons remarqué que dans certains scénarios, jQuery incorporera les données dans un formulaire dans la demande. Lorsque cela se produit, les valeurs ne sont pas automatiquement mappées au type d'objet dans la méthode Controller.

Pour contourner ce problème, vous devez faire deux choses:

1) Vérifiez si les données sont sérialisés. J'ai trouvé un moyen facile de le faire et dans une jetai méthode d'extension:

public static class WebContextExtensions 
{ 
    public static bool IsDataSerialized(this HttpContext context) 
    { 
     return context.Request.Params.AllKeys[0] == null; 
    } 
} 

2) IF retourne IsDataSerialized vrai, vous devez désérialiser les données dans votre type d'objet. Nous avons écrit une méthode GenericDeserializer pour le faire ainsi:

public class GenericContextDeserializer<T> where T : new() 
{ 
    public T DeserializeToType(HttpContext context) 
    { 
     T result = new T(); 
     if (context != null) 
     { 
      try 
      { 
       string jsonString = context.Request.Form.GetValues(0)[0].ToString(); 
       Newtonsoft.Json.JsonSerializer js = new Newtonsoft.Json.JsonSerializer(); 
       result = js.Deserialize<T>(new Newtonsoft.Json.JsonTextReader(
           new System.IO.StringReader(jsonString))); 
      } 
      catch (Exception ex) 
      { 
       throw ex; 
      } 
     } 
     else 
      throw new NullReferenceException(); 
     return result; 
    } 
} 

Maintenant, mettez tous ensemble dans votre méthode Controller:

[HttpPost] 
[HttpOptions] 
public HttpResponseMessage MyAction(JsonData data) 
{ 
    var results = Request.CreateResponse(); 
    try 
    { 
     data = new GenericContextDeserializer<JsonData>().DeserializeToType(HttpContext.Current); 
     // do stuff with data 
     results.StatusCode = HttpStatusCode.OK; 
    } 
    catch (Exception ex) 
    { 
     results.StatusCode = HttpStatusCode.InternalServerError; 
    } 
    return results; 
} 

Si vous voulez plus de détails, il est dans la deuxième moitié de a blog post je l'ai écrit .