none
Unable to get the data for POST API of WCF serivce hosted on Service Bus WCF relay

    Question

  • Hi Everyone,

    I'm working a lot to implement POST API on WCF service hosted on WCF service. when I call the POST API, the data at service side is always null. please find the below code snippet which I have been trying.

    WCF Service.

    <services>
          <service name="ServiceBusWCFIISApp.ProblemSolver">
          
            <endpoint name="RelayBinding" 
                      address="https://mynamespace.servicebus.windows.net/relayname" 
                      binding="webHttpRelayBinding"
                      bindingConfiguration="contosoServiceConfiguration" 
                      contract="ServiceBusWCFIISApp.IProblemSolver" 
                      behaviorConfiguration="sbTokenProvider"/>
    
    <bindings>
          <webHttpRelayBinding>
            <binding name="contosoServiceConfiguration">
              <!--<security relayClientAuthenticationType="None" />-->
              <security relayClientAuthenticationType="RelayAccessToken"/>
            </binding>
          </webHttpRelayBinding>
             </bindings>
        <behaviors>
          <serviceBehaviors>
            <behavior>
              <!-- To avoid disclosing metadata information, set the values below to false before deployment -->
              <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
              <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
              <serviceDebug includeExceptionDetailInFaults="true"/>
            </behavior>
          </serviceBehaviors>
          <endpointBehaviors>
            <behavior>
              <webHttp helpEnabled="true"/>
            </behavior>
            <behavior name="sbTokenProvider">
              <webHttp/>
              <serviceRegistrySettings discoveryMode="Public" displayName="Service"/>
              <transportClientEndpointBehavior>
                <tokenProvider>          
                  <sharedAccessSignature keyName="owner" key="MyToken"/>
                </tokenProvider>
              </transportClientEndpointBehavior>
            </behavior>
          </endpointBehaviors>
          <!--<endpointBehaviors>
            <behavior > 
              <webHttp/>
            </behavior>
          </endpointBehaviors>-->
        </behaviors>

    Operational contract is[OperationContract] [WebInvoke(UriTemplate = "/SamplePost", Method = "POST", BodyStyle = WebMessageBodyStyle.Bare, RequestFormat = WebMessageFormat.Json)] string SamplePost(PostMethodClass Request);

    I have tried WebMessageBodyStyle.Wrapped, WebMessageBodyStyle.WrappedRequest, but no luck.

    when trying to consume from client using HttpClient. the request objet at service side is always null. I'm sending Json Data

    Any help in this is highly appreciated.

    Thanks

    Badri



    Monday, March 20, 2017 8:19 AM

All replies

    1. Does it work if you use the standard WCF webHttpBinding?  I'd strongly recommend getting it working with webHttpBinding before adding Relay into the picture.
    2. What does your PostMethodClass look like?
    3. What does your HttpClient sender code look like?

    -Dave

    Wednesday, March 22, 2017 5:49 PM
  • Here's an end-to-end working sample.  I hope it helps.

    -Dave

        [DataContract]
        class PostMethodClass
        {
            [DataMember]
            public string Data { get; set; }
    
            public override string ToString()
            {
                return $"{nameof(PostMethodClass)} {{\"Data\":\"{this.Data}\"}}";
            }
        }
    
        [ServiceContract]
        interface IService
        {
            [OperationContract]
            [WebInvoke(
                UriTemplate = "/SamplePost",
                Method = "POST",
                BodyStyle = WebMessageBodyStyle.Bare,
                RequestFormat = WebMessageFormat.Json,
                ResponseFormat = WebMessageFormat.Json)]
            string SamplePost(PostMethodClass request);
        }
    
        [ServiceBehavior]
        class Service : IService
        {
            [OperationBehavior]
            public string SamplePost(PostMethodClass request)
            {
                Console.WriteLine("SamplePost called.");
                Console.WriteLine("    request = {0}", request == null ? "null" : request.ToString());
                Console.WriteLine("    uri = {0}", OperationContext.Current.IncomingMessageProperties.Via);
                return "Response from Service";
            }
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                RunAsync().Wait();
            }
    
            static async Task RunAsync()
            {
                string httpAddress = "http://localhost:20869/posttest/";
                var webHttpBinding = new WebHttpBinding();
    
                string relayAddress = "https://REPLACE.servicebus.windows.net/posttest/";
                var relayHttpBinding = new WebHttpRelayBinding();
                var tokenProvider = TokenProvider.CreateSharedAccessSignatureTokenProvider("RootManageSharedAccessKey", "REPLACE_KEY_HERE");
                var credentialsBehavior = new TransportClientEndpointBehavior(tokenProvider);
    
                var serviceHost = new WebServiceHost(typeof(Service));
                serviceHost.AddServiceEndpoint(typeof(IService), webHttpBinding, httpAddress);
                serviceHost.AddServiceEndpoint(typeof(IService), relayHttpBinding, relayAddress).EndpointBehaviors.Add(credentialsBehavior);
                serviceHost.Open();
                Console.WriteLine("Service is listening");
    
                using (var httpClient = new HttpClient())
                {
                    var webHttpResponse = await httpClient.PostAsJsonAsync(httpAddress + "SamplePost", new PostMethodClass() { Data = "normal http send" });
                    Console.WriteLine("{0} {1}", (int)webHttpResponse.StatusCode, webHttpResponse.ReasonPhrase);
                    if (webHttpResponse.Content != null && webHttpResponse.Content.Headers.ContentLength > 0)
                    {
                        Console.WriteLine(await webHttpResponse.Content.ReadAsStringAsync());
                    }
    
                    string webToken = await tokenProvider.GetWebTokenAsync(relayAddress, "Send", false, TimeSpan.FromSeconds(10));
                    httpClient.DefaultRequestHeaders.Add("ServiceBusAuthorization", webToken);
                    var webHttpRelayResponse = await httpClient.PostAsJsonAsync(relayAddress + "SamplePost", new PostMethodClass() { Data = "relayed http send" });
                    Console.WriteLine("{0} {1}", (int)webHttpRelayResponse.StatusCode, webHttpRelayResponse.ReasonPhrase);
                    if (webHttpRelayResponse.Content != null && webHttpRelayResponse.Content.Headers.ContentLength > 0)
                    {
                        Console.WriteLine(await webHttpRelayResponse.Content.ReadAsStringAsync());
                    }
                }
    
                Console.WriteLine("Press Enter to stop listener...");
                Console.ReadLine();
    
                serviceHost.Close();
            }
        }

    Wednesday, March 22, 2017 7:09 PM