【问题标题】:Can WebInvoke attributes be replaced by binding configurationsWebInvoke 属性可以被绑定配置替换吗
【发布时间】:2009-03-18 13:12:23
【问题描述】:

为了让 WCF 服务与 JQuery 一起工作,我在操作合同上添加了一个 WebInvoke 属性来控制 JSON 序列化,如下所示:

[WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]

有没有办法通过配置中的服务绑定来控制这种序列化,因为它限制了这个服务向不同的端点提供不同的序列化。

【问题讨论】:

    标签: .net wcf wcf-binding


    【解决方案1】:

    我有一个不同的解决方案,它与@Marc Gravell 的相反:不是复制合同,而是从服务实现派生两个不同的类。这些只是类型别名;它们是必要的,因为 WCF 激活系统(至少在 IIS 上)不允许您在不同的 URLS 激活相同的服务类型(我不确定为什么 Gravell 的解决方案没有遇到这个问题 - 我的错误当我尝试在同一站点的不同 URL 上激活相同的服务类时,得到的是“URI 的注册已经存在...”)。请注意,只有当您希望使用 pox 和 json 同时运行相同的服务时,这才是一个问题。如果您只想控制响应格式,则不需要此解决方法。

    我的解决方案背后的关键概念是为同一个服务使用 2 个不同的 URI,然后使用端点行为来设置默认的出站响应格式。您可以在this question 中找到更多信息,这也涉及概念纯度问题:我们是否应该使用合约属性来指定属于网络协议的属性?我认为 Marc Gravell 对这个问题的看法本身是有效的,但它与 WCF 的原始概念不一致,其中合约应该从协议栈中抽象出来。但是端点行为不允许您指定所有与 REST 相关的属性,您必须使用 URI 模板和入站格式的属性。

    REST 是否可以以不同的方式实现?尽管 WCF 的设计者在设计通用框架方面做得非常出色,但我认为他们没有看到 REST 的到来。有些东西,比如 URI 模板,似乎确实属于合同。

    说得够多了!这是代码。首先是 web.config 文件。这就是魔法发生的地方。请注意,我在此示例中使用基于 WCF 4 配置的激活,但您也可以通过使用 2 个 svc 文件来表示 2 个 URI 来完成相同的操作。

    <?xml version="1.0"?>
    <configuration>
      <system.web>
        <compilation debug="true" targetFramework="4.0" />
      </system.web>
      <system.serviceModel>
        <services>
          <service name="StackOverflow.QuoteOfTheDayAsJson">
            <endpoint binding="webHttpBinding" contract="StackOverflow.IQuoteOfTheDay" 
                      behaviorConfiguration="jsonBehavior" />
          </service>
          <service name="StackOverflow.QuoteOfTheDayAsPox">
            <endpoint binding="webHttpBinding" contract="StackOverflow.IQuoteOfTheDay" 
                      behaviorConfiguration="poxBehavior" />
          </service>
        </services>
        <behaviors>
          <endpointBehaviors>
            <behavior name="jsonBehavior">
              <webHttp defaultOutgoingResponseFormat="Json" />
            </behavior>
            <behavior name="poxBehavior">
              <webHttp defaultOutgoingResponseFormat="Xml"/>
            </behavior>
          </endpointBehaviors>
        </behaviors>
        <serviceHostingEnvironment multipleSiteBindingsEnabled="false">
          <serviceActivations>
            <add relativeAddress="QuoteOfTheDayJson.svc" 
                 service="StackOverflow.QuoteOfTheDayAsJson"/>
            <add relativeAddress="QuoteOfTheDayPox.svc" 
                 service="StackOverflow.QuoteOfTheDayAsPox"/>
          </serviceActivations>
        </serviceHostingEnvironment>
      </system.serviceModel>
    </configuration>
    

    下面是代码,包括服务契约、服务实现以及使这项工作正常工作所必需的类型别名:

    namespace StackOverflow
    {
        [DataContract]
        public class Quotation
        {
            [DataMember]
            public string Text { get; set; }
    
            [DataMember]
            public string Author { get; set; }
        }
    
        [ServiceContract]
        public interface IQuoteOfTheDay
        {
            [OperationContract]
            [WebInvoke(Method="GET", UriTemplate="GetTodaysQuote")]
            Quotation GetTodaysQuote();
        }
    
        public class QuoteOfTheDayImp : IQuoteOfTheDay
        {
            public Quotation GetTodaysQuote()
            {
                return new Quotation()
                {
                    Text = "Sometimes it's better to appologize for not asking permission",
                    Author = "Admiral Grace Murray Hopper"
                };
            }
        }
    
        /// <summary>
        /// A type alias used for json activation
        /// </summary>
        public class QuoteOfTheDayAsJson : QuoteOfTheDayImp 
        {}
    
        /// <summary>
        /// A type alias used for pox activation
        /// </summary>
        public class QuoteOfTheDayAsPox : QuoteOfTheDayImp
        {}
    }
    

    如果不是类型别名的必要性,我会说这是一个完整的解决方案。如果您不想同时支持多种格式,这是一个完整的解决方案。这优于多合约解决方案,因为只有一个合约,您不需要保持这两个合约同步。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-05-17
      • 2018-05-10
      • 2012-12-11
      • 1970-01-01
      • 2020-06-14
      • 1970-01-01
      • 2017-11-26
      • 1970-01-01
      相关资源
      最近更新 更多