C#解析可能有简单类型的json

时间:2017-10-02 21:30:25

标签: c# json json.net

从C#I调用返回JSON的RESTful Web服务。该服务可以返回任意Javascript对象,我们在编译时不知道它的结构。

通常,它返回一个JSON对象,但有些情况下会返回一个简单的字符串。当我尝试反序列化简单字符串时,JSON.Net会抛出运行时错误。

dynamic dyn = JsonConvert.DeserializeObject("just a string");            

抛出:

Newtonsoft.Json.JsonReaderException was unhandled by user code
  HResult=-2146233088
  Message=Unexpected character encountered while parsing value: j. Path '', line 0, position 0.

我读了答案 Is this simple string considered valid JSON?并且共识似乎是返回一个简单的字符串作为JSON是合法的,但许多实现还没有支持这一点。

这适用于JSON.NET吗?处理可能包含简单类型而不仅仅是对象和数组的JSON的反序列化有哪些变通方法?

这似乎工作正常,我错过了什么?

dynamic dyn;

dyn = GetObjectFromJSON("{ \"name\": \"john\", \"age\": 32 }");
Debug.WriteLine((string)Convert.ToString(dyn));

dyn = GetObjectFromJSON("[ \"a\", \"b\", \"c\" ]");
Debug.WriteLine((string)Convert.ToString(dyn));

dyn = GetObjectFromJSON("just a string");
Debug.WriteLine((string)Convert.ToString(dyn));

dyn = GetObjectFromJSON("35");
Debug.WriteLine((string)Convert.ToString(dyn));

dyn = GetObjectFromJSON("true");
Debug.WriteLine((string)Convert.ToString(dyn));

dyn = GetObjectFromJSON(null);
Debug.WriteLine((Object)dyn ?? "(null)");

private Object GetObjectFromJSON(string jsonString)
{
    if (String.IsNullOrEmpty(jsonString))
    {
        return null;
    }

    dynamic jsonResponse;
    jsonString = jsonString.Trim();
    if (jsonString.StartsWith("{") || jsonString.StartsWith("["))
    {
        // object or array
        jsonResponse = JsonConvert.DeserializeObject(jsonString);
    }
    else
    {
        // some literal value
        double d;
        bool b;
        if (Double.TryParse(jsonString, out d))
        {
            return d;
        }
        else if (bool.TryParse(jsonString, out b))
        {
            return b;
        }
        else
        {
            // not null, not an object, not an array, not a number, and not  a boolean, so it's a string
            jsonResponse = jsonString;
        }
    }
    return jsonResponse;
}

2 个答案:

答案 0 :(得分:0)

@afuzzyllama让我直截了当地评论(如果他发布了答案,我会高兴地接受它!)。

dynamic dyn = JsonConvert.DeserializeObject("just a string");           

失败,因为该字符串无效JSON。字符串必须引用,所以要正确,这应该是:

dynamic dyn = JsonConvert.DeserializeObject("\"just a string\"");           

有关详细信息,请参阅http://www.json.org/

但是,这显然是JAX-RS / Jersey Web服务接受简单字符串的接受(以及设计行为)。见https://stackoverflow.com/a/46535680/90236

答案 1 :(得分:0)

查看以下电话:

\d{5}

这不是反序列化$它是反序列化dynamic dyn = JsonConvert.DeserializeObject("just a string"); (注意字符串被"just a string"包围)。

如果我们查看spec for JSON,那么just a string不受""限制的唯一有效字母序列就是""truefalse

如果我们想要反序列化字符串,我们需要确保它是规范定义的有效字符串。这应该是一个有效的反序列化调用:

null

查看上一个问题Java Jersey JSON service doesn't return quoted string?,我发现您正在返回dynamic dyn = JsonConvert.DeserializeObject("\"just a string\""); 类型:

Object

我对Jersey没有任何经验,但也许框架在解释通用@GET @Produces(MediaType.APPLICATION_JSON) public Object interpretationJson() { String o = "a simple string"; return o; } 时遇到了麻烦。也许如果您使用Object返回类型,结果会有所不同?从该问题的接受答案看来似乎并非如此?

也许像以下这样的解决方案,添加String并更改返回类型,是否合适?

""

结果应该可以反序列化。