在WCF中为操作合同进行路由

时间:2016-11-14 09:36:02

标签: c# asp.net rest wcf asp.net-web-api

我是WCF的初学者,并创建了一个名为OrderProcessor的RESTful服务,其中包含三个操作:

bool IsClientActive(string token);
Order ProcessOrder();
string CheckStatus(Guid orderNumber);

我需要有关同一服务的几点建议和反馈: 1.属性路由:我知道像在WebAPI中一样,在WCF中不可能使用属性路由,但我想用以下URL创建api: http://localhost:{portnumber}/OrderProcessor/IsClientActive/{token} - POST request for IsClientActive() method http://localhost:{portnumber}/OrderProcessor/ProcessOrder - GET request for the ProcessOrder() method http://localhost:{portnumber}/OrderProcessor/CheckStatus/{orderNumber} - POST request for the CheckStatus() method

所以,我已经定义了服务的接口和实现,如下所示:
合同 - IOrderProcessor.cs

interface IOrderProcessor
{
    [OperationContract]
    [WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Xml,     ResponseFormat = WebMessageFormat.Json, UriTemplate = "/api/{token}")]
    bool IsClientActive(string token);

    [OperationContract(IsOneWay = false)]
    [WebInvoke(Method = "GET", RequestFormat = WebMessageFormat.Xml, ResponseFormat = WebMessageFormat.Json, UriTemplate = "/api")]
    Order ProcessOrder();

    [OperationContract]
    [WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Xml, ResponseFormat = WebMessageFormat.Json, UriTemplate = "/api/{orderNumber}")]
    string CheckStatus(Guid orderNumber);
}

实施 - OrderProcessor.cs

public class OrderProcessor : IOrderProcessor
    {
        public bool IsClientActive(string token)
        {
            bool status = false;
            try
            {
                if (!string.IsNullOrEmpty(token.Trim()))
                {
                    //Do db checking
                    status = true;
                }
                status = false;
            }
            catch (Exception ex)
            {
                //Log exception
                throw ex;
            }
            return status;
        }

        public Order ProcessOrder()
        {
            Order newOrder = new Order()
            {
                Id = Guid.NewGuid(),
                Owner = "Admin",
                Recipient = "User",
                Info = "Information about the order",
                CreatedOn = DateTime.Now
            };
            return newOrder;
        }

        public string CheckStatus(Guid orderNumber)
        {
            var status = string.Empty;
            try
            {
                if (!(orderNumber == Guid.Empty))
                {
                    status = "On Track";
                }
                status = "Order Number is invalid";

            }
            catch (Exception)
            {
                //Do logging
                throw;
            }

            return status;
        }
    }

的Web.config

<system.serviceModel>
    <services>
      <service name="WCF_MSMQ_Service.OrderProcessor" behaviorConfiguration="ServiceBehavior">
        <!-- Service Endpoints -->
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:4723/"/>
          </baseAddresses>
        </host>

        <!-- Unless fully qualified, address is relative to base address supplied above -->
        <endpoint address="" binding="webHttpBinding" contract="WCF_MSMQ_Service.IOrderProcessor" behaviorConfiguration="Web"></endpoint>
      </service>
    </services>

    <behaviors>
      <serviceBehaviors>
        <behavior name="ServiceBehavior">
          <!-- Enable metadata publishing. -->
          <!-- 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="false"/>
        </behavior>
      </serviceBehaviors>

      <endpointBehaviors>
        <behavior name="Web">
          <webHttp/>
        </behavior>
      </endpointBehaviors>
    </behaviors>

    <protocolMapping>
        <add binding="basicHttpsBinding" scheme="https" />
    </protocolMapping>   

    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>

问题: 我已经实现了所有代码但是当我尝试使用Visual Studio运行它(在浏览器中查看)时,我无法访问上面定义的URL。例如,我试图检查URL: http://localhost:4723/OrderProcessor/api 它抛出以下错误:

  

在合同&#39; IOrderProcessor&#39;中,有多个操作   方法&#39; POST&#39;和UriTemplate相当于   &#39; / API / {ORDERNUMBER}&#39 ;.每个操作都需要一个独特的组合   UriTemplate和方法明确地分派消息。使用   WebGetAttribute或WebInvokeAttribute改变UriTemplate和   操作的方法值。

我试图搜索此错误,有人建议放置 &#34; [ServiceBehavior(AddressFilterMode = AddressFilterMode.Any)]&#34;在实现,心理类,但错误仍然在这里[AddressFilter mismatch at the EndpointDispatcher - the msg with To。有人可以像WebAPI一样建议使用URL吗?

1 个答案:

答案 0 :(得分:1)

对于以下两种服务方法,简单的UriTemplate无法区分,

[WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Xml,     ResponseFormat = WebMessageFormat.Json, UriTemplate = "/api/{token}")]
bool IsClientActive(string token);

[WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Xml, ResponseFormat = WebMessageFormat.Json, UriTemplate = "/api/{orderNumber}")]
string CheckStatus(Guid orderNumber);

要区分您可以通过在UriTemplate

中添加方法名称来更改它
UriTemplate = "/api/isClientActive/{token}"

UriTemplate = "/api/checkStatus/{orderNumber}"