C# 如何反序列化JSONP响应(最好使用JsonTextReader而不是字符串)?
我试图使用一个声称返回JSON但实际上总是返回JSONP的web服务。我看不出有什么办法可以改变该服务的行为 我想使用NewtonSoft Json.Net来解析结果。我已经声明了一个类,让我们称之为MyType,我想将内部JSON结果反序列化为该类 JSONP: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(前缀和)后缀。虽然这个
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
字符)。这将(
定位在实际JSON的开头StreamReader
- 在反序列化之前,我设置告诉序列化程序忽略JSON内容结尾后的任何字符。奇怪的是,尽管默认值似乎已经是
,但仍然需要显式地这样做,因为false
- 通过将
传递给StringReader
。这样做可以避免通过修剪前缀和后缀文本来创建新字符串,因此即使对于较小的字符串,也可以提高性能和内存使用DeserializeEmbeddedJsonP(TextReader),可以使用相同的代码从
反序列化嵌入式JSONP;string
示例工作。这样您就可以从返回值为null的情况下检测错误。您是在问如果发现返回值为null该怎么办?@Makketronix否。我是在问如何处理这种格式错误的JSON。为什么要这样做?所问的问题没有表明将响应作为字符串读取并使用
。Replace
对您无效所以其他看到这个问题的人都不会理解它与其他大量的“解析JSONP”有什么不同问题,以及这一条是否更符合他们的情况。再一次-你对文章的原始版本表现出强烈的依恋,因此我怀疑其他人是否愿意在你的评论中编辑它,以澄清你到底在看什么,以及为什么读字符串不是答案。@user6694745它没有格式错误,只是JSONP而不是JSON,停止批评那些试图帮助你的人。@user6694745如果你觉得这个问题不再反映你的需要和风格,另一个选择是请求与你的帐户解除关联-如果你想这样做,请在帖子上标出版主的注意事项,并解释这一点。我不是直接用字符串操作的。正则表达式不在流上使用单词。还有虽然我没有检查您的regualr表达式是否处理“parseResponse”。好的,首先转换为字符串?有什么问题吗?是的,正则表达式可以与任何JSONP一起工作。请注意问题,方法反序列化不接受字符串参数。是的,我明白了。:)为什么不能调用JsonConvert.DeserializeObject(someString)
哪一个接受字符串?如果您想直接从响应中获取流并将其放入JSON读取器,那么它将无法工作。您必须先处理它。@user6694745-“方法反序列化不接受字符串参数”-JsonSerializer.Deserialize
有一个重载,它需要一个TextReader
,它可以是StringReader
。我自己也找到了类似的解决方案,虽然有点笨拙。我在流中使用while循环来“跳过”(“.CheckAdditionalContent选项是另一件花了我一些时间的事情。你的回答会节省我很多时间。你的