Я делаю C # JSON <-> PHP JSON впервые.
Я думал, что пойду по легкой дороге, но похоже, что попал в камень.
Я вполне уверен, что JSON от Newtonsoft позволяет[«характер, но не уверен, почему у меня есть эта ошибка вместо этого?
Вот мой код C #:
public class SystemJSON
{
public bool Status { get; set; }
public string Message { get; set; }
public string ResponseData { get; set; }
}
public static class SystemCall
{
public static String Post(string uri, NameValueCollection pairs)
{
byte[] response = null;
using (WebClient wc = new WebClient())
{
response = wc.UploadValues(uri, pairs);
}
return Encoding.Default.GetString(response);
}
}
string system_Response = SystemCall.Post("http://127.0.0.1:8080/edsa-NEFS%20(PHP)/api.php", new NameValueCollection()
{
{"do_work", Functions.Get_Department_List.ToString()},
{"api_data", null }
});
**SystemJSON systemJSON = JsonConvert.DeserializeObject<SystemJSON>(system_Response);** //<-- Error happens here.
if(systemJSON.Status == true)
{
//do stuff here
}else
{
MessageBox.Show(this, systemJSON.Message, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
А вот мой код PHP:
<?php
// Load Request
$function_name = isset($_POST['do_work']) ? $_POST['do_work'] : '';
$api_data = isset($_POST['api_data']) ? $_POST['api_data'] : '';
// Validate Request
if (empty($function_name))
{
SystemResponse(false, 'Invalid Request');
}
if (!function_exists($function_name))
{
SystemResponse(false, 'API Method Not Implemented');
}
// Call API Method
call_user_func($function_name, $api_data);
/* Helper Function */
function SystemResponse($responseStatus, $responseMessage, $responseData = '')
{
exit(json_encode(array(
'Status' => $responseStatus,
'Message' => $responseMessage,
'ResponseData' => $responseData
)));
}
/* API Methods */
function Get_Department_List($api_data)
{
//Test ------------------------------------------START
$node = array();
$dept = array();
$responseData = array();
$dept['id'] = 1;
$dept['name'] = "General";
$dept['description'] = "Forms, Samples, Templates, Catalogs, etc";
$dept['status'] = 1;
array_push($node, $dept);
$dept['id'] = 2;
$dept['name'] = "Test";
$dept['description'] = "Testing";
$dept['status'] = 1;
array_push($node, $dept);
$responseData["dept"] = $dept;
SystemResponse(true, 'SUCCESS', $responseData);
//Test ------------------------------------------END
}
?>
И вот моя ошибка:
Newtonsoft.Json.JsonReaderException HResult = 0x80131500
Сообщение = неожиданный символ, обнаруженный при разборе значения: {. Дорожка
«ResponseData», строка 1, позиция 51.
Проблема в том, что ваш класс C # SystemJSON не соответствует структуре входящего JSON правильно.
ResponseData
в вашем C # SystemJSON класс указан как string
но ваш PHP, кажется, выталкивает сложный объект внутри этого свойства. Вы не можете десериализовать объект в строку — у десериализатора нет способа узнать, как преобразовать структуру объекта в подходящую строку, и, в любом случае, это обычно не полезно и не логично. Таким образом, вместо этого выдается сообщение о том, что структура объекта не совпадает.
Конкретная ошибка, которую вы видите, означает, что десериализатор ожидает "
обозначить начало строки, но вместо этого он видит {
обозначает начало другого объекта.
Почему это происходит? Ну, ваш код PHP будет выдавать ответ JSON, который выглядит следующим образом:
{
"Status": true,
"Message": "SUCCESS",
"ResponseData": {
"dept": {
"id": 2,
"name": "Test",
"description": "Testing",
"status": 1
}
}
}
Как вы можете видеть, ResponseData содержит объект, который имеет «dept», который, в свою очередь, является другим объектом с четырьмя другими свойствами.
Чтобы десериализовать это должным образом, ваш класс SystemJSON должен быть изменен, и вам также понадобятся два подкласса, чтобы помочь ему:
public class SystemJSON
{
public bool Status { get; set; }
public string Message { get; set; }
public ResponseData ResponseData { get; set; }
}
public class ResponseData {
public Department dept {get; set; }
}
public class Department {
public string id {get; set; }
public string description {get; set; }
public int status {get; set; }
}
Теперь вы сможете правильно десериализовать JSON. Вот живое демо десериализации.
П.С. [
характер здесь не имеет значения … неясно, почему вы упомянули об этом в своем вопросе.
P.P.S. Глядя на ваш PHP, я догадываюсь, что вы, возможно, намереваетесь вернуть разные структуры данных в ResponseData в зависимости от того, какой параметр был указан для do_work
— в зависимости от того, какая функция PHP вызывается. Если это так, то вам нужно соответствующим образом изменить ваш C #, чтобы он десериализовался в другой конкретный класс в зависимости от того, какой метод API он запрашивает. Или вы могли бы обмануть и указать ResponseData
как dynamic
которая затем будет принимать любую полученную им структуру данных, хотя и с оговоркой, что теперь она эффективно печатается свободно, и поэтому вы теряете определенные преимущества при компиляции кода, такие как проверка правильности использования имен свойств, типов данных и т. д.
Других решений пока нет …