Question

In my service contract I am exposing a method that takes Stream as a parameter:

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

when I do this my custom WebServiceHost implementation (which is instantiated from a custom WebServiceHostFactory implementation) is seeing the endpoint binding as being CustomBinding and not 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;
        }
      }
    }
  }
}

This is an issue because I need to upload files larger than 64KB... any ideas on how I would go about setting MaxReceivedMessageSize for a CustomBinding or how to insure my Binding gets set to a WebHttpBinding.

P.S. I need to do this programmatically, so .config settings won't be of any use to me.

Was it helpful?

Solution

Okay so after digging long and hard on this one, this is what I came up with:

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

It works, though it can definitely be improved upon. I still need to see if there is a more generic way of handling this, rather than separating the cases by type. Though at the moment I don't see any other way to do it (since the type of binding is based on methods in the service itself, remember it only switched from WebHttpBinding to CustomBinding when I added a Stream parameter to one of the service methods).

  • If anyone has any other insight on this topic, please post.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top