是否可以通过温莎城堡注入 WCF REST 服务客户端
Is it possible to inject WCF REST service client via castle windsor
我创建了两个 WCF 休息服务 service1
和 service2
托管在不同的端口,并使用 Castle Windsor
在 service1
中进行依赖注入,现在从 service1
试图打电话给 service2
。但是当我创建一个实例并调用 service2
时,我收到一个异常 bad request(400)
。当我从 REST 客户端请求 service2
时,我能够获得 200 response
。错误是由于温莎城堡的生活方式行为造成的吗?
容器配置(服务 1)
Container.AddFacility<WcfFacility>().Register(
Component.For(type).AsWcfClient(
new DefaultClientModel {
Endpoint = WcfEndpoint.FromConfiguration("*") }));
配置(服务 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>
服务调用(服务 1)
_bldbService = Container.resolve<IBLDBService>();
WebOperationContext.Current.OutgoingRequest.ContentType = "application/json";
viewModel = _bldbService.GetBLDBData(viewModel);
配置(服务 2)
<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>
从 REST 客户端调用时
P.S。我已经使用 net/tcp 协议进行了测试,它运行良好。
这是日志
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)
----------------------------------------------------------------------------------------------------------------
终于找到答案了。
我将服务的请求-响应格式硬编码为 JSON。现在我把它从服务合同中删除了,它工作得很好。新的服务合同和 web.config 如下所示。
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>
我创建了两个 WCF 休息服务 service1
和 service2
托管在不同的端口,并使用 Castle Windsor
在 service1
中进行依赖注入,现在从 service1
试图打电话给 service2
。但是当我创建一个实例并调用 service2
时,我收到一个异常 bad request(400)
。当我从 REST 客户端请求 service2
时,我能够获得 200 response
。错误是由于温莎城堡的生活方式行为造成的吗?
容器配置(服务 1)
Container.AddFacility<WcfFacility>().Register(
Component.For(type).AsWcfClient(
new DefaultClientModel {
Endpoint = WcfEndpoint.FromConfiguration("*") }));
配置(服务 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>
服务调用(服务 1)
_bldbService = Container.resolve<IBLDBService>();
WebOperationContext.Current.OutgoingRequest.ContentType = "application/json";
viewModel = _bldbService.GetBLDBData(viewModel);
配置(服务 2)
<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>
从 REST 客户端调用时
P.S。我已经使用 net/tcp 协议进行了测试,它运行良好。
这是日志
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)
----------------------------------------------------------------------------------------------------------------
终于找到答案了。
我将服务的请求-响应格式硬编码为 JSON。现在我把它从服务合同中删除了,它工作得很好。新的服务合同和 web.config 如下所示。
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>