Zero
Zero

Reputation: 57

Newtonsoft.Json.JsonReaderException: 'Unexpected character encountered while parsing value: [.

I'm doing C# JSON <-> PHP JSON for the first time. Thought I'd get on an easy road but seems like I've hit the rock.

I'm fairly sure that JSON from Newtonsoft allows "[" character but not sure why i have this error instead?

Here's my C# code:

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

And here's my PHP code:

<?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

}

?>

And here's my error:

Newtonsoft.Json.JsonReaderException HResult=0x80131500
Message=Unexpected character encountered while parsing value: {. Path 'ResponseData', line 1, position 51.

Upvotes: 0

Views: 16186

Answers (1)

ADyson
ADyson

Reputation: 61984

The problem is that your C# SystemJSON class does not match the structure of the incoming JSON correctly.

ResponseData in your C# SystemJSON class is listed as a string but your PHP appears to be pushing out a complex object inside that property. You can't deserialise an object into a string - there is no way for the deserialiser to know how to translate the object structure into a suitable string, and anyway it's not generally a useful or logical thing to do. So instead it throws an error to say the object structure doesn't match.

The specific error you're seeing means the deserialiser is expecting a " to denote the start of a string but instead it's seeing { denoting the start of another object.


Why is this happening? Well, your PHP code will produce a JSON response which looks like this:

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

Live demo here

As you can see, ResponseData contains an object, which has a "dept" which in turn is another object with four more properties.

To deserialise this properly, your SystemJSON class will need to be altered, and you'll also need two sub-classes to help it out:

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

You will now be able to deserialise the JSON correctly. Here is a live demo of the deserialisation.


P.S the [ character appears to be irrelevant here...it's unclear why you referred to that in your question.


P.P.S. From looking at your PHP I'm guessing that you may be intending to return different data structures in ResponseData depending on which parameter was specified for do_work - i.e. depending on which PHP function is called. If so then you'll need to amend your C# accordingly so that it deserialises to a different concrete class depending on which API method it requests. Or you could possibly cheat and specify ResponseData as dynamic, which will then accept any data structure it received, albeit with the caveat that it's now effectively loosely-typed and so you lose certain benefits when compiling the code such as checking for valid usage of property names, data types etc.

Upvotes: 4

Related Questions