web-dev-qa-db-ja.com

Web APIで匿名型を返す

MVCを使用する場合、アドホックJsonを返すのは簡単でした。

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

新しいWeb APIでこの機能を探しています。

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

DataContractJsonSerializerは匿名型を処理できないため、例外がスローされます。

これをこれに置き換えました JsonNetFormatter based onJson.Netこれは私が使用する場合に機能します

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

しかし、HttpResponseMessageを返さない場合、Web APIを使用する意味がわかりません。VanillaMVCに固執する方が良いでしょう。私が試して使用する場合:

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

HttpResponseMessage全体をシリアル化します。

誰でもHttpResponseMessage内で匿名型を返すことができるソリューションに導くことができますか?

71
Magpie

これはベータリリースでは機能しませんが、最新のビット( http://aspnetwebstack.codeplex.com から構築)では機能するため、RCの方法になる可能性があります。できるよ

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

この回答は少し遅れることがありますが、今日の時点でWebApi 2は既にリリースされており、必要なことを簡単に行えるようになりました。

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

そして、パイプラインに沿って、クライアントのプリファレンス(xmlヘッダー)に従ってjsonまたはAcceptにシリアル化されます。これがこの質問につまずく人を助けることを願っています

16
Luiso

これにはJsonObjectを使用できます。

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

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

ExandoObject を使用できます。 (add 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

Web API 2では、HttpResponseMessageに代わる新しいIHttpActionResultを使用して、単純なJsonオブジェクトを返すことができます(MVCに似ています)。

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

以下も試してみてください:

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

ジェネリックを使用すると、匿名型の「型」が得られるため、これを機能させることができます。その後、シリアライザーをそれにバインドできます。

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

クラスにDataContractまたはDataMebmer属性がない場合、すべてのパブリックプロパティのシリアル化にフォールバックします。

(今日後半までこれをテストする機会はありません。何かがうまくいかない場合はお知らせください。)

2

ASP.NET Web API 2.1では、より簡単な方法でそれを行うことができます。

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

これについての詳細は https://www.strathweb.com/2014/02/dynamic-action-return-web-api-2-1/ で読むことができます。

次のようなオブジェクトを返す際に動的オブジェクトをカプセル化できます

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

そしてWebAPIで;次のようなことを行います:

[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