题
为了获得WCF服务使用jQuery我已经操作合同来控制JSON序列上添加了一个WebInvoke属性如下:
[WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]
有一种方法,因为它从不同的端点提供不同serialisations限制了这种服务,以控制通过在配置而不是服务绑定此串行化。
解决方案
我有不同的解决方案,其在从@Marc Gravell的相对的端部的工作原理:而不是重复的合同,从服务实施派生2不同的类。这些只是类型别名;他们是必要的,因为WCF激活系统(如至少在IIS)将不允许您激活在不同的URL相同的服务类型(我不知道为什么Gravell的解决方案并没有碰到这个问题 - 我是错误得到的是“注册已存在的URI ......”当我尝试激活不同的URL相同的服务类在同一个站点)。请注意,这只是一个问题,如果你想与痘和JSON的同时的运行相同的服务。如果你想要的是控制响应格式,则不需要此解决方法。
后面我的解决方案的关键概念是使用2点不同的URI相同的服务,则使用的终结点行为来设置默认出站响应格式。你可以找到更多的这个问题,这也触及了问题的概念纯度:我们应该用合同属性来指定网络协议的部分属性?我认为马克Gravell的在这个问题上是有效的本身,但它是不相符的WCF,其中合同都应该被抽象从协议栈远的原始概念。但端点的行为不会让你指定所有REST相关的属性,你必须使用URI模板和入站格式的属性。
可以休息已经实现不同?虽然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
{}
}
如果不是因为该类型别名的必要性,我会说这是一个完整的解决方案。这是,如果你不想要同时支持多种格式的完整解决方案。这是优于方面的多个合同的解决方案,因为只有一个合同,你不需要保持2个合约同步。