我正在使用第三方开源服务器软件Bonitasoft的工作流引擎上的REST Web服务。这是在Apache上运行的。遗憾的是,该软件仅允许任何Web服务调用的POST方法。
为了测试通话的基础知识,我已经能够使用Firefox的海报加载项而不会出现问题。以下是实用程序中使用的请求信息:
使用此信息运行加载项后,我得到一个包含我正在查找的信息的响应。无论是在客户端还是在服务器上,都没有与呼叫相关的错误。这是通过Poster进行此调用时写入服务器日志的内容:
10.0.5.1 - username [26/Apr/2012:16:06:24 -0600] "POST /bonita-server-rest/API/queryDefinitionAPI/getLightProcesses HTTP/1.1" 200 981091
所有系统都去了!
现在,我正在尝试创建一个与此Poster实用程序相同的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 ** 我试图通过添加:
来消除401request.PreAuthenticate = true;
但这并没有解决我的问题。
**更新2 ** 我已经能够通过使用以下代码手动设置标题来消除401:
byte[] authBytes = Encoding.UTF8.GetBytes("username:password".ToCharArray());
request.Headers["Authorization"] = "Basic " + Convert.ToBase64String(authBytes);
为了确保我手动将标题添加到Poster请求中,我没有收到500错误,而是我期待的数据。但是我仍然通过.NET实现收到500错误。
答案 0 :(得分:2)
我已经解决了我的问题。
为了符合大部分文档,我回到了一个字节数组,用于我需要写出的正文数据。
// 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编码的。然后我将我的代码更改为不执行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);
}
看起来很简单,我不确定我是如何错过它的。感谢您对此的帮助。希望这会帮助那些人。
答案 1 :(得分:0)
假设请求在Web浏览器中正常工作,问题可能是auth信息传递给服务器的顺序。
将request.PreAuthenticate
设为true。这应该可以解决问题。