WCF 3.5 Проблема (CustomBinding назначается вместо WebHttpBinding, когда параметр является потоком)

В моем контракте на обслуживание я предоставляю метод, который принимает Stream в качестве параметра:

[OperationContract]
[WebInvoke(UriTemplate = "/Upload?fileName={fileName}", Method = "POST", BodyStyle = WebMessageBodyStyle.Bare, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
Stream Upload(String fileName, Stream fileData);

когда я делаю это, моя пользовательская реализация WebServiceHost (которая создается из пользовательской реализации WebServiceHostFactory) видит привязку конечной точки как CustomBinding, а не WebHttpBinding:

public class myWebServiceHost : WebServiceHost {
  .
  .
  .
  protected override void OnOpening() {
    base.OnOpening();
    if (base.Description != null) {
      foreach (ServiceEndpoint endpoint in base.Description.Endpoints) {
        WebHttpBinding binding = endpoint.Binding as WebHttpBinding;
        if (binding != null) { //Will always be null given the operation contract above
          Int32 MB = 1048576 * Convert.ToInt32(ConfigurationManager.AppSettings["requestSizeMax"]);
          binding.MaxReceivedMessageSize = MB;
          binding.TransferMode = TransferMode.Streamed;
        }
      }
    }
  }
}

Это проблема, потому что мне нужно загружать файлы размером более 64 КБ... любые идеи о том, как мне поступить с настройкой MaxReceivedMessageSize для CustomBinding или как убедиться, что для моего Binding установлено значение WebHttpBinding.

PS Мне нужно сделать это программно, поэтому настройки.config не будут мне полезны.

1 ответ

Решение

Ладно, после того, как долго и усердно копали этот, вот что я придумал:

protected override void OnOpening() {
  base.OnOpening();
  if (base.Description != null) {
    foreach (ServiceEndpoint endpoint in base.Description.Endpoints) {
      Int32 MB = 1048576 * Convert.ToInt32(ConfigurationManager.AppSettings["requestSizeMax"]);
      switch(endpoint.Binding.GetType().ToString()) {
        case "System.ServiceModel.Channels.CustomBinding":
          CustomBinding custom = (CustomBinding)endpoint.Binding;
          custom.Elements.Find<HttpTransportBindingElement>().MaxReceivedMessageSize = MB;
          custom.Elements.Find<HttpTransportBindingElement>().TransferMode = TransferMode.Streamed;
        break;
        case "System.ServiceModel.WebHttpBinding":
          WebHttpBinding webhttp = (WebHttpBinding)endpoint.Binding;
          webhttp.MaxReceivedMessageSize = MB;
          webhttp.TransferMode = TransferMode.Streamed;
        break;
      }
    }
  }
}

Это работает, хотя это определенно можно улучшить. Мне все еще нужно посмотреть, есть ли более общий способ обработки этого, а не разделять случаи по типам. Хотя в настоящий момент я не вижу другого способа сделать это (поскольку тип привязки основан на методах в самой службе, помните, что он переключился с WebHttpBinding на CustomBinding только тогда, когда я добавил параметр Stream в один из методов службы).

  • Если у кого-то есть какие-либо другие идеи по этой теме, пожалуйста, напишите.
Другие вопросы по тегам