web-dev-qa-db-fra.com

Renvoi de types anonymes avec Web API

Lors de l'utilisation de MVC, renvoyer adhoc Json était facile.

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

Je recherche cette fonctionnalité avec la nouvelle API Web.

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

Cela lève une exception car le DataContractJsonSerializer ne peut pas gérer les types anonymes.

J'ai remplacé ceci par ceci 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, il vaudrait mieux que je m'en tiens à Vanilla MVC. Si j'essaie d'utiliser:

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

Il sérialise l'ensemble HttpResponseMessage.

Quelqu'un peut-il me guider vers une solution permettant de retourner des types anonymes dans un HttpResponseMessage?

71
Magpie

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

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

Cette réponse peut venir un peu tard, mais à partir d’aujourd’hui WebApi 2 est déjà sorti et maintenant il est plus facile de faire ce que vous voulez, il vous suffirait de faire:

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

et le long du pipeline, il sera sérialisé à 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

16
Luiso

vous pouvez utiliser JsonObject pour cela:

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

return new HttpResponseMessage<JsonObject>(json);
6
SeriousM

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

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

Dans la Web API 2, vous pouvez utiliser le nouveau IHttpActionResult, qui remplace HttpResponseMessage, puis renvoyer un objet Json simple: (Similair à MVC)

public IHttpActionResult GetJson()
    {
       return Json(new { Message = "Hello"});
    }
4
D.B

Vous pouvez aussi 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());
3
leojh

Vous devriez pouvoir faire en sorte que cela fonctionne 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<T> MakeResponse(T object, HttpStatusCode code)
{
    return new HttpResponseMessage<T>(object, code);
}

S'il n'y a pas d'attribut DataContract ou DataMebmer dans votre classe, il retombera sur la sérialisation de toutes les propriétés publiques, ce qui devrait faire exactement ce que vous recherchez.

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

2
Michael Edenfield

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/

1

Vous pouvez encapsuler un objet dynamique en renvoyant un objet 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<dynamic>(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;
}
0
Subodh Pushpak