REST HttpWebRequest GetResponseStream()错误500

时间:2012-04-26 22:38:18

标签: c# web-services rest

我正在使用第三方开源服务器软件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 ** 我试图通过添加:

来消除401
request.PreAuthenticate = true;

但这并没有解决我的问题。

**更新2 ** 我已经能够通过使用以下代码手动设置标题来消除401:

byte[] authBytes = Encoding.UTF8.GetBytes("username:password".ToCharArray());
request.Headers["Authorization"] = "Basic " + Convert.ToBase64String(authBytes);

为了确保我手动将标题添加到Poster请求中,我没有收到500错误,而是我期待的数据。但是我仍然通过.NET实现收到500错误。

2 个答案:

答案 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。这应该可以解决问题。