0

我有一个 WCF REST 服务,其操作如下:

[OperationContract]
[WebInvoke(UriTemplate = "/User", BodyStyle = WebMessageBodyStyle.Bare, Method = "POST", RequestFormat = WebMessageFormat.Json)]
void User(User user);

当我从 Fiddler 调用它时,如果我像这样指定 Content-Type="application/json" 它工作正常:

Content-Type: application/json
Host: localhost:58150
Content-Length: 172
Expect: 100-continue

但是,如果我排除 Content-Type,那么我会收到错误 400,因为它会尝试将请求正文作为 XML 处理。这很烦人,你真的会认为设置 RequestFormat = WebMessageFormat.Json 会成功,这样我就不必指定 Content-Type 但事实并非如此。事实上,如果我放弃“RequestFormat”,一切都不会改变。我也尝试过为 WebMessageBodyStyle 'wrapped',但 DTO 来自 null。

澄清一下,如果我在帖子正文中也使用 XML(并省略 Content-Type),就会发生这种情况......所以我真正想要完成的是:

使用 WebInvoke 时如何使我的 WCF Rest 方法不需要 Content-Type(我希望 WCF 能够自动解决)

这让我发疯请帮助。

4

2 回答 2

1

您需要在 WebHttpBinding 上添加 WebContentTypeMapper。在那里,您可以告诉 WCF 运行时 WebContentFormat 提供的(或假定的)内容类型 mime 值是什么。通常,当收到没有内容类型标头的 POST 时,这将是“application/x-www-form-urlencode”(multipart/form-data 或 text/plain 也可能发生,因此请注意)。只需告诉 WCF 这是 Json 或 Xml(或您需要的任何东西),它就会起作用(您的 Millage 可能会有所不同)。

    public class YourContentTypeMapper : WebContentTypeMapper
{
    public override WebContentFormat GetMessageFormatForContentType(string contentType)
    {
        if (contentType == "application/x-www-form-urlencode")
        {
            return WebContentFormat.Json; // assuming this is wanted
        }
        else
        {
            return WebContentFormat.Default;
        }
    }
}

只需将 WebHttpBinding 上的 ContentTypeMapper 设置为您的类的实例(这可以在配置文件中完成,也可以在使用 contentTypeMapper 属性的绑定上完成)

var binding = new WebHttpBinding();
binding.ContentTypeMapper = new YourContentTypeMapper();

更多信息 => https://msdn.microsoft.com/en-us/library/bb943479(v=vs.110).aspx

于 2016-02-24T23:49:26.377 回答
0

您是否尝试将automaticFormatSelectionEnabled端点行为设置为 true?

考虑到此属性特定于 NET 4.0,我记得使用它来格式化基于 http 的 Accept 标头的响应消息。

我没有尝试重现您的场景,但阅读此官方文档链接它指出以下内容:

如果请求消息包含 Accept 标头,Windows Communication Foundation (WCF) 基础结构将搜索它支持的类型。如果 Accept 标头为它的媒体类型指定了优先级,它们就会被接受。如果在 Accept 标头中找不到合适的格式,则使用请求消息的内容类型。如果未指定合适的内容类型,则使用操作的默认格式设置。

这是 msdn 中关于如何设置 automaticFormatSelectionEnabled 的示例。

<behaviors>
  <endpointBehaviors>
    <behavior>
      <webHttp automaticFormatSelectionEnabled="true" />
    </behavior>
  </endpointBehaviors>
</behaviors>
于 2013-06-13T03:16:15.283 回答