Newtonsoft.Json.JsonReaderException:'解析值时遇到意外字符:[。

时间:2018-11-07 09:34:24

标签: c# php json http json.net

我是第一次使用C#JSON <-> PHP JSON。 以为我会走上一条轻松的道路,但好像我已经跌跌撞撞。

我相当确定Newtonsoft的JSON允许使用“ [”字符,但不确定为什么我会出现此错误?

这是我的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。

1 个答案:

答案 0 :(得分:0)

问题是您的C#SystemJSON类与传入JSON的结构不正确匹配。

C#SystemJSON类中的

ResponseData被列为string,但是您的PHP似乎在该属性内推出了一个复杂的对象。您不能将对象反序列化为字符串-反序列化器无法知道如何将对象结构转换为合适的字符串,而且总的来说这不是一件有用或合乎逻辑的事情。因此,它抛出一个错误以说对象结构不匹配。

您看到的特定错误意味着反序列化程序期望"表示字符串的开头,但是却看到{表示另一个对象的开头。


为什么会这样?好了,您的PHP代码将产生一个如下所示的JSON响应:

{
    "Status": true,
    "Message": "SUCCESS",
    "ResponseData": {
        "dept": {
            "id": 2,
            "name": "Test",
            "description": "Testing",
            "status": 1
        }
    }
}

Live demo here

如您所见,ResponseData包含一个对象,该对象具有一个“部门”,而“部门”又是另一个具有四个属性的对象。

要正确地反序列化,需要更改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。这是live demo的反序列化。


P.S [字符在这里似乎无关紧要...不清楚您为什么在问题中提到该字符。


P.P.S。通过查看您的PHP,我猜测您可能打算在ResponseData中返回不同的数据结构,具体取决于为do_work指定了哪个参数-即取决于调用了哪个PHP函数。如果是这样,那么您将需要相应地修改C#,以便根据其请求的API方法将其反序列化为其他具体类。或者,您可能会作弊并将ResponseData指定为dynamic,这将接受它收到的任何数据结构,尽管要注意的是,它现在已经有效地进行了松散类型化,因此在编译代码时会失去某些好处例如检查属性名称,数据类型等的有效用法。