【问题标题】:c# multipart/form-data submit programmaticallyc# multipart/form-data 以编程方式提交
【发布时间】:2019-01-04 22:00:52
【问题描述】:

所以遇到了一个小问题。我正在创建一个小型应用程序来自动在一个网站上提交表单。但不好的是,他们为此使用了 multipart/form-data。 没有文件上传只是一些文本字段供提交。

当然这样做会失败。

string postData1 = "firstfield="+firststring+"secondfield="+secondstring;

所以我的问题是如何用多部分表单发布这些表单字段?

像这样在 php 中发布类似数组:

$postdata = array('firstfield' => $firststring, 'secondfield' => $secondstring);

工作并通过表单,但似乎不适用于 c#

有什么建议吗?


数据提交通过 3 页(基本屏幕截图)登录/part1/part2

到目前为止,我可以成功登录并发布第 1 部分(使用普通应用程序/x-www-form-urlencoded 表单)

但是,当我尝试发布多部分表单时,它会失败并将我送回第 1 部分。所以也许我的代码错了,但这里是:

string password = "password";
string username = "username";
string link = "http://somelink.com/";
string text = "Blah Blah some text here";
string title = "Blah Blah";
string tags1 = title;
string summary = "Blah Blah summary";
string tags = tags1.Replace(" ", ",");

// Set cookie container
CookieContainer cookieJar = new CookieContainer();

string loginData = "username=" + username + "&password=" + password + "&processlogin=1&return=%2Fsubmit.php";

HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create("http://loginlink.com/login.php");
myRequest.Method = "POST";
        myRequest.ServicePoint.Expect100Continue = false;
myRequest.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.4) Gecko/20091016 Firefox/3.5.4 GTB6 (.NET CLR 3.5.30729)";
myRequest.Timeout = 10000;
myRequest.ContentType = "application/x-www-form-urlencoded";
myRequest.ContentLength = loginData.Length;
myRequest.CookieContainer = cookieJar;
myRequest.KeepAlive = true;
myRequest.AllowAutoRedirect = true;

//Write post data to stream
StreamWriter myWriter = new StreamWriter(myRequest.GetRequestStream());
myWriter.Write(loginData);
myWriter.Close();

// Get the response.
HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();

// Open the stream using a StreamReader for easy access.
StreamReader myReader = new StreamReader(myResponse.GetResponseStream());
// Read the content.
string output = myReader.ReadToEnd();

// Clean up the streams and the response.
myReader.Close();
myResponse.Close();


Match matchkey = Regex.Match(output, "type=\"hidden\" name=\"randkey\" value=\"([^\"]+)\"", RegexOptions.IgnoreCase);
string key1 = matchkey.Groups[1].Value;
Match matchid = Regex.Match(output, "type=\"hidden\" name=\"id\" value=\"([^\"]+)\"", RegexOptions.IgnoreCase);
string id1 = matchid.Groups[1].Value;


string postData = "url=" + link + "&phase=1&randkey=" + key1 + "&id=" + id1;

HttpWebRequest myRequest2 = (HttpWebRequest)WebRequest.Create("http://submitpage1.com/submit.php");
myRequest2.Method = "POST";
myRequest2.ServicePoint.Expect100Continue = false;
myRequest2.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.4) Gecko/20091016 Firefox/3.5.4 GTB6 (.NET CLR 3.5.30729)";
myRequest2.Timeout = 10000;
myRequest2.ContentType = "application/x-www-form-urlencoded";
myRequest2.ContentLength = postData.Length;
myRequest2.CookieContainer = cookieJar;
myRequest2.KeepAlive = true;
myRequest2.AllowAutoRedirect = true;


//Write post data to stream
StreamWriter myWriter2 = new StreamWriter(myRequest2.GetRequestStream());
myWriter2.Write(postData);
myWriter2.Close();

// Get the response.
HttpWebResponse myResponse2 = (HttpWebResponse)myRequest2.GetResponse();

// Open the stream using a StreamReader for easy access.
StreamReader myReader2 = new StreamReader(myResponse2.GetResponseStream());
// Read the content.
string output1 = myReader2.ReadToEnd();

// Clean up the streams and the response.
myReader2.Close();
myResponse2.Close();

Match matchkey1 = Regex.Match(output1, "type=\"hidden\" name=\"randkey\" value=\"([^\"]+)\"", RegexOptions.IgnoreCase);
string key2 = matchkey1.Groups[1].Value;
Match matchid1 = Regex.Match(output1, "type=\"hidden\" name=\"randkey\" value=\"([^\"]+)\"", RegexOptions.IgnoreCase);
string id2 = matchid1.Groups[1].Value;

string boundary = "-----------------------------1721856231228";

