开发者

String from Httpresponse not passing full value

HI i am in desperate need for help here,

I am making a web request and getting a json string with Response.ContentLenth=2246 but when i parse it in a string it gives only few 100 characters, i traked it down that it is only getting values less than 964. strings length is still 2246 but remaining values are just (\0) null characters. Its also giving an error Unterminated string passed in. (2246): at following line

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

It works fine if the response stream contains characters less than 964 chars.

Following is the extract from the full code error encountered in last line.

    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);

error given is

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

following is the shape of classes used in my code:

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 li开发者_如何学Pythonnk{get; set;}
}

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


You're assuming that res.GetResponseStream().Read will return the whole response in one go. In fact, Stream.Read() returns the number of bytes that were read - if this is less than the number you're expecting, you need to keep calling it until all the response chunks have been fetched. You can see this in the example at http://msdn.microsoft.com/en-us/library/system.net.httpwebresponse.getresponsestream.aspx.


The reason you're getting 0's is because the array is not completely filled. A read does not guarantee to return all bytes that you requested. Call it in a loop:

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

Also put in some error checking (if read returns < 1, throw an IOException).


yup, after considering your answers i got it working it like this;

    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);


The solution provided here:

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

is by far the simplest way.

Based on experience, this happens only in large chunks of JSON, and not necessarily always. Using the method provided in the previous page does fix the issue but it is an overkill if your JSON responses are small.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