У меня есть запрос SQL, который возвращает ответ json. Запрос был проанализирован с использованием FOR JSON AUTO в базе данных. Проблема, с которой я сталкиваюсь, заключается в том, что когда я запрашиваю базу данных в своем приложении, я получаю обратную косую черту. Когда я выполняю хранимую процедуру в студии управления сервером SQL, результаты возвращаются хорошо. Но когда я делаю запрос из приложения с помощью ADO.net, я получаю обратную косую черту.
Ответ от SSMS
{
"role": "Commercial Credit Solutions Manager",
"Applications": [
{
"name": "LOS",
"Authorizations": [
{
"permissions": "Pre-Approve",
"AppPermissions": [
{
"NOTES": null
}
]
},
{
"permissions": "Pend",
"AppPermissions": [
{
"NOTES": null
}
]
}
]
},
{
"name": "DNA",
"Authorizations": [
{
"permissions": "L05",
"AppPermissions": [
{
"NOTES": null
}
]
},
{
"permissions": "L11",
"AppPermissions": [
{
"NOTES": "Only on manager's approval"
}
]
}
]
}
]
}
Когда я возвращаю JsonResult из контроллера, я получаю сообщение об ошибке: «VM26: 1 Uncaught (в обещании) SyntaxError: неожиданный токен« S »,« System.Not »... недействителен JSON» на стороне клиента.
В режиме отладки это ответ, но я получаю недопустимый Json на стороне клиента.
JSON_F52E2B61-18A1-11d1-B105-00805F49916B
"{""role"":""Commercial Credit Solutions Manager"",""Applications"":[{""name"":""LOS"",""Authorizations"":[{""permissions"":""Pre-Approve"",""AppPermissions"":[{""NOTES"":null}]},{""permissions"":""Pend"",""AppPermissions"":[{""NOTES"":null}]}]},{""name"":""DNA"",""Authorizations"":[{""permissions"":""L05"",""AppPermissions"":[{""NOTES"":null}]},{""permissions"":""L11"",""AppPermissions"":[{""NOTES"":""Only on manager's approval""}]}]}]}"
когда я сериализую свой код С#, я получаю ответ ниже с обратной косой чертой:
QueryTables
public DataTable QueryTables(int id)
{
ConnectToDataBase();
SqlCommand cmd = new("spGetAppAndPermissions", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("id", id);
DataSet _dataSet = new();
SqlDataAdapter adapter = new(cmd);
DataTable response = new();
adapter.Fill(response);
con.Close();
return response;
}
дбконтекст
public DataTable GetAppsAndPermission(int id)
{
DataTable dbResponse = QueryTables(id);
return dbResponse;
}
Контроллер
[HttpGet]
[Route("home/GetAssignments/{id:int?}")]
public JsonResult GetAssignments(int id)
{
DataTable response = dbContext.GetAppsAndPermission(id);
//DataRow test = response.Rows[0][0];
((string)response.Rows[0][0]).Replace("\"", string.Empty);
List < Dictionary<string, object>> rows = new List<Dictionary<string, object>>();
Dictionary<string, object> row;
foreach (DataRow dr in response.Rows)
{
row = new Dictionary<string, object>();
foreach (DataColumn col in response.Columns)
{
row.Add(col.ColumnName, dr[col]);
}
rows.Add(row);
}
//Replace(@"\""", @"""");
//JsonConvert.SerializeObject(rows)
return Json(JsonConvert.SerializeObject(rows));
}
Я получаю ответ ниже после сериализации:
[
{
"JSON_F52E2B61-18A1-11d1-B105-00805F49916B": "{\"role\":\"Commercial Credit Solutions Manager\",\"Applications\":[{\"name\":\"LOS\",\"Authorizations\":[{\"permissions\":\"Pre-Approve\",\"AppPermissions\":[{\"NOTES\":null}]},{\"permissions\":\"Pend\",\"AppPermissions\":[{\"NOTES\":null}]}]},{\"name\":\"DNA\",\"Authorizations\":[{\"permissions\":\"L05\",\"AppPermissions\":[{\"NOTES\":null}]},{\"permissions\":\"L11\",\"AppPermissions\":[{\"NOTES\":\"Only on manager's approval\"}]}]}]}"
}
]
Чтобы исправить это, я попробовал Json.stringify, затем привязал замену метона и синтаксический анализ обратно в JSON, но я все равно вернулся к тому, где был изначально. Недопустимый JSON. См. хранимую процедуру ниже:
CREATE PROCEDURE spGetAppAndPermissions(@ID AS INT)
AS
BEGIN
SELECT ROLE_NAME AS role,APPLICATION_NAME AS name ,
AUTH_LABEL AS permissions,NOTES
FROM AppPermissions
JOIN roles
ON roles.ROLE_ID = AppPermissions.ROLE_ID
JOIN Applications
ON Applications.APP_ID = AppPermissions.APP_ID
JOIN Authorizations
ON Authorizations.AUTH_ID = AppPermissions.AUTH_ID
WHERE Roles.ROLE_ID = @ID
FOR JSON AUTO,INCLUDE_NULL_VALUES,WITHOUT_ARRAY_WRAPPER;
END;
Было бы проще просто вернуть результат JSON из базы данных на уровень .NET, а затем десериализовать JSON в объект?
Подождите... Итак, вы получаете JSON из своей базы данных (т. е. строку), которую затем сериализуете (двойную сериализацию), а затем задаетесь вопросом, почему ваши данные были дважды сериализованы?
@ProgrammingLlama Я тоже так рассуждал. Если вы посмотрите на мои коды, вы заметите, что я пытался вернуть данные JSON как есть из базы данных, но я получаю сообщение об ошибке на стороне клиента. Вот что здесь сбивает с толку.
@Kane Мне не совсем понятно, что пример кода действительно поможет здесь. Спасибо
Не могли бы вы поделиться соответствующим классом, чтобы его можно было исследовать соответствующим образом.
@MdFaridUddinKiron, пожалуйста, уточните, что вы имеете в виду по соответствующему классу. Ответ не является строго типизированным. Это обычный ответ Json на SQL-запрос в приложении. Спасибо
Хорошо, могу я узнать, почему вы перепривязываете свой ответ DataTable в строку через цикл? Почему бы вам не сериализовать свой ответ с данными непосредственно в класс, а затем вернуть его как json. Вот почему я прошу класс или создать класс, соответствующий вашему ответу, чтобы json был в правильном формате.





Md Farid Uddin Kiron, я разобрался в чем проблема. Я принял предложение Кейна.
Однако, поскольку ответ уже поступил из БД в виде сериализованного объекта, его анализ в вызове response.json в запросе на выборку снова сериализует его. Это вызывает двойную сериализацию.
Чтобы решить эту проблему, я преобразовал ответ в строку на уровне C#, а затем сериализовал на стороне клиента.
Любая помощь в этом будет высоко оценена.