我正在编写WCF REST服务以使用我的WCF REST服务接收AWS SNS通知消息。
但是,WCF REST仅支持XML和JSON,但由于遗留原因,Amazon SNS使用Content-Type: text/plain; charset=UTF-8
标头发布了通知,根据Amazon documentation:
POST / HTTP/1.1
Content-Type: text/plain; charset=UTF-8
// ...
{
"Type" : "Notification",
// ...
"UnsubscribeURL" : "https://sns.us-west-2.amazonaws.com/?Action=Unsubscribe&..."
}
当我用这个" text / plain"来呼叫我的服务时像亚马逊这样的内容类型,有一个错误,上面写着:
请求错误。
服务器在处理请求时遇到错误。异常消息是'传入消息具有意外的消息格式' Raw'。该操作的预期消息格式是' Xml&#39 ;; '的Json&#39 ;.这可能是因为尚未在绑定上配置WebContentTypeMapper。有关更多详细信息,请参阅WebContentTypeMapper的文档。'。有关详细信息,请参阅服务器日志。
我目前的代码:
public interface MyServiceInterface
{
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "/AmazonIPChanges")]
Task AmazonIPChanges(SNSNotificationMessage data);
}
[DataContract]
public class SNSNotificationMessage
{
[DataMember]
public string Type { get; set; }
// ...
[DataMember]
public string UnsubscribeURL { get; set; }
}
DataContract映射到Amazon SNS消息。当我使用content-type" application / json"执行POST时,此代码正常工作,但我怎样才能让它接受亚马逊的text / plain内容类型?
答案 0 :(得分:3)
您可以通过创建和应用自定义WebContentTypeMapper
来解决此问题,如错误消息所示。它应该是这样的:
namespace StackOverflow36216464
{
public class RawContentTypeMapper : WebContentTypeMapper
{
public override WebContentFormat GetMessageFormatForContentType(string contentType)
{
switch (contentType.ToLowerInvariant())
{
case "text/plain":
case "application/json":
return WebContentFormat.Json;
case "application/xml":
return WebContentFormat.Xml;
default:
return WebContentFormat.Default;
}
}
}
}
这个解释请求的内容类型,并返回相应的WebContentFormat
枚举成员。
然后,您可以以自定义绑定的形式将其应用于您的服务:
<system.serviceModel>
<bindings>
<customBinding>
<binding name="textPlainToApplicationJson">
<webMessageEncoding webContentTypeMapperType="StackOverflow36216464.RawContentTypeMapper, StackOverflow36216464, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<httpTransport manualAddressing="true" />
</binding>
</customBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="debugServiceBehavior">
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="restEndpointBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service
name="StackOverflow36216464.Service1"
behaviorConfiguration="debugServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="http://localhost:65393/"/>
</baseAddresses>
</host>
<endpoint address=""
binding="customBinding"
contract="StackOverflow36216464.IService1"
behaviorConfiguration="restEndpointBehavior"
bindingConfiguration="textPlainToApplicationJson"/>
</service>
</services>
</system.serviceModel>
相关部分是配置自定义映射器的<customBinding>
元素,以及应用它的servcices/service/endpoint/bindingConfiguration
属性。