2012-04-12 9 views
57

Podczas korzystania z MVC, zwrot adhoc Json był łatwy.Powracanie anonimowych typów za pomocą interfejsu Web API

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

Poszukuję tej funkcjonalności za pomocą nowego interfejsu API.

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

ta zgłasza wyjątek jako DataContractJsonSerializer nie może obsługiwać anonimowych typów.

Zastąpiłem to tym JsonNetFormatter na podstawie Json.Net. To działa, jeśli mogę użyć

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

ale nie widzę sensu korzystania z sieci Web API, jeśli nie będę powrocie HttpResponseMessage, byłbym lepiej trzymać z wanilii MVC. Jeśli spróbuję użyć:

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

Serializuje całość HttpResponseMessage.

Czy każdy może prowadzić mnie do rozwiązania, w którym mogę zwrócić anonimowe typy w ramach HttpResponseMessage?

Odpowiedz

67

To nie działa w wersji beta, ale ma to miejsce w najnowszym bitów (zbudowany z http://aspnetwebstack.codeplex.com), więc prawdopodobnie będzie to droga dla RC. Można zrobić

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

Nie wydaje się, że tak jest w obecnej wersji. Otrzymuję HTTP 500 podczas wykonywania czegoś podobnego. – CodeMonkeyKing

+0

Działa dobrze dla mnie w 4.0 RTM. – Snixtor

+14

Ważna uwaga, tylko domyślny seriser json może obsługiwać szeregowanie anonimowych obiektów. Domyślny serialalizator XML będzie się nie wyświetlał, więc upewnij się, że zwrócisz anonimowe obiekty, które Twoi klienci wiedzą, aby wysłać, zaakceptuj: application/json w nagłówku. Podobnie jak w przeglądarce Chrome zwykle domyślnie żądam xml, więc to tylko heads up. – Despertar

1

Powinieneś być w stanie to zrobić, jeśli używasz generycznych, ponieważ da ci to "typ" dla twojego anonimowego typu. Następnie możesz związać serializer z tym.

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

Jeśli nie ma DataContract lub DataMebmer atrybuty w swojej klasie, spadnie z powrotem na szeregowania wszystkie właściwości publiczne, które powinny zrobić dokładnie to, czego szukasz.

(nie będę miał okazję przetestować to dopiero później dzisiaj, daj mi znać, jeśli coś nie działa.)

3

można użyć JSONObject na to:

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

return new HttpResponseMessage<JsonObject>(json); 
2

Można też spróbować:

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

Można użyć ExandoObject.(dodaj using System.Dynamic;)

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

można upakować dynamicznego obiektu w zwrocie przedmiotu jak

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

a potem w WebAPI; zrobić coś takiego:

[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; 
} 
10

Ta odpowiedź może przyjść nieco późno, ale na dzień dzisiejszy WebApi 2 jest już na zewnątrz i teraz łatwiej jest robić to, co chcesz, to po prostu trzeba zrobić:

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

i wzdłuż potoku będzie serializowany do xml lub json według lub preferencji klienta (nagłówek Accept). Mam nadzieję, że pomoże to każdemu potknąć się o to pytanie.

+0

Nie dla mnie – doker

+0

@doker Jakiej wersji WebApi używasz, właśnie wkleiłem ten kod z kontrolera używając VS 2015 i WebApi2 – Luiso

+0

5.2 .3 i skończyło się usunięciem formatera xml, ponieważ większość zwróconych obiektów i tak nie serializuje do xml. – doker