Строка из Httpresponse не передает полное значение

Привет, я отчаянно нуждаюсь в помощи здесь,

Я делаю веб-запрос и получаю строку json с Response.ContentLenth=2246, но когда я анализирую ее в строке, она дает всего несколько 100 символов, я обнаружил, что она получает только значения меньше 964. длина строки по-прежнему 2246, но оставшиеся значения всего (\0) null символов. Это также дает ошибку Unterminated string passed in. (2246): в следующей строке

 FacebookFeed feed = sr.Deserialize<FacebookFeed>(data);

Он отлично работает, если поток ответов содержит символы менее 964 символов.

Ниже приведен отрывок из полной ошибки кода, обнаруженной в последней строке.

    System.Web.Script.Serialization.JavaScriptSerializer sr = new System.Web.Script.Serialization.JavaScriptSerializer();
    System.Net.HttpWebRequest req = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(@"https://graph.facebook.com/100000570310973_181080451920964");
    req.Method = "GET";
    System.Net.HttpWebResponse res = (System.Net.HttpWebResponse)req.GetResponse();

    byte[] resp = new byte[(int)res.ContentLength];
    res.GetResponseStream().Read(resp, 0, (int)res.ContentLength);
    string data = Encoding.UTF8.GetString(resp);
    FacebookFeed feed = sr.Deserialize<FacebookFeed>(data);

данная ошибка

Unterminated string passed in. (2246): {"id":"100000570310973_1810804519209........ (with rest of data in the string data including null chars)

Ниже приведена форма классов, используемых в моем коде:

public class FacebookFeed
{
    public string id { get; set; }
    public NameIdPair from { get; set; }
    public NameIdPair to { get; set; }
    public string message { get; set; }
    public Uri link{get;set;}
    public string name{get; set;}
    public string caption { get; set; }
    public Uri icon { get; set; }
    public NameLinkPair[] actions { get; set; }
    public string type { get; set; }
    public NameIdPair application { get; set; } //Mentioned in Graph API as attribution
    public DateTime created_time { get; set; }
    public DateTime updated_time { get; set; }
    public FacebookPostLikes likes { get; set; }
}

public class NameIdPair
{
    public string name { get; set; }
    public string id { get; set; }
}

public class NameLinkPair
{
    public string name { get; set; }
    public Uri link{get; set;}
}

public class FacebookPostLikes
{
    public NameIdPair[] data { get; set; }
    public int count { get; set; }
}

person Shekhar_Pro    schedule 27.12.2010    source источник


Ответы (4)


Вы предполагаете, что res.GetResponseStream().Read вернет весь ответ за один раз. На самом деле Stream.Read() возвращает количество прочитанных байтов — если это число меньше ожидаемого, вам нужно продолжать вызывать его до тех пор, пока не будут получены все фрагменты ответа. Вы можете увидеть это в примере по адресу http://msdn.microsoft.com/en-us/library/system.net.httpwebresponse.getresponsestream.aspx.

person MarkXA    schedule 27.12.2010

Причина, по которой вы получаете 0, заключается в том, что массив не полностью заполнен. Чтение не гарантирует возврат всех запрошенных байтов. Вызовите его в цикле:

var numreceived = 0;
while (numreceived < numwanted)
  numreceived += read(bytearray, numreceived, numwanted-numreceived);

Также добавьте некоторую проверку ошибок (если чтение возвращает ‹ 1, сгенерируйте исключение IOException).

person fejesjoco    schedule 27.12.2010

да, обдумав ваши ответы, я заставил это работать так;

    System.Web.Script.Serialization.JavaScriptSerializer sr = new System.Web.Script.Serialization.JavaScriptSerializer();
    System.Net.HttpWebRequest req = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(@"https://graph.facebook.com/100000570310973_181080451920964");
    req.Method = "GET";
    System.Net.HttpWebResponse res = (System.Net.HttpWebResponse)req.GetResponse();

    byte[] resp = new byte[(int)res.ContentLength];
    int bytestoread = 0;
    for (int i = 0; i < (int)res.ContentLength;)
    {
        bytestoread = (i + 64 < (int)res.ContentLength) ? 64 : 64 - ((i + 64) - (int)res.ContentLength);
        i += res.GetResponseStream().Read(resp, i, bytestoread);
    }
    string data = Encoding.UTF8.GetString(resp);
    FacebookFeed feed = sr.Deserialize<FacebookFeed>(data);
person Shekhar_Pro    schedule 27.12.2010

Решение предоставлено здесь:

http://msdn.microsoft.com/en-us/library/system.net.httpwebresponse.getresponsestream.aspx.

это самый простой способ.

Судя по опыту, это происходит только с большими фрагментами JSON и не всегда. Использование метода, представленного на предыдущей странице, действительно устраняет проблему, но это излишне, если ваши ответы JSON малы.

person Miguel Mateo    schedule 03.09.2012