2017-07-19 28 views
0

我正在开发一个C#wpf应用程序,它具有登录到我的网站并下载文件的功能。这个网站的行为有一个授权属性。我需要2个cookie才能下载文件,第一个cookie用于登录,第二个cookie(成功登录后提供)用于下载文件。所以我提出了在我的httpwebrequest/httpwebresponse之后保留cookie的流程。我正在查看我的发布流程,因为这可能是问题所在。这是我的代码。C#:HttpWebRequest POST数据不工作

void externalloginanddownload() 
{ 
    string pageSource = string.Empty; 
    CookieContainer cookies = new CookieContainer(); 

    HttpWebRequest getrequest = (HttpWebRequest)WebRequest.Create("login uri"); 
    getrequest.CookieContainer = cookies; 
    getrequest.Method = "GET"; 
    getrequest.AllowAutoRedirect = false; 

    HttpWebResponse getresponse = (HttpWebResponse)getrequest.GetResponse(); 

    using (StreamReader sr = new StreamReader(getresponse.GetResponseStream())) 
    { 
     pageSource = sr.ReadToEnd(); 
    } 

    var values = new NameValueCollection 
    { 
       {"Username", "username"}, 
       {"Password", "password"}, 
     { "Remember me?","False"}, 
      }; 

    var parameters = new StringBuilder(); 

    foreach (string key in values.Keys) 
    { 
     parameters.AppendFormat("{0}={1}&", 
      HttpUtility.UrlEncode(key), 
      HttpUtility.UrlEncode(values[key])); 
    } 

    parameters.Length -= 1; 

    HttpWebRequest postrequest = (HttpWebRequest)WebRequest.Create("login uri"); 
    postrequest.CookieContainer = cookies; 
    postrequest.Method = "POST"; 

    using (var writer = new StreamWriter(postrequest.GetRequestStream())) 
    { 
     writer.Write(parameters.ToString()); 
    } 

    using (WebResponse response = postrequest.GetResponse()) // the error 500 occurs here 
    { 
     using (var streamReader = new StreamReader(response.GetResponseStream())) 
     { 
      string html = streamReader.ReadToEnd(); 

     } 
    } 
} 
+0

你还没有提到你有什么问题。它在哪里失败? –

+0

它无法通过POST方法获取httpwebrequest的响应。它给了我一个错误500. –

+0

和你为什么这样做?:parameters.Length - = 1; –

回答

1

当你得到WebResponse的,返回的饼干将在响应,而不是在请求(奇怪的是,即使你需要的CookieContainer的要求)。

您需要将响应对象中的Cookie添加到CookieContainer中,以便在下一个请求中发送。

一个简单的方法:

for(var cookie in getresponse.Cookies) 
    cookies.Add(cookie) 

由于响应饼干已经是饼干的容器,你可以这样做(可能有助于检查空的情况下,所有的cookies已经在那里)

if (response.Cookies != null) cookies.Add(response.Cookies) 

您也可能会遇到麻烦你的文章,你需要设置的ContentType和长度:

myWebRequest.ContentLength = parameters.Length; 
myWebRequest.AllowWriteStreamBuffering = true; 

如果您有任何多字节字符需要考虑,那么您可能必须通过在请求和stringbuilder上将编码设置为UTF-8并将字符串转换为字节并使用该长度来解决该问题。

另一个提示:如果没有用户代理,一些Web服务器代码会窒息。尝试:

myWebRequest.UserAgent = "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)"; 

以防万一您有任何多字节字符,这是更好地做到这一点:

var databytes = System.Text.Encoding.UTF8.GetBytes(parameters.ToString()); 
myWebRequest.ContentLength = databytes.Length; 
myWebRequest.ContentType = "application/x-www-form-urlencoded; charset=utf-8"; 
using (var stream = myWebRequest.GetRequestStream()) 
{ 
    stream.Write(databytes, 0, databytes.Length); 
} 
+0

响应*应该*只包括不在请求中的新cookie,所以在每次请求后都应该完成你想要的内容 –

+0

我不确定“application/x-www-form-urlencoded”是否意味着我传递给操作的值放在URL上? –

+0

“application/x-www-form-urlencoded”基本上意味着post参数被格式化为“key = value&key = value ...”,而不是json编码或其他类型。 –

0

在C#应用程序(服务器端Web API)启用C++异常和公共语言运行使用(Ctrl + Alt + E)实时异常什么是服务器端抛出异常。

首先你检查数据是否绑定正确。在你看到它是精确异常之后。内部服务器错误大多数情况下抛出的数据格式不正确,没有正确管理异常。