我正在第三方开源服务器软件Bonitasoft的工作流引擎上使用REST web服务。这是在Apache上运行的。不幸的是,这个软件只允许任何web服务调用的POST方法。
为了测试调用的基础知识,我已经能够使用Firefox的海报外接程序,而没有问题。以下是该实用程序中使用的请求信息:
在使用此信息运行外接程序之后,我将得到一个具有我正在寻找的信息的响应。在客户端和服务器上都没有与调用相关的错误。这是在通过海报进行此调用时写入服务器日志的内容:
10.0.5.1 - username [26/Apr/2012:16:06:24 -0600] "POST /bonita-server-rest/API/queryDefinitionAPI/getLightProcesses HTTP/1.1" 200 981091所有系统都启动!
现在,我正在尝试制作一个C#控制台应用程序,它将完成与这个海报实用程序相同的功能。下面是我正在使用的当前测试代码:
// Create the URI Address
var address = new Uri(url);
// Create the web request
var request = WebRequest.Create(address) as HttpWebRequest;
// Set type to POST
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.Credentials = new NetworkCredential("username", "password");
// Create the data we want to send
var data = HttpUtility.UrlEncode("options=user:100,password:100");
// Set the content length in the request headers
request.ContentLength = data;
// Write data
using (Stream postStream = request.GetRequestStream())
{
using (StreamWriter writeStream = new StreamWriter(postStream))
{
writeStream.Write(data);
}
}
// Get response
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
// Get the response stream
StreamReader reader = new StreamReader(response.GetResponseStream());
// Console application output
Console.WriteLine(reader.ReadToEnd());
} 当我运行应用程序时,它没有问题地进入GetResponse()方法,但是一旦调用该方法,我将得到以下错误(截断堆栈跟踪):
System.Net.WebException: The remote server returned an error: (500) Internal Server Error.下面是Apache编写的日志信息:
10.0.5.1 - - [26/Apr/2012:16:21:08 -0600] "POST /bonita-server-rest/API/queryDefinitionAPI/getLightProcesses HTTP/1.1" 401 1331172
10.0.5.1 - username [26/Apr/2012:16:21:08 -0600] "options%3duser%3a100%2cpassword%3a100POST /bonita-server-rest/API/queryDefinitionAPI/getLightProcesses HTTP/1.1" 500 1150384当然,第一个想法是,服务没有正常运行,但确定不是这样,因为独立的客户端可以在没有错误的情况下调用服务。我已经浏览了大量的文章和问题,但无法解决这个问题。在收到回应方面,我是否做错了什么?其他想法?
作为参考,我对Grails进行了完全相同的服务调用(叹息),并且没有收到任何错误。
**更新1 **我试图通过添加以下内容来删除401:
request.PreAuthenticate = true;但这并没有解决我的问题。
**更新2 **通过使用以下代码手动设置标头,可以删除401:
byte[] authBytes = Encoding.UTF8.GetBytes("username:password".ToCharArray());
request.Headers["Authorization"] = "Basic " + Convert.ToBase64String(authBytes);当然,我手动将标题添加到招贴画请求中,我没有收到500个错误,而是我所期望的数据。但是,我仍然通过.NET实现接收500个错误。
发布于 2012-04-27 19:29:16
我已经解决了我的问题。
为了与大部分文档保持一致,我移回了一个字节数组,用于我需要编写的正文数据。
// Create the data we want to send
var data = HttpUtility.UrlEncode("options=user:100,password:100");
// Create a byte array of the data we want to send
byte[] byteData = UTF8Encoding.UTF8.GetBytes(data);
// Set the content length in the request headers
request.ContentLength = byteData.Length;
// Write data
using (Stream postStream = request.GetRequestStream())
{
postStream.Write(data);
}这没有解决我的问题,但使我回到了共同的立场。然后,我查看了通过浏览器外接程序发送的头和正文,并反转了任何UTF8编码,发现内容不是在UTF8编码之前编码的。然后,我更改了代码,使其不执行URL编码,并且没有出现问题:
// Create the data we want to send
var data = "options=user:100,password:100";
// Create a byte array of the data we want to send
byte[] byteData = UTF8Encoding.UTF8.GetBytes(data);
// Set the content length in the request headers
request.ContentLength = byteData.Length;
// Write data
using (Stream postStream = request.GetRequestStream())
{
postStream.Write(data);
}它似乎如此简单,以至于我不知道我是如何错过它的。谢谢你在这方面的帮助。希望这能帮助到外面的一些人。
发布于 2012-04-27 02:45:31
假设请求在web浏览器中正常工作,问题很可能是向服务器传递auth信息的顺序。
将request.PreAuthenticate设置为true。这应该能解决问题。
https://stackoverflow.com/questions/10342398
复制相似问题