Renvoi de types anonymes avec Web API

Lors de l’utilisation de MVC, le retour de adhoc Json était facile.

return Json(new { Message = "Hello"}); 

Je recherche cette fonctionnalité avec la nouvelle API Web.

 public HttpResponseMessage Test() { return new HttpResponseMessage(new { Message = "Hello" }, HttpStatusCode.OK); } 

Cela génère une exception car DataContractJsonSerializer ne peut pas gérer les types anonymes.

Je l’ai remplacé par ce JsonNetFormatter basé sur Json.Net . Cela fonctionne si j’utilise

  public object Test() { return new { Message = "Hello" }; } 

mais je ne vois pas l’intérêt d’utiliser l’API Web si je ne retourne pas HttpResponseMessage , je ferais mieux de me HttpResponseMessage à MVC vanille. Si j’essaie d’utiliser:

 public HttpResponseMessage Test() { return new HttpResponseMessage(new { Message = "Hello" }, HttpStatusCode.OK); } 

Il sérialise l’intégralité de HttpResponseMessage .

Quelqu’un peut-il me guider vers une solution où je peux renvoyer des types anonymes dans un HttpResponseMessage ?

Cela ne fonctionne pas dans la version bêta, mais cela se fait dans les derniers bits (construit à partir de http://aspnetwebstack.codeplex.com ), donc ce sera probablement la voie pour RC. Tu peux faire

 public HttpResponseMessage Get() { return this.Request.CreateResponse( HttpStatusCode.OK, new { Message = "Hello", Value = 123 }); } 

Cette réponse est peut-être un peu tardive, mais WebApi 2 est déjà sorti et il est désormais plus facile de faire ce que vous souhaitez:

 public object Message() { return new { Message = "hello" }; } 

et le long du pipeline, il sera sérialisé en xml ou json selon les préférences du client (l’en-tête Accept ). J’espère que cela aide quelqu’un qui tombe sur cette question

Vous pouvez utiliser un ExandoObject . (append en using System.Dynamic; )

 [Route("api/message")] [HttpGet] public object Message() { dynamic expando = new ExpandoObject(); expando.message = "Hello"; expando.message2 = "World"; return expando; } 

vous pouvez utiliser JsonObject pour cela:

 dynamic json = new JsonObject(); json.Message = "Hello"; json.Value = 123; return new HttpResponseMessage(json); 

Vous devriez pouvoir le faire fonctionner si vous utilisez des génériques, car cela vous donnera un “type” pour votre type anonyme. Vous pouvez ensuite lier le sérialiseur à cela.

 public HttpResponseMessage MakeResponse(T object, HttpStatusCode code) { return new HttpResponseMessage(object, code); } 

S’il n’y a pas d’ DataContract ou DataMebmer sur votre classe, il s’agira de sérialiser toutes les propriétés publiques, ce qui devrait faire exactement ce que vous recherchez.

(Je n’aurai pas la chance de tester cela avant plus tard aujourd’hui, faites-moi savoir si quelque chose ne fonctionne pas.)

Vous pouvez également essayer:

 var request = new HttpRequestMessage(HttpMethod.Post, "http://leojh.com"); var requestModel = new {User = "User", Password = "Password"}; request.Content = new ObjectContent(typeof(object), requestModel, new JsonMediaTypeFormatter()); 

Dans ASP.NET Web API 2.1, vous pouvez le faire de manière plus simple:

 public dynamic Get(int id) { return new { Id = id, Name = "X" }; } 

Vous pouvez en savoir plus à ce sujet sur https://www.strathweb.com/2014/02/dynamic-action-return-web-api-2-1/

Vous pouvez encapsuler un object dynamic en renvoyant un object comme

 public class GenericResponse : BaseResponse { public dynamic Data { get; set; } } 

puis dans WebAPI; faire quelque chose comme:

 [Route("api/MethodReturingDynamicData")] [HttpPost] public HttpResponseMessage MethodReturingDynamicData(RequestDTO request) { HttpResponseMessage response; try { GenericResponse result = new GenericResponse(); dynamic data = new ExpandoObject(); data.Name = "Subodh"; result.Data = data;// OR assign any dynamic data here;// response = Request.CreateResponse(HttpStatusCode.OK, result); } catch (Exception ex) { ApplicationLogger.LogCompleteException(ex, "GetAllListMetadataForApp", "Post"); HttpError myCustomError = new HttpError(ex.Message) { { "IsSuccess", false } }; return Request.CreateErrorResponse(HttpStatusCode.OK, myCustomError); } return response; }