在 WCF REST 服务中通过 POST 发送参数的正确 URI 是啥?

Posted

技术标签:

【中文标题】在 WCF REST 服务中通过 POST 发送参数的正确 URI 是啥?【英文标题】:What is the correct URI for sending parameters via POST in WCF REST Services?在 WCF REST 服务中通过 POST 发送参数的正确 URI 是什么? 【发布时间】:2011-03-23 06:55:16 【问题描述】:

假设我在地址“http://localhost/MyRESTService/MyRESTService.svc”指定了以下 WCF REST 服务

[ServiceContract]
public interface IMyRESTService

[OperationContract]
[WebInvoke(
  Method = "POST",
  UriTemplate = "/receive")]
string Receive(string text);

现在我可以使用地址“http://localhost/MyRESTService/MyRESTService.svc/receive”在 Fiddler 中调用我的 REST 服务并且它可以工作(我会得到一个返回值)。

但是如果我想向我的 REST 服务发送参数怎么办?我应该将我的接口定义更改为如下所示:

[ServiceContract]
public interface IMyRESTService

[OperationContract]
[WebInvoke(
  Method = "POST",
  UriTemplate = "/receive/text")]
string Receive(string text);

现在,如果我使用地址“http://localhost/MyRESTService/MyRESTService.svc/receive/mytext”在 Fiddler 中调用 REST 服务,它可以工作(它发送参数“mytext”,我会得到一个返回值)。那么这是通过 POST 发送参数的正确 URI 吗?

让我感到困惑的是,当我发送参数时,我不知道如何在代码中准确地使用这个 URI。我有以下代码,几乎可以将 POST 数据发送到 WCF REST 服务,但我不知道如何使用 URI 来考虑参数。

Dictionary<string, string> postDataDictionary = new Dictionary<string, string>();
      postDataDictionary.Add("text", "mytext");

      string postData = "";
      foreach (KeyValuePair<string, string> kvp in postDataDictionary)
      
        postData += string.Format("0=1&", HttpUtility.UrlEncode(kvp.Key), HttpUtility.UrlEncode(kvp.Value));
      
      postData = postData.Remove(postData.Length - 1); 

      Uri uri = new Uri("http://localhost/MyRESTService/MyRESTService.svc/receive");
      HttpWebRequest req = (HttpWebRequest)WebRequest.Create(uri);
      req.Method = "POST";
      byte[] postArray = Encoding.UTF8.GetBytes(postData);
      req.ContentType = "application/x-www-form-urlencoded";
      req.ContentLength = postArray.Length;

      Stream dataStream = req.GetRequestStream();
      dataStream.Write(postArray, 0, postArray.Length);
      dataStream.Close();

      HttpWebResponse response = (HttpWebResponse)req.GetResponse();
      Stream responseStream = response.GetResponseStream();
      StreamReader reader = new StreamReader(responseStream);

      string responseString = reader.ReadToEnd();

      reader.Close();
      responseStream.Close();
      response.Close();

如果我想通过 POST 在代码中发送参数(例如“mytext”),那么 URI 代码应该是其中一个

这个

Uri uri = new Uri("http://localhost/MyRESTService/MyRESTService.svc/receive");

或者这个(这个可行,但没有任何意义,因为参数应该以其他方式添加,而不是直接添加到 URI 地址)

Uri uri = new Uri("http://localhost/MyRESTService/MyRESTService.svc/receive/mytext");

如果您能帮助我,我很高兴,使用 WCF REST 服务不会那么困难。

【问题讨论】:

【参考方案1】:

因此,如果您想将 XML 等原始数据发送到您的 WCF REST 服务(并返回),请按照以下步骤操作。但我不得不说,在我找到这个解决方案之前,我花了很多时间在谷歌上搜索感到沮丧,因为所有示例都只是在讨论在 URI 中发送参数(来吧,常见的场景是发送 XML,而你不能正确地做到这一点在 URI 中)。最后,当我找到正确的代码示例时,我发现它在 WCF 中还不够,因为我收到了错误“400 Bad Request”。这个错误是由于 WCF 不能使用我的原始 XML 如果我不通过一些自定义代码覆盖它来强制它(来吧,你在想什么微软?,在 .NET 的下一个版本中解决这个问题)框架)。因此,如果做这样一个基本的事情如此困难和耗时,我一点也不满意)。

