由于 WCF 路由不支持 REST 服务的路由,因此我创建了一项 REST 服务,该服务具有一个端点,该端点接受所有传入请求,并根据查询参数重定向这些请求。
我按照这篇文章做到了这一点http://blog.tonysneed.com/2012/04/24/roll-your-own-rest-ful-wcf-router/ http://blog.tonysneed.com/2012/04/24/roll-your-own-rest-ful-wcf-router/.
此方法适用于传递请求并返回结果。问题是,每当我从实际服务中收到错误(例如 404)时,返回给客户端的消息都是 400(错误请求)。
我想要的是一个路由代理,它实际上只是根据查询将调用重定向到真实服务,并将所有错误返回给客户端,因为它们来自真实服务。
这是否是我想要实现的目标的正确方法,或者是否有更简单或更好的解决方案?
任何帮助表示赞赏!
在下面我添加了我的代码的样子。
应用程序配置:
<!--
System.net
-->
<system.net>
<settings>
<servicePointManager expect100Continue="false" useNagleAlgorithm="false" />
</settings>
<connectionManagement>
<add address="*" maxconnection="24" />
</connectionManagement>
</system.net>
<!--
System.ServiceModel
-->
<system.serviceModel>
<!--
Services
-->
<services>
<service name="RoutingGateway.RoutingService">
<endpoint address="/api/routing" binding="webHttpBinding" bindingConfiguration="secureWebHttpBinding" contract="RoutingGateway.IRoutingService" behaviorConfiguration="RESTBehaviour" />
</service>
</services>
<client>
<endpoint binding="webHttpBinding" bindingConfiguration="secureWebHttpBinding" contract="RoutingGateway.IRoutingService" name="routingService" behaviorConfiguration="RESTBehaviour" />
</client>
<!--
Bindings
-->
<bindings>
<webHttpBinding>
<binding name="secureWebHttpBinding" hostNameComparisonMode="StrongWildcard" maxReceivedMessageSize="2147483647" transferMode="Streamed">
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</binding>
</webHttpBinding>
</bindings>
<!--
Behaviors
-->
<behaviors>
<endpointBehaviors>
<behavior name="RESTBehaviour">
<dispatcherSynchronization asynchronousSendEnabled="true" />
<webHttp helpEnabled="true" />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the value below to false before deployment -->
<serviceMetadata httpsGetEnabled="false" />
<!-- 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="false" />
<!-- Enable Throttling -->
<serviceThrottling maxConcurrentCalls="100" maxConcurrentInstances="100" maxConcurrentSessions="100" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
IRoutingService.cs:
[ServiceContract(Namespace = "https://test/api/routing")]
public interface IRoutingService
{
[OperationContract(Action = "*", ReplyAction = "*")]
[WebInvoke(UriTemplate = "*", Method = "*")]
Message ProcessRequest(Message requestMessage);
}
路由服务.cs:
public Message ProcessRequest(Message requestMessage)
{
ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true;
Uri originalRequestUri = WebOperationContext.Current.IncomingRequest.UriTemplateMatch.RequestUri;
// Gets the URI depending on the query parameters
Uri uri = GetUriForRequest(requestMessage);
// Select rest client endpoint
string endpoint = "routingService";
// Create channel factory
var factory = new ChannelFactory<IRoutingService>(endpoint);
Uri requestUri = new Uri(uri, originalRequestUri.PathAndQuery);
factory.Endpoint.Address = new EndpointAddress(requestUri);
requestMessage.Headers.To = requestUri;
// Create client channel
_client = factory.CreateChannel();
// Begin request
Message result = _client.ProcessRequest(requestMessage);
return result;
}