Modèle DataContract se liant à JSON dans ASP.NET MVC Action Method Arguments

MVC3 sort de la boîte avec JsonValueProviderFactory () qui est très pratique pour lier le JSON entrant à un modèle. Malheureusement, je ne vois pas comment configurer des contrats de modèle avec des noms différents du JSON entrant. Par exemple:

[DataContract(Name = "session")] public class FacebookSession { [DataMember(Name = "access_token")] public ssortingng AccessToken { get; set; } [DataMember(Name = "expires")] public int? Expires { get; set; } [DataMember(Name = "secret")] public ssortingng Secret { get; set; } [DataMember(Name = "session_key")] public ssortingng Sessionkey { get; set; } [DataMember(Name = "sig")] public ssortingng Signature { get; set; } [DataMember(Name = "uid")] public ssortingng UserId { get; set; } } 

lors de la transmission d’un object JSON représentant la session facebook, les propriétés secret et expire se lient correctement, mais le rest ne le fait pas car le nom de la propriété est différent du nom de la clé Json. Je m’attendrais à ce que le sérialiseur datacontract tente de se lier au nom fourni dans l’atsortingbut, mais cela ne semble pas être le cas. Quelqu’un at-il des suggestions de solution de contournement?

modifier

Un exemple d’utilisation de ce modèle:

  public ActionResult Log(int? custId, FacebookSession response) { ViewBag.Id = response.UserId; return View(); } 

J’ai fini par utiliser l’ exemple de classeur de modèle de liaison de gt124 avec un meilleur classeur de modèle pour écrire ma propre logique de liaison de modèle. Cela a fini par ressembler à ceci:

 public interface IFilteredModelBinder : IModelBinder { bool IsMatch(Type modelType); } public class SmartModelBinder : DefaultModelBinder { private readonly IFilteredModelBinder[] _filteredModelBinders; public SmartModelBinder(IFilteredModelBinder[] filteredModelBinders) { _filteredModelBinders = filteredModelBinders; } public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { foreach (var filteredModelBinder in _filteredModelBinders) { if (filteredModelBinder.IsMatch(bindingContext.ModelType)) { return filteredModelBinder.BindModel(controllerContext, bindingContext); } } return base.BindModel(controllerContext, bindingContext); } } public class NewtonsoftJsonModelBinder : IFilteredModelBinder { public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { if (!controllerContext.HttpContext.Request.ContentType.StartsWith("application/json", SsortingngComparison.OrdinalIgnoreCase)) { // not JSON request return null; } var request = controllerContext.HttpContext.Request; request.InputStream.Position = 0; var incomingData = new StreamReader(request.InputStream).ReadToEnd(); if (Ssortingng.IsNullOrEmpty(incomingData)) { // no JSON data return null; } object ret = JsonConvert.DeserializeObject(incomingData, bindingContext.ModelType); return ret; } public bool IsMatch(Type modelType) { var ret = (typeof(JsonModel).IsAssignableFrom(modelType)); return ret; } } 

J’ai ensuite utilisé les atsortingbuts JSON.net pour mapper les différentes propriétés d’object (au lieu de DataContracts) sur les modèles. Les modèles ont tous hérité d’une classe de base vide JsonModel.

Vous pouvez le transmettre sous forme de chaîne et appeler manuellement le datacontractdeserializer, sauf si vous écrivez votre propre modelbinder. Je crois que le classeur par défaut utilise le javascriptserializer, pas le datacontractjsserializer.

Exemple de classeur

Vous n’avez pas besoin de remplacer le classeur par défaut, écrivez simplement un atsortingbut comme celui-ci.

 public class DataContractJsonModelBinderAtsortingbute : CustomModelBinderAtsortingbute { public override IModelBinder GetBinder() { return new DataContractJsonModelBinder(); } } 

l’utilisation est simple

 [DataContract(Name = "session")] [DataContractJsonModelBinder] public class FacebookSession { [DataMember(Name = "access_token")] public ssortingng AccessToken { get; set; } [DataMember(Name = "expires")] public int? Expires { get; set; } [DataMember(Name = "secret")] public ssortingng Secret { get; set; } [DataMember(Name = "session_key")] public ssortingng Sessionkey { get; set; } [DataMember(Name = "sig")] public ssortingng Signature { get; set; } [DataMember(Name = "uid")] public ssortingng UserId { get; set; } } 

UPDATE Maintenant, vous pouvez simplement utiliser les fonctionnalités intégrées de Json.NET comme ceci:

 [JsonObject] public class FacebookSession { [JsonProperty("access_token")] public ssortingng AccessToken { get; set; } } 

et si nécessaire

 var facebokSession = JsonConvert.DeserializeObject(facebookSessionJsonSsortingng);