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

时间:2010-07-30 14:18:04

标签: wcf rest parameters uri

假设我已在地址“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服务也不会那么困难。

2 个答案:

答案 0 :(得分:4)

因此,如果您想将XML等原始数据发送到WCF REST服务(并返回),请按照以下步骤操作。但我不得不说,在我找到这个解决方案之前,我花了很多时间谷歌搜索沮丧,因为所有的例子只是讨论在URI中发送参数(来吧,常见的情况是发送XML而你不能正确地做到这一点在URI中)。最后,当我找到正确的代码示例时,它出现了在WCF中因为我收到错误“400 Bad Request”而不够。这个错误是由于WCF不能使用我的原始XML,如果我不通过一些自定义代码覆盖它来强制它(来吧,你在想什么Microsoft?,在.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

答案 1 :(得分:2)

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

这是我在Fiddler的标题中使用的行:

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

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

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

对我来说很好。

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