Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/google-chrome/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何反序列化JSONP响应(最好使用JsonTextReader而不是字符串)?_C#_Json_Json.net_Jsonp - Fatal编程技术网

C# 如何反序列化JSONP响应(最好使用JsonTextReader而不是字符串)?

C# 如何反序列化JSONP响应(最好使用JsonTextReader而不是字符串)?,c#,json,json.net,jsonp,C#,Json,Json.net,Jsonp,我试图使用一个声称返回JSON但实际上总是返回JSONP的web服务。我看不出有什么办法可以改变该服务的行为 我想使用NewtonSoft Json.Net来解析结果。我已经声明了一个类,让我们称之为MyType,我想将内部JSON结果反序列化为该类 JSONP: parseResponse({ "total" : "13,769", "lower" : "1", "upper" : "20"}) 正如您所看到的,这不是正确的JSON,因为它有parseResponse(前缀和)后缀。虽然这个

我试图使用一个声称返回JSON但实际上总是返回JSONP的web服务。我看不出有什么办法可以改变该服务的行为

我想使用NewtonSoft Json.Net来解析结果。我已经声明了一个类,让我们称之为MyType,我想将内部JSON结果反序列化为该类

JSONP:

parseResponse({
"total" : "13,769",
"lower" : "1",
"upper" : "20"})
正如您所看到的,这不是正确的JSON,因为它有
parseResponse(
前缀和
后缀。虽然这个示例非常简单,但实际响应可能相当长,大约为100k

MyType:

public class MyType
{
    public Decimal total;
    public int lower;
    public int upper;
}
在将web服务响应放入流和JsonTextReader后,我尝试如下反序列化:

(MyType)serializer.Deserialize(jsonTextReader, typeof(MyType));
当然,对于一个结果,我会得到null,因为有一个用圆括号括起来的讨厌的parseResponse


我已经看了一眼,但不幸的是这没有帮助。实际上,我使用了一个
JsonTextReader
来输入JSON,而不是一个字符串(为了避免创建一个巨大的字符串对性能的影响,我更愿意这样做)。即使我使用这个问题的建议,它看起来也很危险,因为它使用了全局替换。如果没有使用流的好方法,那么对字符串进行安全解析的答案就可以了。

看起来它正在返回。有点奇怪,Web服务在默认情况下会这样做,而不包括“回调”。在任何情况下,如果是这样的话,您都可以轻松地使用正则表达式剥离方法调用:

var x = WebServiceCall();
x = Regex.Replace(x, @"^.+?\(|\)$", "");

如果我将你的问题解释如下:

我正在尝试从
反序列化一些JSON。“JSON”实际上是JSONP格式的,因此包含一些我想忽略的前缀和后缀文本。如何跳过前缀和后缀文本,同时仍然直接从流中读取和反序列化,而不是将整个流加载到字符串中

然后,可以使用以下扩展方法从JSONP流反序列化JSON:

public static class JsonExtensions
{
    public static T DeserializeEmbeddedJsonP<T>(Stream stream)
    {
        using (var textReader = new StreamReader(stream))
            return DeserializeEmbeddedJsonP<T>(textReader);
    }

    public static T DeserializeEmbeddedJsonP<T>(TextReader textReader)
    {
        using (var jsonReader = new JsonTextReader(textReader.SkipPast('(')))
        {
            var settings = new JsonSerializerSettings
            {
                CheckAdditionalContent = false,
            };
            return JsonSerializer.CreateDefault(settings).Deserialize<T>(jsonReader);
        }
    }
}

public static class TextReaderExtensions
{
    public static TTextReader SkipPast<TTextReader>(this TTextReader reader, char ch) where TTextReader : TextReader
    {
        while (true)
        {
            var c = reader.Read();
            if (c == -1 || c == ch)
                return reader;
        }
    }
}
公共静态类JsonExtensions
{
公共静态T反序列化EmbeddedJSONP(流)
{
使用(var textReader=newstreamreader(stream))
返回反序列化EmbeddedJSONP(textReader);
}
公共静态T反序列化EmbeddedJSONP(文本阅读器文本阅读器)
{
使用(var jsonReader=newjsontextreader(textReader.SkipPast(“(”))
{
var设置=新的JsonSerializerSettings
{
CheckAdditionalContent=false,
};
返回JsonSerializer.CreateDefault(设置)。反序列化(jsonReader);
}
}
}
公共静态类TextReaderExtensions
{
公共静态TTextReader SkipPast(此TTextReader,char ch),其中TTextReader:TextReader
{
while(true)
{
var c=reader.Read();
如果(c==-1 | | c==ch)
返回读取器;
}
}
}
注:

  • 在构造
    JsonTextReader
    之前,我构造了一个
    StreamReader
    并跳过流中的第一个
    字符)。这将
    StreamReader
    定位在实际JSON的开头

  • 在反序列化之前,我设置告诉序列化程序忽略JSON内容结尾后的任何字符。奇怪的是,尽管默认值似乎已经是
    false
    ,但仍然需要显式地这样做,因为

  • 通过将
    StringReader
    传递给
    DeserializeEmbeddedJsonP(TextReader),可以使用相同的代码从
    string
    反序列化嵌入式JSONP;
    。这样做可以避免通过修剪前缀和后缀文本来创建新字符串,因此即使对于较小的字符串,也可以提高性能和内存使用


示例工作。

这样您就可以从返回值为null的情况下检测错误。您是在问如果发现返回值为null该怎么办?@Makketronix否。我是在问如何处理这种格式错误的JSON。为什么要这样做?所问的问题没有表明将响应作为字符串读取并使用
。Replace
对您无效所以其他看到这个问题的人都不会理解它与其他大量的“解析JSONP”有什么不同问题,以及这一条是否更符合他们的情况。再一次-你对文章的原始版本表现出强烈的依恋,因此我怀疑其他人是否愿意在你的评论中编辑它,以澄清你到底在看什么,以及为什么读字符串不是答案。@user6694745它没有格式错误,只是JSONP而不是JSON,停止批评那些试图帮助你的人。@user6694745如果你觉得这个问题不再反映你的需要和风格,另一个选择是请求与你的帐户解除关联-如果你想这样做,请在帖子上标出版主的注意事项,并解释这一点。我不是直接用字符串操作的。正则表达式不在流上使用单词。还有虽然我没有检查您的regualr表达式是否处理“parseResponse”。好的,首先转换为字符串?有什么问题吗?是的,正则表达式可以与任何JSONP一起工作。请注意问题,方法反序列化不接受字符串参数。是的,我明白了。:)为什么不能调用
JsonConvert.DeserializeObject(someString)
哪一个接受字符串?如果您想直接从响应中获取流并将其放入JSON读取器,那么它将无法工作。您必须先处理它。@user6694745-“方法反序列化不接受字符串参数”-
JsonSerializer.Deserialize
有一个重载,它需要一个
TextReader
,它可以是
StringReader
。我自己也找到了类似的解决方案,虽然有点笨拙。我在流中使用while循环来“跳过”(“.CheckAdditionalContent选项是另一件花了我一些时间的事情。你的回答会节省我很多时间。你的