RestSharp RestResponse is truncating content to 64

2019-02-20 16:40发布

Hi I am using the RestSharp to create the request to my web API. Unfortunately the response.content does not contain full response, which I am able to see when I perform request through browser or fiddler. The content is being truncated to 64 kb. I am attaching my code below.

Could you please advice what could solve this issue?

var request = new RestRequest("Products?productId={productId}&applicationId={applicationId}", Method.GET);
request.RequestFormat = DataFormat.Json;
request.AddParameter("productId", id, ParameterType.UrlSegment);
request.AddParameter("applicationId", Settings.ApplicationId, ParameterType.UrlSegment);
request.AddHeader("X-AppKey", token.AppKey);
request.AddHeader("X-Token", token.Token);
request.AddHeader("X-IsWebApi", "true");

RestResponse response = (RestResponse) client.Execute(request);

if (response.StatusCode == HttpStatusCode.Found)
{
    // The following line failes because response.Content is truncated.
    ShowProductModel showProductModel =
        new JavaScriptSerializer().Deserialize<ShowProductModel>(response.Content);

   // Do other things.
   return ShowProductApi(showProductModel, q, d, sort, breadcrumb);
}

2条回答
虎瘦雄心在
2楼-- · 2019-02-20 16:58

It looks like HttpStatusCode.Found may be causing the issue. That equates to Http Status Code 302 which is a form of redirect. I'm not entirely sure if that's necessarily the right thing to do in this case. If you have "found" the data you are looking for you should return a success level status code, e.g. 200 (Ok). Wikipedia has a list of HTTP Status Codes with summaries about what they mean and links off to lots of other resources.

I've created a little demonstrator solution (You can find it on GitHub) to show the difference. There is a WebApi server application that returns a list of values (Hex codes) and a Console client application that consumes the resources on the WebApi application.

Here is the ValuesFound resource which returns HTTP Status Code 302/Found:

public class ValuesFoundController : ApiController
{
    public HttpResponseMessage Get(int count)
    {
        var result = Request.CreateResponse(HttpStatusCode.Found, Values.GetValues(count));
        return result;
    }
}

And the same again but returning the correct 200/OK response:

public class ValuesOkController : ApiController
{
    public HttpResponseMessage Get(int count)
    {
        var result = Request.CreateResponse(HttpStatusCode.OK, Values.GetValues(count));
        return result;
    }
}

On the client side the important part of the code is this:

private static void ProcessRequest(int count, string resource)
{
    var client = new RestClient("http://localhost:61038/api/");
    var request = new RestRequest(resource+"?count={count}", Method.GET);
    request.RequestFormat = DataFormat.Json;
    request.AddParameter("count", count, ParameterType.UrlSegment);
    RestResponse response = (RestResponse) client.Execute(request);
    Console.WriteLine("Status was                : {0}", response.StatusCode);
    Console.WriteLine("Status code was           : {0}", (int) response.StatusCode);
    Console.WriteLine("Response.ContentLength is : {0}", response.ContentLength);
    Console.WriteLine("Response.Content.Length is: {0}", response.Content.Length);
    Console.WriteLine();
}

The count is the number of hex codes to return, and resource is the name of the resource (either ValuesOk or ValuesFound) which map to the controllers above.

The console application asks the user for a number and then shows the length of response for each HTTP Status Code. For low values, say 200, both versions return the same amount of content, but once the response content exceeds 64kb then the "Found" version gets truncated and the "Ok" version does not.

Trying the console application with a value of about 9999 demonstrates this:

How many things do you want returned?
9999
Waiting on the server...
Status was                : OK
Status code was           : 200
Response.ContentLength is : 109990
Response.Content.Length is: 109990

Status was                : Redirect
Status code was           : 302
Response.ContentLength is : 109990
Response.Content.Length is: 65536

So, why does RestSharp do this? I've no idea why it truncates content in one instance and not in the other. However, it could be assumed that in a situation where the server has asked the client to redirect to another resource location that content exceeding 64kb is unlikely to be valid.

For example, if you use Fiddler to look at what websites do, the responses in the 300 range (Redirection) such as 302/Found do have a small content payload that simply contain a little HTML so that the user can click the link to manually redirect if the browser did not automatically redirect for them. The real redirect is in the Http "Location" header.

查看更多
欢心
3楼-- · 2019-02-20 17:07

This is happening because RestSharp uses the HttpWebRequest class from the .NET Framework. This class has a static attribute called DefaultMaximumErrorResponseLength. This attribute determines the max length of an error response, and the default value for this attribute is 64Kb.

You can change the value of that atribbute before instatiating the RestRequest class.

Here's some code:

 HttpWebRequest.DefaultMaximumErrorResponseLength = 1048576;

 var request = new RestRequest("resource" + "/", Method.POST)
    {
        RequestFormat = DataFormat.Json,
        JsonSerializer = new JsonSerializer()
    };

That way your error response can be longer without problemns.

查看更多
登录 后发表回答