Как вернуть объект Json из метода С#
Я пытаюсь исправить метод ASP.NET WebAPI, где требуется ответ Json. Однако вместо этого он возвращает строку.
Первоначально это был формат XML, но я добавил эту строку в код mvc в App_Start\WebApiConfig.cs, чтобы вернуть Json по умолчанию.
config.Formatters.Remove(config.Formatters.XmlFormatter);
Мы обновили метод c # следующим образом, чтобы использовать 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 возвращается как строковый тип:
"{status:\"SUCCESS\",data:[\"4eb97d2c6729df98206cf214874ac1757649839fe4e24c51d21d\"]}"
и jsonresp var выглядит так:
"\"{status:\\\"SUCCESS\\\",data:[\\\"4eb97d2c6729df98206cf214874ac1757649839fe4e24c51d21d\\\"]}\""
и в инструментах разработчика Chrome F12 объект данных:
""{status:\"SUCCESS\",data:[\"4eb97d2c6729df98206cf214874ac1757649839fe4e24c51d21d\"]}""
и в Консольных инструментах результат angular.fromJson(data):
"{status:"SUCCESS",data:["4eb97d2c6729df98206cf214874ac1757649839fe4e24c51d21d"]}"
Я хотел бы получить несколько советов о том, как правильно возвращать объект Json, а НЕ в любом типе строки.
UPDATE
Перехватив переменную resp
и воспользовавшись приведенным ниже предложением г-на Чу, я могу успешно получить хороший чистый объект Json на клиенте.
Ключ в том, что resp
должен содержать двойные кавычки вокруг обеих пар ключ: значение:
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;
}
в консоли Chrome ответ:
Object {status: "SUCCESS", data: Array[1]}
data: Array[1]
status: "SUCCESS"
__proto__: Object
Ответы
Ответ 1
resp
уже является строкой JSON, но недействителен JSON (ключи не заключены в кавычки ("
). Если он возвращается в angular, метод 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
и иметь веб-интерфейс для его сериализации для вас...
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
...
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];
});
Ответ 2
Я не вижу, как это связано с AngularJS, но ваша проблема проста. Ваш объект данных закодирован JSON. Таким образом, вы почти наверняка сможете получить доступ к data.JsonRequestBehavior
, и это будет 1
. Но поле данных внутри него AGAIN JSON-закодировано. Вы должны декодировать его, прежде чем пытаться его использовать - это просто строка, когда вы добираетесь до этого обратного вызова:
var myData = angular.fromJson(data.Data);
console.log(myData.data);
Обратите внимание, что ваш объект data.Data сам по себе является другой оболочкой - массивом. Вы почти наверняка хотите, чтобы myData.data[0]
заходил в это поле sessionID...
Ответ 3
Ключ к тому, что здесь происходит, в комментарии, сделанном Майком Чилом; сериализация происходит дважды, один раз в коде OP и один раз в 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\"}"
Наконец, я увидел комментарий Майка и понял, что мне нужно возвращать объект .Net напрямую и просто позволить WebAPI
обрабатывать сериализацию. Поэтому вместо того, чтобы возвращать это:
return Ok(JsonConvert.SerializeObject(result));
вернуть это:
return Ok(result);
Тогда я получил ожидаемый результат:
{"x":"hello","y":"world"}