web-dev-qa-db-ja.com

C#メソッドからJsonオブジェクトを返す方法

Json応答が必要なASP.NET WebAPIメソッドを修正しようとしています。ただし、代わりに文字列を返します。

最初はXML形式を取得していましたが、デフォルトでJsonを返すために、App_Start\WebApiConfig.csのmvcコードにこの行を追加しました。

config.Formatters.Remove(config.Formatters.XmlFormatter);

NewtonSoftを使用するために、c#メソッドを次のように更新しました。

public string Get()
{
    string userid = UrlUtil.getParam(this, "userid", "");
    string pwd = UrlUtil.getParam(this, "pwd", "");
    string resp = DynAggrClientAPI.openSession(userid, pwd);

    JsonSerializer ser = new JsonSerializer();
    string jsonresp = JsonConvert.SerializeObject(resp);

    return resp;
}

Resp varは文字列型として返されます:

"{status:\"SUCCESS\",data:[\"4eb97d2c6729df98206cf214874ac1757649839fe4e24c51d21d\"]}"

jsonresp varは次のようになります。

"\"{status:\\\"SUCCESS\\\",data:[\\\"4eb97d2c6729df98206cf214874ac1757649839fe4e24c51d21d\\\"]}\""

また、ChromeのF12開発ツールでは、データオブジェクトは次のとおりです。

""{status:\"SUCCESS\",data:[\"4eb97d2c6729df98206cf214874ac1757649839fe4e24c51d21d\"]}""

コンソールツールでは、angular.fromJson(data)の結果:

"{status:"SUCCESS",data:["4eb97d2c6729df98206cf214874ac1757649839fe4e24c51d21d"]}"

文字列型ではなく、Jsonオブジェクトを適切に返す方法に関するアドバイスをいただければ幸いです。


更新

resp varをインターセプトし、以下のChu氏の提案を使用することにより、クライアントでNice clean Jsonオブジェクトを正常に実現できます。重要なのは、respには両方のkey:valueペアを二重引用符で囲む必要があるということです。

public HttpResponseMessage Get()
{
    string userid = UrlUtil.getParam(this, "userid", "");
    string pwd = UrlUtil.getParam(this, "pwd", "");
    string resp = DynAggrClientAPI.openSession(userid, pwd);

    resp = "{\"status\":\"SUCCESS\",\"data\":[\"194f66366a6dee8738428bf1d730691a9babb77920ec9dfa06cf\"]}";  // TEST !!!!!           

    var response = Request.CreateResponse(HttpStatusCode.OK);
    response.Content = new StringContent(resp, System.Text.Encoding.UTF8, "application/json");
    return response;
}

in Chrome console、応答は次のとおりです。

Object {status: "SUCCESS", data: Array[1]}
data: Array[1]
status: "SUCCESS"
__proto__: Object
13
bob.mazzo

respはすでにJSON文字列ですが、有効なJSONではありません(キーは引用符で囲まれていません(")。アンギュラーに返された場合、JavaScript JSON.parse()メソッドはデシリアライズできません。ただし、JSON.NETを使用してJObjectにデシリアライズし、有効なJSONに再度シリアライズして、独自のHttpResponseMessage...を作成できます。

public HttpResponseMessage Get()
{
    string userid = UrlUtil.getParam(this, "userid", "");
    string pwd    = UrlUtil.getParam(this, "pwd", "" );

    string resp = DynAggrClientAPI.openSession(userid, pwd);
    var jObject = JObject.Parse(resp);

    var response = Request.CreateResponse(HttpStatusCode.OK);
    response.Content = new StringContent(jObject.ToString(), Encoding.UTF8, "application/json");
    return response;
}

または、単にJObjectを返し、Web APIでシリアル化してください...

public JObject Get()
{
    string userid = UrlUtil.getParam(this, "userid", "");
    string pwd    = UrlUtil.getParam(this, "pwd", "" );

    string resp = DynAggrClientAPI.openSession(userid, pwd);
    var jObject = JObject.Parse(resp);

    return jObject;
}

どちらの場合でも、Web API呼び出しはこのJSONを返すはずです。これは現在有効です...

{
  "status": "SUCCESS",
  "data": [
    "4eb97d2c6729df98206cf214874ac1757649839fe4e24c51d21d"
  ]
}

angularコードでは、data...という配列に保存されているセッションIDを掘り下げる必要があります。

userService.openUserSession(rzEnvJson).then(function (response) {
    var sessionResponse = response.data; // or simply response, depending if this is a promise returned from $http
    $rootScope.rgSessionVars.sessionID = sessionResponse.data[0];
});
28
Anthony Chu

これがAngularJSとどう関係するかわかりませんが、あなたの問題は簡単です。データオブジェクトはJSONエンコードされています。したがって、ほぼ確実にdata.JsonRequestBehaviorにアクセスでき、1になります。ただし、その中のデータフィールドはAGAIN JSONエンコードされています。使用する前にデコードする必要があります。このコールバックに到達するときは、単なる文字列です。

var myData = angular.fromJson(data.Data);
console.log(myData.data);

Data.Dataオブジェクト自体が別のラッパー-配列であることに注意してください。ほぼ確実にmyData.data[0]をそのsessionIDフィールドに入れたい...

2
Chad Robinson

ここで行われていることの鍵は、 Mike Cheel ;によるコメントにあります。シリアル化は、OPのコードで1回、Asp.Net WebAPI。そのため、Jsonオブジェクトの代わりに文字列が返されます。

私はまったく同じことに遭遇していました。問題を示すハローワールドの例を次に示します。私は最初にこのようなことをしました:

[Route("getall")]
public string GetAllItems()
{
    var result = new
    {
        x = "hello",
        y = "world"
    };
    return JsonConvert.SerializeObject(result);
}

私はそれを解決するためにIHttpActionResultを返す必要があると考えて、このようなことを試みました:

[Route("getall")]
public IHttpActionResult GetAllItems()
{
    var result = new
    {
        x = "hello",
        y = "world"
    };
    return Ok(JsonConvert.SerializeObject(result));
}

これらのコントローラーアクションはどちらも、私が望んでいたJsonオブジェクトではなく、文字列を提供しました。だから私はこれに行きます:

"{\"x\":\"hello\",\"y\":\"world\"}"

最後に、Mikeのコメントを見て、.Netオブジェクトを直接返して、WebAPIにシリアル化を処理させる必要があることに気付きました。したがって、これを返す代わりに:

return Ok(JsonConvert.SerializeObject(result));

これを返します:

return Ok(result);

それから私は期待していた結果を得ました:

{"x":"hello","y":"world"}
1
BruceHill