【问题标题】:WCF REST service url routing based on query parameters基于查询参数的 WCF REST 服务 url 路由
【发布时间】:2015-08-14 20:41:12
【问题描述】:

由于 WCF 路由不支持 REST 服务的路由,因此我创建了一个 REST 服务,该服务具有一个接受所有传入请求并根据查询参数重定向这些请求的端点。
我是按照这篇文章 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);
}

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

【问题讨论】:

    标签: c# web-services wcf rest


    【解决方案1】:

    我最终捕获了所有 CommunicationExceptions,然后使用适当的消息和状态代码重新抛出 WebFaultExceptions。

    代码如下:

    Message result = null;
    try
    {
        result = _client.ProcessRequest(requestMessage);
    }
    catch (CommunicationException ex)
    {
        if (ex.InnerException == null ||
            !(ex.InnerException is WebException))
        {
            throw new WebFaultException<string>("An unknown internal Server Error occurred.",
                HttpStatusCode.InternalServerError);
        }
        else
        {
            var webException = ex.InnerException as WebException;
            var webResponse = webException.Response as HttpWebResponse;
    
            if (webResponse == null)
            {
                throw new WebFaultException<string>(webException.Message, HttpStatusCode.InternalServerError);
            }
            else
            {
                var responseStream = webResponse.GetResponseStream();
                string message = string.Empty;
                if (responseStream != null)
                {
                    using (StreamReader sr = new StreamReader(responseStream))
                    {
                        message = sr.ReadToEnd();
                    }
                    throw new WebFaultException<string>(message, webResponse.StatusCode);
                }
                else
                {
                    throw new WebFaultException<string>(webException.Message, webResponse.StatusCode);                            
                }
            }
        }
    }
    

    【讨论】:

    • 这是一个沉重的catch
    猜你喜欢
    • 2017-07-07
    • 2023-03-23
    • 2011-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多