Search code examples
.netasp.net-mvcweb-serviceswcfcastle-windsor

Is it possible to inject WCF REST service client via castle windsor


I created two WCF rest services service1 and service2 hosted in separate ports and used Castle Windsor for dependency injection in service1 and now from service1 trying to call service2. but when I create an instance and call for the service2, I am getting an exception saying bad request(400). When I request for service2 from REST client I am able to get the 200 response. Is the error due to castle Windsor lifestyle behavior?.

Container config (service 1)

Container.AddFacility<WcfFacility>().Register(
                           Component.For(type).AsWcfClient(
                               new DefaultClientModel { 
                                       Endpoint = WcfEndpoint.FromConfiguration("*") }));

Configuration (service 1)

<system.serviceModel>
<client>
    <endpoint address="http://localhost:8082/BLDBService" binding="webHttpBinding" bindingConfiguration="customHttpBinding" contract ="DataSourceContracts.IBLDBService" behaviorConfiguration ="serviceEndpointHttpBehavior">
  </endpoint>
</client>
<services>
  <service name="BusinessService.MetaDataService" behaviorConfiguration="basicHttpBehavior">        
    <host>
      <baseAddresses >
        <add baseAddress ="http://localhost:8084/"/>
      </baseAddresses>
    </host>
   <endpoint address="MetaDataService" binding="webHttpBinding" contract ="BusinessServiceContracts.IMetaDataService" behaviorConfiguration="endpointHttpBehavior" />
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
  </service>
</services>
<bindings>
  <!--<basicHttpsBinding>
    <binding name="BasicHttpsBinding">
      <security mode="Transport">
        <transport clientCredentialType="None"></transport>
      </security>
    </binding>
  </basicHttpsBinding>-->
  <webHttpBinding>
    <binding name ="customHttpBinding" transferMode ="Streamed">          
    </binding>
  </webHttpBinding>
</bindings>
<behaviors>
  <endpointBehaviors>
    <behavior name="endpointHttpBehavior">
      <webHttp helpEnabled ="true" automaticFormatSelectionEnabled ="true" defaultOutgoingResponseFormat ="Json"></webHttp>
    </behavior>
    <behavior name="serviceEndpointHttpBehavior">
      <webHttp defaultOutgoingResponseFormat="Json" automaticFormatSelectionEnabled ="true" helpEnabled ="true"  />
      <dataContractSerializer/>
    </behavior>
  </endpointBehaviors>
  <serviceBehaviors>
    <behavior name="basicHttpBehavior">
     <serviceMetadata httpGetEnabled="true"/>
      <serviceDebug includeExceptionDetailInFaults="true" />
    </behavior>
  </serviceBehaviors>
</behaviors>

Service call (service 1)

_bldbService = Container.resolve<IBLDBService>();
WebOperationContext.Current.OutgoingRequest.ContentType = "application/json";
viewModel = _bldbService.GetBLDBData(viewModel);

Configuration (Service2)

 <service name="BusinessService.BLDBService" behaviorConfiguration="basicHttpBehavior">
    <!--<endpoint address="net.tcp://localhost:8082/BLDBService" binding="netTcpBinding" contract="BusinessServiceContracts.IBLDBService"/>-->
    <host>
      <baseAddresses>
        <add baseAddress ="http://localhost:8082/"/>
      </baseAddresses>
    </host>
    <endpoint address="BLDBService" binding="webHttpBinding"    contract ="BusinessServiceContracts.IBLDBService" behaviorConfiguration="endpointHttpBehavior"/>
  </service>

On calling from REST Client

enter image description here

P.S. I have tested with net/tcp protocol and it works perfectly.

enter image description here

here is the log

        Time : 06.03.2017 11:11:15
    ----------------------------------------------------------------------------------------------------------------
    Message: The remote server returned an unexpected response: (400) Bad Request.
    ----------------------------------------------------------------------------------------------------------------
    Environment: Castle.Facilities.WcfIntegration
    ----------------------------------------------------------------------------------------------------------------
    Stack Trace: at System.ServiceModel.Channels.HttpChannelUtilities.ValidateRequestReplyResponse(HttpWebRequest request, HttpWebResponse response, HttpChannelFactory`1 factory, WebException responseException, ChannelBinding channelBinding)
       at System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
       at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
       at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
       at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
       at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
       at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
       at Castle.Facilities.WcfIntegration.Proxy.WcfRemotingInterceptor.InvokeRealProxy(RealProxy realProxy, WcfInvocation wcfInvocation)
       at Castle.Facilities.WcfIntegration.WcfInvocation.Proceed()
       at Castle.Facilities.WcfIntegration.RepairChannelPolicy.Apply(WcfInvocation wcfInvocation)
       at Castle.Facilities.WcfIntegration.Proxy.WcfRemotingInterceptor.PerformInvocation(IInvocation invocation, Action`1 action)
       at Castle.DynamicProxy.AbstractInvocation.Proceed()
       at Castle.Proxies.IBLDBServiceProxy.GetBLDBData(MetaDataViewModel viewModel)
       at BusinessLogic.BLDBBusinessManager.GetData(MetaDataViewModel viewModel) in C:\localPTC\Sample\BasicFramework\BusinessLogic\BLDB\BLDBBusinessManager.cs:line 46
       at BusinessService.MetaDataService.GetMetaData(MetaDataViewModel metadata) in C:\localPTC\Sample\BasicFramework\BusinessService\Services\MetaDataService.cs:line 16
    ----------------------------------------------------------------------------------------------------------------


    Time : 06.03.2017 11:11:15
    ----------------------------------------------------------------------------------------------------------------
    Message: The remote server returned an error: (400) Bad Request.
    ----------------------------------------------------------------------------------------------------------------
    Environment: System
    ----------------------------------------------------------------------------------------------------------------
    Stack Trace: at System.Net.HttpWebRequest.GetResponse()
       at System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
    ----------------------------------------------------------------------------------------------------------------

Solution

  • Finally found the answer.

    I was hardcoding Request-Reponse format for the service as JSON. now I removed it from the service contract and It's works perfectly. The new service contract and web.config looks like below.

    namespace DataSourceContracts
    {
    using System.ServiceModel;
    using System.ServiceModel.Web;
    using ViewModel.DataSource;
    
        /// <summary>
        /// This is same as the exposed BLDB data REST service in abother project we need to keep both in sync. 
        /// The reason for not refering to the same project is the .Net framework version
        /// </summary>
        [ServiceContract]
        public interface IBLDBService : IDataSourceService
        {
            /// <summary>
            /// Sample method
            /// </summary>
            /// <param name="viewModel"></param>
            /// <returns></returns>
            [OperationContract]
            [WebInvoke(Method = "POST",  UriTemplate = "GetBLDBData")]
            MetaDataViewModel GetBLDBData(MetaDataViewModel viewModel);
        }
    }
    

    Web.Config

      <behaviors>
          <endpointBehaviors>
            <behavior name="endpointHttpBehavior">
              <webHttp helpEnabled="true" automaticFormatSelectionEnabled="true"  defaultBodyStyle="Bare"></webHttp>
            </behavior>
        </endpointBehaviors>
    </behaviors>