首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >绑定配置能否替换WebInvoke属性

绑定配置能否替换WebInvoke属性
EN

Stack Overflow用户
提问于 2009-03-18 13:12:23
回答 1查看 1.8K关注 0票数 6

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

代码语言:javascript
复制
[WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-03-29 13:06:31

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

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

REST可以以不同的方式实现吗?尽管WCF的设计者在设计通用框架方面做得很好,但我认为他们并没有看到REST的到来。有些东西,比如URI模板,看起来确实属于合同。

说够了!这是代码。首先是web.config文件。这就是魔术发生的地方。请注意,我在本例中使用的是基于WCF4配置的激活,但是您也可以通过使用两个svc文件来表示两个URI来完成相同的任务。

代码语言:javascript
复制
<?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>

下面是代码,包括服务合同、服务实现和实现此功能所必需的类型别名:

代码语言:javascript
复制
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
    {}
}

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

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/658195

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档