尝试使用摘要式身份验证与Web服务器(Apache 2.2.17)进行通信,并使用POST方法发送数据时,我遇到了问题:它总是返回401错误。但是,当我们不发布数据或Fiddler正在运行时(即使在发布数据时)它也能正常工作......您是否知道可能导致问题的原因?
public void DoRequest(string v_strURL, XmlDocument v_objXMLDoc)
{
var credentialCache = new CredentialCache();
credentialCache.Add(new Uri("http://" + ServerIP + "/"), "Digest", new NetworkCredential("admin", "test", "realm"));
String RequestContent = "request=" + v_objXMLDoc.InnerXml.Replace(' ', '+');
Uri Url = new Uri(v_strURL);
HttpWebRequest objHttpWebRequest;
HttpWebResponse objHttpWebResponse = null;
Stream objRequestStream = null;
byte[] bytes = new byte[0];
bytes = System.Text.Encoding.UTF8.GetBytes(RequestContent);
objHttpWebRequest = (HttpWebRequest)WebRequest.Create(v_strURL);
objHttpWebRequest.UserAgent = "MySampleCode";
objHttpWebRequest.Credentials = credentialCache;
objHttpWebRequest.Method = "POST";
objHttpWebRequest.ContentLength = bytes.Length;
objHttpWebRequest.ContentType = "text/xml; encoding='utf-8'";
objHttpWebRequest.ContentType = "application/x-www-form-urlencoded";
objRequestStream = objHttpWebRequest.GetRequestStream();
objRequestStream.Write(bytes, 0, bytes.Length);
objRequestStream.Close();
objHttpWebResponse = (HttpWebResponse)objHttpWebRequest.GetResponse();
}
答案 0 :(得分:2)
您是否有某种原因要将Content-Type标头设置两次?这不可能做你想做的事。另外,为什么要使用服务器IP而不是主机名将缓冲区放入缓存中?
HTTP / 401表明服务器正在挑战客户端的凭据。期望客户通过附加凭证重新提交请求来做出响应。一个关键问题是,在失败的情况下,客户端是否尝试发送凭据并被拒绝,或者根本没有尝试发送凭据?
如果Fiddler“神奇地”为您解决问题,您可能应该使用Netmon或Wireshark作为较低级别的外观。
答案 1 :(得分:1)
HttpWebRequest.Create()调用中的主机名(即v_strUrl)是否与调用credentialCache.Add()(即ServerIP)中的主机名相同?如果没有,那么这将永远失败。
只需将凭据直接添加到HttpWebRequest对象
,而不是使用CredentialCacherequest.Credentials = new NetworkCredential(“user”,“password”,“realm”);
看看是否有效。
答案 2 :(得分:0)
我们终于解决了这个问题:
objHttpWebRequest.ServicePoint.Expect100Continue = false;