C# HttpWebRequest 表单上传

标签 c# forms upload httpwebrequest

我正在尝试从我的 C# 程序自动上传文件。这是上传文件的方法。

public static string UploadFileEx(string uploadfile, string url,
                            string fileFormName, string contenttype, NameValueCollection querystring,
                            CookieContainer cookies)
    {
        if ((fileFormName == null) ||
            (fileFormName.Length == 0))
        {
            fileFormName = "file";
        }

        if ((contenttype == null) ||
            (contenttype.Length == 0))
        {
            contenttype = "application/octet-stream";
        }


        string postdata;
        postdata = "";
        if (querystring != null)
        {
            foreach (string key in querystring.Keys)
            {
                postdata += key + "=" + querystring.Get(key) + "&";
            }
        }
        Uri uri = new Uri(url + postdata);

        string boundary = "----------" + DateTime.Now.Ticks.ToString("x");
        HttpWebRequest webrequest = (HttpWebRequest)WebRequest.Create(uri);

        var sp = webrequest.ServicePoint;
        var prop = sp.GetType().GetProperty("HttpBehaviour", BindingFlags.Instance | BindingFlags.NonPublic);
        prop.SetValue(sp, (byte)0, null);

        webrequest.CookieContainer = cookies;
        webrequest.ContentType = "multipart/form-data; boundary=" + boundary;
        webrequest.Method = "POST";

        webrequest.KeepAlive = true;
        webrequest.Referer = "http://www.iwi.hs-karlsruhe.de/scs/simulate/upload.jsp";
        webrequest.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
        webrequest.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.220 Safari/535.1";
        webrequest.Headers.Add("Accept-Language:de-de,de;q=0.8,en-us;q=0.5,en;q=0.3");
        webrequest.Headers.Add("Accept-Encoding:gzip, deflate");
        webrequest.ProtocolVersion = HttpVersion.Version11;


        // Build up the post message header

        StringBuilder sb = new StringBuilder();
        sb.Append("--");
        sb.Append(boundary);
        sb.Append("\r\n");
        sb.Append("Content-Disposition: form-data; name=\"");
        sb.Append(fileFormName);
        sb.Append("\"; filename=\"");
        sb.Append(Path.GetFileName(uploadfile));
        sb.Append("\"");
        sb.Append("\r\n");
        sb.Append("Content-Type: ");
        sb.Append(contenttype);
        sb.Append("\r\n");
        sb.Append("\r\n");

        string postHeader = sb.ToString();
        byte[] postHeaderBytes = Encoding.UTF8.GetBytes(postHeader);

        // Build the trailing boundary string as a byte array

        // ensuring the boundary appears on a line by itself

        byte[] boundaryBytes =
               Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n");

        FileStream fileStream = new FileStream(uploadfile,
                                    FileMode.Open, FileAccess.Read);
        long length = postHeaderBytes.Length + fileStream.Length +
                                               boundaryBytes.Length;
        webrequest.ContentLength = length;

        Stream requestStream = webrequest.GetRequestStream();

        // Write out our post header

        requestStream.Write(postHeaderBytes, 0, postHeaderBytes.Length);

        // Write out the file contents

        byte[] buffer = new Byte[checked((uint)Math.Min(4096,
                                 (int)fileStream.Length))];
        int bytesRead = 0;
        while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
            requestStream.Write(buffer, 0, bytesRead);

        // Write out the trailing boundary

        requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
        try
        {
            WebResponse responce = webrequest.GetResponse();
            Stream s = responce.GetResponseStream();
            StreamReader sr = new StreamReader(s);

            return sr.ReadToEnd();
        }
        catch (Exception ex)
        {
            return ex.Message;
        }

    }

当我在示例图片上传页面上这样调用它时,一切正常:

string outdata = UploadFileEx(uploadfile,
             "http://www.minpic.de/upload_file.php", "uploadfile0", "image/jpg",
             null, null);

但是当我尝试将它上传到我高中的页面时,它不起作用。上传页面由登录表单保护。所以我调用上传页面来获取 initail Cookie,然后我发布登录凭据并获得正确的结果。所以我可以看到以下上传表单:

<form action="../simulate" method=post enctype="multipart/form-data"><br />Choose your inputdata file (xml).<br /><input type=file size=50 maxlength=100000 name="Datei" accept="text/xml"><br><br><input type=submit value="Send"></form>

然后当我发布图像时(我知道预期的类型是 xml 但页面会回答我在这种情况下想要的错误...)我的上传函数返回错误代码 500。这是 wireshark 对浏览器的说明帖子:

POST /scs/simulate HTTP/1.1 Host: some host Connection: keep-alive Content-Length: 3874 Cache-Control: max-age=0 Origin: same host User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.79 Safari/537.4 Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryP3Ti6rxYcN1ov7JD Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8 Referer: some url Accept-Encoding: gzip,deflate,sdch Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3 Cookie: SCS_COOKIE=Default=DE$$MarkePlaceLang=DE; JSESSIONID=B459541362241F66D9312AF157262D25

这里是来自 c# 的帖子:

POST same as above Content-Type: multipart/form-data; boundary=----------8cf828671b8365c Referer: some url Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.220 Safari/535.1 Accept-Language: de-de,de;q=0.8,en-us;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate Host: same host as above Cookie: JSESSIONID=FFE0B7530FFE6A3C8F15FD8A900865B0 Content-Length: 3847 Expect: 100-continue Connection: Keep-Alive

我能看到的唯一区别是 Expect: 100-continue ... 数据包大小有问题吗?

提前致谢。

最佳答案

您必须使用分段上传。这显示在您的浏览器帖子中:

   Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryP3Ti6rxYcN1ov7JD

举个例子: Upload files with HTTPWebrequest (multipart/form-data)

这是有道理的,因为通常图像大小可能会大于通常帖子的限制(2KB 或 4KB,我忘记了)。

关于C# HttpWebRequest 表单上传,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13101989/

相关文章:

c# - 如何在调整 PictureBox 大小时使矩形移动

c# - 使用C#从id集合中获取4个(或任意数量)随机唯一ID的最简单方法是什么?

c# - Debian 7 Linq To SQL 上的 Mono 字符串对象引用未设置为对象的实例

javascript - 为什么如果条件为真,Javascript window.location 无法重定向页面?

php - 如何在php中创建目录?

c# - Facebook C# SDK 获取用户accessToken

javascript - 我怎样才能让这个javascript表单验证DRYer?

delphi - 是否有针对 'lock' 表单设计(布局)的 Delphi 选项以防止意外更改?

javascript - 如何跟踪是否使用 javascript 选择了文件?

html - 如何查找网页上次更新的时间