Как я могу декодировать gzip в клиенте DataServiceContext WCF Data Services? - PullRequest
1 голос
/ 15 марта 2012

У нас есть поставщик услуг передачи данных, который предоставляет нам динамическое сжатие на сайте служб данных WCF.Нам нужно использовать это сжатие, потому что исходные данные, которые мы извлекаем, составляют более 5 Гб в день.Использование gzip резко упадет.

У нас есть клиентское приложение, которое было создано с помощью мастера «Добавить ссылку на службу» в Visual Studio 2010 на основе класса DataServiceContext.Я могу указать заголовок Accept: gzip, deflate, используя событие SendingRequest, но как я могу заставить десериализатор декодировать поток, прежде чем он попытается проанализировать XML?

Ответы [ 2 ]

1 голос
/ 01 августа 2012

Там же, где вы указали в SendingRequest, что хотите получать сжатые данные, просто добавьте следующее:

    e.RequestHeaders.Add("Accept-Encoding","gzip, deflate");
    ((System.Net.HttpWebRequest)e.Request).AutomaticDecompression = 
        (System.Net.DecompressionMethods.GZip | 
           System.Net.DecompressionMethods.Deflate);

Ссылка: http://social.msdn.microsoft.com/Forums/en/adodotnetdataservices/thread/65127110-1213-45fa-a2ef-8bbd069d1294

0 голосов
/ 19 марта 2012

Я не мог понять, как это сделать с помощью предоставленных инструментов инфраструктуры, поэтому мне пришлось свернуть свои собственные.Во-первых, это метод, который выполняет фактический запрос, который показывает, как указать заголовок, который запрашивает кодировку gzip и распаковывает результат.

  private static IEnumerable<dynamic> MakeHttpQuery(string uri)
  {
     var request = (HttpWebRequest)WebRequest.Create(new Uri(uri));
     request.Method = "GET";
     request.Accept = "application/json";
     request.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip");

     try
     {
        var response = request.GetResponse();
        var contentEncoding = response.Headers[HttpResponseHeader.ContentEncoding];
        var responseStream = response.GetResponseStream();

        if (!string.IsNullOrEmpty(contentEncoding) && contentEncoding.Equals("gzip"))
        {
           responseStream = new GZipStream(responseStream, CompressionMode.Decompress);
        }

        var json = JsonObject.Parse(responseStream);
        var d = json["d"];
        if (!d.IsArray) return new JsonArray(new[] {d}).Values;
        else return ((JsonArray) d).Values;
     }
     catch (WebException webException)
     {
        log4net.LogManager.GetLogger(typeof(ProfileMediaDataInterface)).Error(webException);
        return new JsonArray(new JsonValue[] {}).Values;
     }
  }

Библиотека DynamicJson - это библиотека с открытым исходным кодом, которую я недавно написал и которая очень пригодилась здесь.Вы можете очень легко пропустить заголовок Accept: application/json, и тогда вы получите обратно XML.В этом случае что-то вроде linq-to-xml также будет работать, почти таким же образом.

Далее код клиента.Здесь показано, как создать URL-адрес для передачи методу MakeHttpQuery, а также что делать с результатом.

  public static List<BenchmarkListSqr> GetBenchmarkListSqr(string currencyCode)
  {
     return 
        MakeHttpQuery(
           CreateDataService()
           .BenchmarkList
           .Where(bm => bm.Currency == currencyCode)
           .ToString())
        .Select(x => new BenchmarkListSqr(
           x.Currency, 
           x.AssetClass, 
           ToNullDateTime(x.AvailableFromDate), 
           x.ID, 
           ToNullDateTime(x.InceptionDate), 
           x.Name, 
           x.Region, 
           ToNullDecimal(x.ShareID)))
        .ToList();
  }
...