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

发布于 2024-09-12 20:56:25 字数 2849 浏览 2 评论 0原文

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

[ServiceContract]
public interface IMyRESTService
{
[OperationContract]
[WebInvoke(
  Method = "POST",
  UriTemplate = "/receive")]
string Receive(string text);

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

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

[ServiceContract]
public interface IMyRESTService
{
[OperationContract]
[WebInvoke(
  Method = "POST",
  UriTemplate = "/receive/{text}")]
string Receive(string text);

现在,如果我使用地址“http://localhost/MyRESTService/MyRESTService.svc/receive/mytext" 它有效(它发送参数“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 服务不会那么困难。

Let's say that I have specified the following WCF REST Service at the address "http://localhost/MyRESTService/MyRESTService.svc"

[ServiceContract]
public interface IMyRESTService
{
[OperationContract]
[WebInvoke(
  Method = "POST",
  UriTemplate = "/receive")]
string Receive(string text);

Now I can call my REST service in Fiddler using the address "http://localhost/MyRESTService/MyRESTService.svc/receive" and it works (I'll get a return value).

But what if I want to send parameters to my REST Service? Should I change my interface definition to look like this:

[ServiceContract]
public interface IMyRESTService
{
[OperationContract]
[WebInvoke(
  Method = "POST",
  UriTemplate = "/receive/{text}")]
string Receive(string text);

Now if I'll call the REST Service in Fiddler using the address "http://localhost/MyRESTService/MyRESTService.svc/receive/mytext" it works (it sends the parameter "mytext" and I'll get a return value). So is this the correct URI for sending parameters via POST?

What confuses me is that I don't know how to use this URI exactly in code at the same time when I'm sending parameters. I have this following code which is almost complete for sending POST data to a WCF REST Service but I'm in stuck with how to take parameters into account with 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();

If I'll want to send parameters (e.g. "mytext") in code via POST should the URI code be either

this

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

or this (this works but it doesn't make any sense since parameters should be added other way and not directly to the URI address)

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

I'm glad if you can help me, it can't be so difficult with WCF REST Services.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

为你拒绝所有暧昧 2024-09-19 20:56:25

因此,如果您想将 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

So if you want to send raw data such as XML to your WCF REST Service (and also return), here is how to do it. But I have to say that before I found this solution I spend a lot of time googling frustrated as all examples were just talking about sending parameters in the URI (come on, the common scenario is to send XML and you can't do that properly in the URI). And when finally I found the right code examples it came up that it wasn't enough in WCF as I got the error "400 Bad Request". This error was caused by the fact that WCF can't use my raw XML if I don't force it by overriding it with some custom code (come on, what were you thinking Microsoft?, fix this in the next version of .NET Framework). So I'm not satisfied at all if doing such a basic thing can be so hard and time consuming).

** IMyRESTService.cs (server-side code) **

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

** client-side code **

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 (server-side custom code which forces WCF to accept raw XML) **

public class XmlContentTypeMapper : WebContentTypeMapper
{
public override WebContentFormat GetMessageFormatForContentType(string contentType)
{
return WebContentFormat.Raw;
}
}

** Web.config (server-side configuration settings for utilizing the custom code)

<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>

Invoke a WCF Web Service with an HTTP POST
http://social.msdn.microsoft.com/forums/en-us/wcf/thread/4074F4C5-16CC-470C-9546-A6FB79C998FC

嗼ふ静 2024-09-19 20:56:25

我遇到了同样的问题,并且使用 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。

I had the same problem, and using Fiddler, I received a 403 (Bad Request) error every time I tried to post using the Body. The Fix, which took me a couple of hours to find is to change the Content Type to application/xml and send the body as an Xml.

This is the line I used in the Header in Fiddler:

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

Now I haven't used Microsoft.Http library, in my client I used WebRequest to do the post, and by setting the Content-Type to:

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

Worked fine for me.

Now if you want to use the URI to send parameters I recommend using WebGet instead of WebInvoke with POST.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文