由于原语无效,无法反序列化JSON字符串

时间:2013-12-07 07:26:07

标签: c# json https json.net httpwebresponse

我遇到了从HTTPS Web响应中反序列化JSON字符串的问题。每当我尝试这样做时,它都会返回以下错误:

Additional information: Invalid JSON primitive: .

(包括期间)

现在,因为我知道服务器正在发送一个有效的JSON字符串(Fiddler这样说)我相信字符串可能是通过HTTPS加密的,而且这反映了我的反序列化。如何修复此错误并正确反序列化json字符串:

JSON

我尝试使用.NET框架和Newtsoft的JSON.NET,如下面的代码所示。

        StringBuilder login = new StringBuilder();
        login.Append("json=%7B%22username%22%3A%22csharpautomaton%22%2C%22password%22%3A%22[redacted password]%22%2C%22remember%22%3A0%7D");
        byte[] logBytes = encoding.GetBytes(login.ToString());

        HttpWebRequest requirejs = (HttpWebRequest)WebRequest.Create(new Uri("https://www.textnow.com/api/sessions"));

        //requirejs.PreAuthenticate = true;
        requirejs.KeepAlive = true;
        requirejs.Method = "POST";
        requirejs.Accept = "Accept: application/json, text/javascript, */*; q=0.01";
        requirejs.Headers.Add("Accept-Encoding", "gzip,deflate,sdch");
        requirejs.Headers.Add("Accept-Language", "en-US,en;q=0.8");
        requirejs.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13";
        requirejs.ContentType = "application/x-www-form-urlencoded; charset=UTF-8";

        Stream sw = requirejs.GetRequestStream();
        sw.Write(logBytes, 0, logBytes.Length);
        sw.Close();
        response = (HttpWebResponse)requirejs.GetResponse();
        Stream stream = response.GetResponseStream();
        StreamReader sr = new StreamReader(stream,true);

        string line = sr.ReadLine();
        //the one I tried second
        TheObject id = JsonConvert.DeserializeObject<TheObject>(line);
        MessageBox.Show(id.ToString());

        //the one I tried first v
        System.Web.Script.Serialization.JavaScriptSerializer deserialize = new System.Web.Script.Serialization.JavaScriptSerializer();
        TheObject jsonObject = deserialize.Deserialize<TheObject>(sr.ReadToEnd());

//the object I used with just .NET
public class TheObject
{
    string id { get; set; } 
    string username { get; set; }
}
//the object I used with JSON.NET
public class TheObject
{
    [JsonProperty("id")]
    public string id { get; set; }

    [JsonProperty("username")]
    public string username { get; set; }
}

2 个答案:

答案 0 :(得分:1)

事实证明这也不起作用,但却是解决方案的一部分:

我们确定TextNow实际上需要将转义的JSON字符串传递给json=键,如下所示:

json={\"username\":\"csharpautomaton\",\"password\":\"[redacted password]\",\"remember\":0}

更多信息,虽然这不起作用:

TextNow要求username参数和password参数作为x-www-form-urlencoded内容(表单值对)传递。

您不能将完整的url编码的JSON字符串传递给它,您需要将JSON字符串解码为可用对象(您已经使用jsonObject执行此操作)然后传递这些参数。

最后,您需要具有以下内容:

StringBuilder login = new StringBuilder();
login.Append("username=csharpautomation&password=xxxxx");
byte[] logBytes = encoding.GetBytes(login.ToString());

既然你已经在你的类中实现了jsonObject(虽然使用id/username而不是username/password?),一旦你重建参数字符串应该不会有太大的挑战已经解码了JSON对象。

答案 1 :(得分:1)

事实证明,服务器正在发送压缩响应。所以,我最后需要做的就是删除"Accept-Encoding","gzip,deflate,sdch",但我也可以手动解压缩它,但这是一个更容易的选择。 @ r3mus感谢你的帮助,你很精彩,坦率地说,我很惊讶你花在帮助我的时间,我非常感谢!