// Build up the post
StringBuilder sb = new StringBuilder();
sb.Append("\r\n" + boundary + "\r\n");
sb.Append("Content-Disposition: form-data; name=\"title\"" + "\r\n");
sb.Append("\r\n");
sb.Append(title);
sb.Append("\r\n--" + boundary + "\r\n");
sb.Append("Content-Disposition: form-data; name=\"tags\"" + "\r\n");
sb.Append("\r\n");
sb.Append(tags);
sb.Append("\r\n--" + boundary + "\r\n");
sb.Append("Content-Disposition: form-data; name=\"bodytext\"" + "\r\n");
sb.Append("\r\n");
sb.Append(text);
sb.Append("\r\n--" + boundary + "\r\n");
sb.Append("Content-Disposition: form-data; name=\"summarycheckbox\"" + "\r\n");
sb.Append("\r\n");
sb.Append("on");
sb.Append("\r\n--" + boundary + "\r\n");
sb.Append("Content-Disposition: form-data; name=\"summarytext\"" + "\r\n");
sb.Append("\r\n");
sb.Append(summary);
sb.Append("\r\n--" + boundary + "\r\n");
sb.Append("Content-Disposition: form-data; name=\"remLen\"" + "\r\n");
sb.Append("\r\n");
sb.Append("125");
sb.Append("\r\n--" + boundary + "\r\n");
sb.Append("Content-Disposition: form-data; name=\"category\"" + "\r\n");
sb.Append("\r\n");
sb.Append("1");
sb.Append("\r\n--" + boundary + "\r\n");
sb.Append("Content-Disposition: form-data; name=\"trackback\"" + "\r\n");
sb.Append("\r\n");
sb.Append("");
sb.Append("\r\n--" + boundary + "\r\n");
sb.Append("Content-Disposition: form-data; name=\"url\"" + "\r\n");
sb.Append("\r\n");
sb.Append(link);
sb.Append("\r\n--" + boundary + "\r\n");
sb.Append("Content-Disposition: form-data; name=\"phase\"" + "\r\n");
sb.Append("\r\n");
sb.Append("2");
sb.Append("\r\n--" + boundary + "\r\n");
sb.Append("Content-Disposition: form-data; name=\"randkey\"" + "\r\n");
sb.Append("\r\n");
sb.Append(key2);
sb.Append("\r\n--" + boundary + "\r\n");
sb.Append("Content-Disposition: form-data; name=\"id\"" + "\r\n");
sb.Append("\r\n");
sb.Append(id2);
sb.Append("\r\n--" + boundary + "--" + "\r\n");

string postData1 = sb.ToString();

HttpWebRequest myRequest3 = (HttpWebRequest)WebRequest.Create("http://submitpage2.com/submit.php");
myRequest3.Method = "POST";
myRequest3.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.4) Gecko/20091016 Firefox/3.5.4 GTB6 (.NET CLR 3.5.30729)";
myRequest3.Timeout = 10000;
myRequest3.ServicePoint.Expect100Continue = false;
myRequest3.Referer = "http://bookmarkindo.com/submit.php";
myRequest3.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
myRequest3.ContentType = "multipart/form-data; boundary=" + boundary;
myRequest3.ContentLength = postData1.Length;
myRequest3.CookieContainer = cookieJar;
myRequest3.KeepAlive = true;
myRequest3.AllowAutoRedirect = true;

//Write out postdata
StreamWriter myWriter3 = new StreamWriter(myRequest3.GetRequestStream());
myWriter3.Write(postData1);
myWriter3.Close();

// Get the response.
HttpWebResponse myResponse3 = (HttpWebResponse)myRequest3.GetResponse();

// Open the stream using a StreamReader for easy access.
StreamReader myReader3 = new StreamReader(myResponse3.GetResponseStream());
// Read the content.
string output2 = myReader3.ReadToEnd();

// Clean up the streams and the response.
myReader3.Close();
myResponse3.Close();

欢迎所有建议

【问题讨论】:

    标签: c# multipartform-data


    【解决方案1】:

    posts os multipart/form-data 类型具有不同的结构,因为它们旨在传输数据而不仅仅是纯文本。

    格式如下:

    --[random number, a GUID is good here]
    Content-Disposition: form-data; name="[name of variable]"
    
    [actual value]
    --[random number, a GUID is good here]--
    

    使用 HTTPWebRequest,您可以创建具有该格式的请求。这是一个示例:

    string boundary = Guid.NewGuid().ToString();
    string header = string.Format("--{0}", boundary);
    string footer = string.Format("--{0}--", boundary);
    
    StringBuilder contents = new StringBuilder();
    contents.AppendLine(header);
    
    contents.AppendLine(header);
    contents.AppendLine(String.Format("Content-Disposition: form-data; name=\"{0}\"", "username"));
    contents.AppendLine();
    contents.AppendLine("your_username");
    
    contents.AppendLine(header);
    contents.AppendLine(String.Format("Content-Disposition: form-data; name=\"{0}\"", "password"));
    contents.AppendLine();
    contents.AppendLine("your_password");
    
    contents.AppendLine(footer);
    

    【讨论】:

      【解决方案2】:

      在 C# 中发送 multipart 表单数据的最佳方式显示在 sn-p 中,在这里您可以看到添加不同类型的内容就像将其添加到包装器 multipart 内容类型一样简单:

      var documentContent = new MultipartFormDataContent();
      documentContent.Add(new StringContent("AnalyticsPage.xlsx"), "title");
      documentContent.Add(new ByteArrayContent(File.ReadAllBytes("C:\\Users\\awasthi\\Downloads\\AnalyticsPage.xlsx")), "file", "AnalyticsPage.xlsx");
      

      然后只需进行 api 调用:

      using (var client = new HttpClient(new HttpClientHandler() { UseDefaultCredentials = true, CookieContainer = new CookieContainer() }))
      {
        response = client.PostAsync(documentAddApi, documentContent).Result;
        var responseContent = response.Content.ReadAsStringAsync().Result;
       }
      

      这里的期望是您正在调用的其余端点接受文件的“标题”字段和名为“文件”的文件的字节数组。

      【讨论】:

        【解决方案3】:

        这是一篇关于multipart form posts in C# 的文章,其中包含更多详细信息。这段代码最终被合并到RestSharp,这是一个可以用来生成请求的优秀库。

        【讨论】:

          【解决方案4】:

          multipart/form-data 请求的格式在此处概述:http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.2

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2017-09-20
            • 2016-04-02
            • 2013-10-21
            • 1970-01-01
            • 2021-01-07
            • 2011-04-22
            • 2019-11-15
            相关资源
            最近更新 更多