Cum se returnează un obiect Json dintr-o metodă C# (Programare, C#, Asp.Net Web Api, Json.Net)

bob.mazzo a intrebat.

Încerc să fixez o metodă ASP.NET WebAPI în care este necesar un răspuns Json. Cu toate acestea, se returnează în schimb un șir de caractere.

Inițial returna formatul XML, dar am adăugat această linie la codul mvc din App_StartWebApiConfig.cs pentru a returna implicit Json.

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

Am actualizat metoda c# după cum urmează pentru a utiliza NewtonSoft:

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

Var-ul resp se întoarce ca fiind de tip string:

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

iar jsonresp var arată astfel :

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

iar în F12 dev tools din Chrome, obiectul de date este :

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

iar în Console tools, rezultatul angular.fromJson(data) :

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

Aș aprecia un sfat despre cum să returnez corect obiectul Json și NU în orice tip de șir.


UPDATE

Prin interceptarea resp var, și folosind sugestia domnului Chu de mai jos, pot obține cu succes un obiect Json frumos și curat pe client.Cheia este că resp trebuie să conțină ghilimele duble în jurul ambelor perechi cheie:valoare:

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

în consola Chrome, răspunsul este :

Object {status: "SUCCESS", data: Array[1]}
data: Array[1]
status: "SUCCESS"
__proto__: Object

Comentarii

  • Ce este resp? Este un șir JSON? –  > Por Anthony Chu.
  • WebApi îl va converti automat în JSON (presupunând că l-ați configurat corespunzător). Nu-l convertiți în JSON și încercați să returnați doar obiectul C#. –  > Por Mike Cheel.
3 răspunsuri
Anthony Chu

resp este deja un șir JSON, dar nu este un JSON valid (cheile nu sunt înfășurate între ghilimele ("). Dacă este returnat către angular, metoda JavaScript JSON.parse() nu poate să îl deserializeze. Cu toate acestea, puteți utiliza JSON.NET în deserializarea acestuia într-un JObject și serializarea lui din nou în JSON valid și să creați propria dvs. 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;
}

Sau puteți returna pur și simplu metoda JObject și să cereți ca Web API să o serializeze pentru dvs…

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

În ambele cazuri, apelul Web API ar trebui să returneze acest JSON, care este acum valid…

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

În codul angular, va trebui să extrageți ID-ul sesiunii, care este stocat într-o matrice numită data

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];
});

Comentarii

  • Am actualizat postarea mea originală pentru a arăta schimbarea – acum folosesc JsonConvert.SerializeObject de la NewtonSoft. –  > Por bob.mazzo.
  • Ați încercat acest răspuns? Se pare că ar trebui să facă ceea ce doriți. –  > Por Anthony Chu.
  • Primesc o eroare de front-end: „SyntaxError: Unexpected token s at Object.parse (native)” –  > Por bob.mazzo.
  • Se pare că resp conține JSON invalid. status și data ar trebui să fie înfășurat în "s. Adresa s de care se plânge eroarea este s în status. –  > Por Anthony Chu.
  • @bob Mi-am actualizat răspunsul pentru a arăta cum puteți utiliza JSON.NET pentru a converti JSON-ul invalid din DynAggrClientAPI.openSession în JSON valid și să îl returnați către Angular. –  > Por Anthony Chu.
BruceHill

Cheia pentru ceea ce se întâmplă aici se află în comentariul făcut de Mike Cheel; serializarea se întâmplă de două ori, o dată în codul OP și o dată de către Asp.Net WebAPI. Acesta este motivul pentru care este returnat un șir de caractere în loc de un fișier Json obiect.

Am întâlnit exact același lucru. Iată un exemplu hello world care arată problema. Prima dată am făcut ceva de genul acesta:

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

Apoi am încercat să fac ceva de genul acesta, crezând că trebuie să returnez IHttpActionResult pentru a rezolva această problemă:

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

Ambele acțiuni ale controlerului mi-au dat un șir de caractere și nu obiectul Json pe care îl doream; așa că am făcut așa:

"{
x
:
hello
,
y
:
world
}"

În cele din urmă am văzut comentariul lui Mike și mi-am dat seama că trebuie să returnez obiectul .Net direct și să las WebAPI să se ocupe de serializare. Deci, în loc să returnez acest lucru:

return Ok(JsonConvert.SerializeObject(result));

return this:

return Ok(result);

Apoi am obținut rezultatul pe care îl așteptam:

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

Comentarii

  • Știu că ați constatat că return Ok(JsonConvert.SerializeObject(result)); a cauzat o problemă. Mă bucur că ai postat acel cod, pentru că acel cod a fost cel care a REZOLVAT problema pe care o aveam. –  > Por StackOverflowUtilizator.
Chad Robinson

Nu văd ce legătură are acest lucru cu AngularJS, dar problema ta este simplă. Obiectul tău de date este codificat JSON. Deci, aproape sigur ai putea accesa data.JsonRequestBehavior și ar fi 1. Dar câmpul tău de date din interiorul lui este din nou codificat JSON. Trebuie să îl decodificați înainte de a încerca să îl utilizați – este doar un șir de caractere când ajungeți la acest callback:

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

Rețineți că obiectul data.Data este el însuși un alt înveliș – o matrice. Aproape sigur doriți ca myData.data[0] să intrați în câmpul sessionID…

Comentarii

  • PS, toate acestea se întâmplă probabil pentru că faceți string resp = DynAggrClientAPI.openSession( userid, pwd ); și luați rezultatul sub forma unui șir de caractere. Nu ați inclus cod pentru aceasta, dar dacă aveți acest lucru returnează un obiect real, codificatorul JSON poate probabil să evite dubla codificare și să vă permită săriți peste pasul de mai sus. –  > Por Chad Robinson.
  • var-ul „resp” este într-adevăr sursa conflictului aici. Este un program C++ care returnează acest lucru. Voi avea nevoie ca acel programator să returneze un fel de obiect formatat Json, presupun. –  > Por bob.mazzo.
  • am actualizat codul pentru a utiliza JsonSerializer(). Rezultatul datelor mele se întoarce acum ca „”{status:
    SUCCESS
    „,data:[
    9f950502cd3e0a81cab3b2c7b4fc65395b0b40741130c7aead498a
    ]}”” -”  > Por bob.mazzo.
  • între timp, extrag câmpul data: aplicând mai întâi JSON.parse(data), apoi folosind funcția .split() pentru a accesa câmpul data:. Nu este ideal, dar funcționează între timp. –  > Por bob.mazzo.