无法反序列化文本/html json 响应

问题描述

我正在集成到一个旧的 API 中,该 API 出于某种原因将 json 数据作为文本/html 响应返回。我曾尝试在 C# 中使用 Newtonsoft 反序列化这个字符串,并使用包括 JSON.parse() 在内的各种 javascript 库,但都失败了。

实际响应看起来像一个有效的 json 对象,但无法反序列化:

{"err":201,"errMsg":"We cannot find your account.\uff01","data":[],"selfChanged":{}}

我认为有一些特殊字符或者实际响应的格式是我的任何解析器都无法反序列化的。我附上了各种语言的各种代码示例,包括 curl。如果有人可以帮助反序列化 C# 中的响应对象或为我指明正确的方向,我将不胜感激。

C#

var client = new RestClient("http://47.89.182.211:8080/index.PHP/account/login");
client.Timeout = -1;
var request = new RestRequest(Method.POST);
request.AddHeader("Accept","application/json");
request.AddHeader("Content-Type","application/x-www-form-urlencoded");
request.AddParameter("appVersion","0");
request.AddParameter("password","xxxxxx");
request.AddParameter("platform","5");
request.AddParameter("platformId","[email protected]");
request.AddParameter("userType","4");
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);

Java

Unirest.setTimeouts(0,0);
HttpResponse<String> response = Unirest.post("http://47.89.182.211:8080/index.PHP/account/login")
  .header("Accept","application/json")
  .header("Content-Type","application/x-www-form-urlencoded")
  .field("appVersion","0")
  .field("password","xxxxxx")
  .field("platform","5")
  .field("platformId","[email protected]")
  .field("userType","4")
  .asstring();

Javascript

var data = "appVersion=0&password=xxxxxx&platform=5&platformId=xxx%40xxx.com&userType=4";

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange",function() {
  if(this.readyState === 4) {
    console.log(this.responseText);
  }
});

xhr.open("POST","http://47.89.182.211:8080/index.PHP/account/login");
xhr.setRequestHeader("Accept","application/json");
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");

xhr.send(data);

卷曲

curl --location --request POST 'http://47.89.182.211:8080/index.PHP/account/login' \
--header 'Accept: application/json' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'appVersion=0' \
--data-urlencode 'password=xxxxxx' \
--data-urlencode 'platform=5' \
--data-urlencode '[email protected]' \
--data-urlencode 'userType=4'

如果您能够将响应解析为有效的 json 对象或将其反序列化为 C# 或 Java 对象,请告诉我。

解决方法

这可以通过自定义 JsonMediaTypeFormatter(来自 NuGet 包 Microsoft.AspNet.WebApi.Client)在 C# 中完成,如下所示:

using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Get,"UrlToLoginPageHere");
using var response = await client.SendAsync(request);

var formatters = new[]
{
    new JsonMediaTypeFormatter
    {
        SupportedMediaTypes = { new MediaTypeHeaderValue("text/html") },},};
var result = await response.Content.ReadAsAsync<Rootobject>(formatters);

其中 Rootobject 是表示您的 JSON 模型的对象(例如,在 Visual Studio 中,选择“编辑”>“选择性粘贴”>“将 JSON 粘贴为类”)。

,

这个 c# 代码对我有用。我无法解释所遇到的空字符问题。如果是这种情况,我必须想象您正在使用的网站会给所有用户带来麻烦。无论如何,这里有一些东西可以尝试:

HttpClient hc = new HttpClient();
Dictionary<string,string> body = new Dictionary<string,string> { { "appversion","0" },{ "password","xxxxx" },{ "platform","5" },{ "platformId","xxx.xxx.com" },{"userType","4"}};
HttpRequestMessage msg = new HttpRequestMessage(HttpMethod.Post,"http://47.89.182.211:8080/index.php/account/login");
msg.Headers.Add("Accept","application/json");
FormUrlEncodedContent fuec = new FormUrlEncodedContent(body);
msg.Content = fuec;
var result = await hc.SendAsync(msg);
string response = await result.Content.ReadAsStringAsync();
Console.WriteLine(response[0]);
Console.WriteLine(response);
var obj = Newtonsoft.Json.Linq.JObject.Parse(response);
Console.WriteLine(obj["err"]);