我正在使用第三方开源服务器软件 Bonitasoft 的工作流引擎上的 REST Web 服务。这是在 Apache 上运行的。不幸的是,该软件只允许对任何 Web 服务调用使用 POST 方法。
为了测试通话的基础知识,我可以毫无问题地使用 Firefox 的海报插件。以下是实用程序中使用的请求信息:
- 网址: http://internalserver/bonita-server-rest/API/queryDefinitionAPI/getLightProcesses
- 用户验证:用户名、密码
- 内容类型: application/x-www-form-urlencoded
- 正文: options=user%3a100%2cpassword%3a100
使用此信息运行加载项后,我会收到包含我正在寻找的信息的响应。在客户端和服务器上都没有与调用相关的错误。这是通过海报进行此调用时写入服务器日志的内容:
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 错误。