2013-05-03 11 views
5

Korzystamy z interfejsu Web API w celu świadczenia usługi RESTful dla naszej aplikacji, która w tej chwili korzysta z WPF i dlatego wymaga klienta usługi.Strumień odpowiedzi HttpWebRequest zwraca tylko 64 tys. Danych.

Problem polega na tym, że gdy rozmiar odpowiedzi przekracza 64 tys., Strumień bazowy zatrzymuje się przy 64 tys. I generuje wyjątek, jeśli zażądano więcej danych, mimo że długość treści jest większa (w przypadku testowym ~ 125k)

Oto nasza metoda, która wywołuje usługę:

private HttpWebResponse CallServiceMethod<TDto>(Uri serviceURL, string method, out WebException requestExceptionDetail, TDto dto = null) where TDto : DTOBase 
{ 
    HttpWebRequest request; 
    HttpWebResponse response; 
    Encoding enc; 
    string encodedDto; 
    byte[] encodedDtoArray; 
    Stream writeStream; 

    request = WebRequest.CreateHttp(serviceURL); 
    request.Method = method; 

    if (dto != null) 
    { 
    enc = UTF8Encoding.Default; 
    encodedDto = String.Concat("=", JsonConvert.SerializeObject(dto)); 
    encodedDtoArray = enc.GetBytes(encodedDto); 

    request.ContentLength = encodedDtoArray.Length; 
    request.ContentType = "application/x-www-form-urlencoded"; 

    writeStream = request.GetRequestStream(); 
    writeStream.Write(encodedDtoArray, 0, encodedDtoArray.Length); 
    writeStream.Close(); 
    } 

    requestExceptionDetail = null; 

    try 
    { 
    response = (HttpWebResponse)request.GetResponse(); 
    } 
    catch (WebException wex) 
    { 
    response = (HttpWebResponse)wex.Response; 
    requestExceptionDetail = wex; 
    } 

    return response; 
} 

... i tu jest to metoda, która dekoduje odpowiedzi, z pewnej logiki kleju pomiędzy która przechodzi przez reakcję.

private TObjectType DecodeResponse<TObjectType>(HttpWebResponse webResponse) 
{ 
    Encoding enc; 
    StreamReader responseReader; 
    string responseText; 
    TObjectType retVal; 

    // Obtain a string from the underlying response string 
    enc = UTF8Encoding.Default; 
    responseReader = new StreamReader(webResponse.GetResponseStream(), enc); 
    responseText = responseReader.ReadToEnd(); 

    // Use JSon to deserialise the string 
    retVal = JsonConvert.DeserializeObject<TObjectType>(responseText); 

    return retVal; 
} 

Mamy również próbował tego typu rzeczy, ale bezskutecznie:

private TObjectType DecodeResponse<TObjectType>(HttpWebResponse webResponse) 
{ 
    Encoding enc; 
    StreamReader responseReader; 
    string responseText; 
    TObjectType retVal; 
    char[] buffer; 
    int bufferSize, startPos, totalLength, readLength; 
    StringBuilder sbx; 

    // Obtain a string from the underlying response string 
    enc = UTF8Encoding.Default; 
    responseReader = new StreamReader(webResponse.GetResponseStream(), enc); 

    totalLength = (int)webResponse.ContentLength; 
    bufferSize = 65536; 
    startPos = 0; 
    buffer = new char[bufferSize]; 

    sbx = new StringBuilder(totalLength); 
    //webResponse.GetResponseStream(). 

    while (startPos < totalLength) 
    { 
    readLength = Math.Min(bufferSize, totalLength - startPos); 
    responseReader.Read(buffer, startPos, readLength); 
    sbx.Append(buffer, 0, readLength); 

    startPos += readLength; 
    } 

    //responseText = responseReader.ReadToEnd(); 
    responseText = sbx.ToString(); 

    // Use JSon to deserialise the string 
    retVal = JsonConvert.DeserializeObject<TObjectType>(responseText); 

    return retVal; 
} 

Każda pomoc będzie mile widziane ;-)

+0

Twój ostateczny kod jest podzielona na początek - to * * zakłada, że ​​'Read' zawsze brzmi jak wiele znaków to jest pytanie. Nie zakładaj tego. –

+0

Tak, dziękuję - to był po prostu kod napisałem, aby spróbować i zdiagnozować, gdzie wystąpił problem. Widzę, że HttpWebResponse kończy się niepowodzeniem przy 64k, mimo że jest o wiele więcej dostępnych danych (FireFox i IE zwracają pełny zestaw danych). –

Odpowiedz

7

Dalsze badania wykazały, że HttpWebRequest ma właściwość statyczną o nazwie DefaultMaximumErrorResponseLength, która jest domyślnie ustawiona na 65536.

Spiskowałoby, że struktura .NET zawiera tę diabelską prope rty, który działa tak długo, jak twoja odpowiedź jest tekstowa/zwykła, ale jeśli wymaga jakiegoś zamknięcia - takiego jak XML lub JSON - to zepsuje się.

Dla każdego, kto potrzebuje więcej informacji, patrz:

Powiązane problemy