** IMyRESTService.cs(服务器端代码)**

[OperationContract]
[WebInvoke(BodyStyle = WebMessageBodyStyle.Bare)]
Stream Receive(Stream text);

** 客户端代码 **

XmlDocument MyXmlDocument = new XmlDocument();
MyXmlDocument.Load(FilePath);
byte[] RequestBytes = Encoding.GetEncoding("iso-8859-1").GetBytes(MyXmlDocument.OuterXml);

Uri uri = new Uri("http://localhost/MyRESTService/MyRESTService.svc/Receive");

Request.ContentLength = RequestBytes.Length;

Request.Method = "POST";

Request.ContentType = "text/xml";

Stream RequestStream = Request.GetRequestStream();
RequestStream.Write(RequestBytes, 0, RequestBytes.Length);
RequestStream.Close();

HttpWebResponse response = (HttpWebResponse)Request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream());
string ResponseMessage = reader.ReadToEnd();
response.Close();

** XmlContentTypeMapper.cs(强制 WCF 接受原始 XML 的服务器端自定义代码)**

public class XmlContentTypeMapper : WebContentTypeMapper

public override WebContentFormat GetMessageFormatForContentType(string contentType)

return WebContentFormat.Raw;


** Web.config(使用自定义代码的服务器端配置设置)

<endpoint binding="customBinding" bindingConfiguration="XmlMapper" contract="MyRESTService.IMyRESTService"
           behaviorConfiguration="webHttp"    />

<bindings>
  <customBinding>
    <binding name="XmlMapper">
      <webMessageEncoding webContentTypeMapperType="MyRESTService.XmlContentTypeMapper, MyRESTService"/>
      <httpTransport manualAddressing="true"/>
    </binding>
  </customBinding>
</bindings>

使用 HTTP POST 调用 WCF Web 服务 http://social.msdn.microsoft.com/forums/en-us/wcf/thread/4074F4C5-16CC-470C-9546-A6FB79C998FC

【讨论】:

我收到此 ("400") 错误消息,但仅在从运行较旧(精简版).NET 版本的手持设备调用时。至少就我而言,我认为我不需要对服务器进行更改,因为我的代码在“当代”客户端项目(在 VS 2013 中创建的 Winforms 应用程序)中运行良好【参考方案2】:

我遇到了同样的问题,使用 Fiddler 时,每次尝试使用 Body 发帖时都会收到 403(错误请求)错误。我花了几个小时才找到的修复方法是将内容类型更改为 application/xml 并将正文作为 Xml 发送。

这是我在 Fiddler 的 Header 中使用的那一行:

Content-Type: application/xml;charset=UTF-8 

现在我还没有使用 Microsoft.Http 库,在我的客户端中我使用 WebRequest 来发帖,并将 Content-Type 设置为:

request.ContentType = "application/xml;charset=UTF-8";

对我来说工作得很好。

现在,如果您想使用 URI 发送参数,我建议使用 WebGet 而不是带有 POST 的 WebInvoke。

【讨论】:

以上是关于在 WCF REST 服务中通过 POST 发送参数的正确 URI 是啥?的主要内容,如果未能解决你的问题,请参考以下文章

在自托管 Web 服务器环境中通过 POST REST API 上传 C# 文件

在 Azure 上的 WCF 中通过 SSL 配置 webHTTP 和 NetHTTP 绑定

在 Android 的 OKhttp 中通过 POST 请求发送 JSON 正文

将 JSON 数据从 JQuery 发送到 WCF REST 方法时出现问题

在 WCF REST 服务 POST 方法中处理 Json 请求数据

在事务中从 WCF 服务向 REST API 发出 Post 请求