C#上传文件错误 - 损坏的表单数据:没有前导边界

时间:2013-12-18 15:50:14

标签: c# httpwebrequest webclient multipartform-data httpwebresponse

我使用下面的代码验证并将文件上传到网站,但我收到错误“损坏的表单数据:没有前导边界”。

在小提琴手中,我看到了这一点,(当我使用浏览器上传文件时,我看到了完全相同的事情),不知道为什么我在收到错误时遇到错误我正在使用 C#HttpWebRequest / WebClient

提琴手信息:

------WebKitFormBoundary9ewWOMyBmk0YAhTL
Content-Disposition: form-data; name="FileSubmitted"; filename="SAMPLE_0001.xls"
Content-Type: application/vnd.ms-excel

------WebKitFormBoundary9ewWOMyBmk0YAhTL
Content-Disposition: form-data; name="FileSubmittedValue" 

C:\path\SAMPLE_0001.xls
------WebKitFormBoundary9ewWOMyBmk0YAhTL--

假设:

硬编码'边界'值,因为我不确定如何在登录后获取'boundary'值。

代码: 从Stackoverflow复制

static void Main()
{
    NameValueCollection nvCollection = new NameValueCollection();
    CookieAwareWebClient webClient = new CookieAwareWebClient();

    nvCollection.Clear();
    nvCollection["Name"] = "ABC";
    nvCollection["Password"] = "XYZ";
    //Login to the Site
    byte[] responseBytes = webClient.UploadValues("https://www.somesite.com/login.cfm", "POST", nvCollection);
    string resultAuthTicket = Encoding.UTF8.GetString(responseBytes);
    //Get Cookies
    CookieCollection cookies = webClient.CookieContainer.GetCookies(new Uri("https://www.somesite.com/login.cfm"));
    //
    string URL = "https://www.somesite.com/app/request.cfm";
    string boundary = "----WebKitFormBoundary9ewWOMyBmk0YAhTL";
    string FilePath = "C:\\Users\\user.name\\Desktop\\SAMPLE_0001.xls";
    byte[] fileData = GetMultipartFormData(new Dictionary<string, object>() { { "FileSubmitted", FilePath } }, boundary);
    PostForm(URL, "", "", fileData, boundary, cookies);
}
private static byte[] GetMultipartFormData(Dictionary<string, object> postParameters, string boundary)
{
    Encoding encoding = Encoding.UTF8;
    Stream formDataStream = new System.IO.MemoryStream();
    bool needsCLRF = false;
    foreach (var param in postParameters)
    {
        // Thanks to feedback from commenters, add a CRLF to allow multiple parameters to be added.
        // Skip it on the first parameter, add it to subsequent parameters.
        if (needsCLRF)
            formDataStream.Write(encoding.GetBytes("\r\n"), 0, encoding.GetByteCount("\r\n"));
        needsCLRF = true;
        {
            string postData = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\"\r\nContent-Type: {3}\r\n\r\n",
                boundary,
                param.Key,
                param.Value,
                "application/vnd.ms-excel");
            formDataStream.Write(encoding.GetBytes(postData), 0, encoding.GetByteCount(postData));
            string postData2 = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\" \r\n\r\n{2}",
                boundary,
                "FileSubmittedValue",
                "C:\\path\\SAMPLE_0001.xls");
            formDataStream.Write(encoding.GetBytes(postData2), 0, encoding.GetByteCount(postData2));
        }
    }
    // Add the end of the request.  Start with a newline
    string footer = "\r\n--" + boundary + "--\r\n";
    formDataStream.Write(encoding.GetBytes(footer), 0, encoding.GetByteCount(footer));
    // Dump the Stream into a byte[]
    formDataStream.Position = 0;
    byte[] formData = new byte[formDataStream.Length];
    formDataStream.Read(formData, 0, formData.Length);
    formDataStream.Close();
    return formData;
}   
private static HttpWebResponse PostForm(string postUrl, string userAgent, string contentType, byte[] formData, string boundary, CookieCollection cookies)
{
    HttpWebRequest request = WebRequest.Create(postUrl) as HttpWebRequest;
    if (request == null)
    {
        throw new NullReferenceException("request is not a http request");
    }
    // Set up the request properties.
    request.UserAgent = userAgent;
    request.ContentLength = formData.Length;
    request.ContentType = "multipart/form-data; boundary=" + boundary;
    request.Method = "POST";
    request.KeepAlive = true;
    request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";
    request.CookieContainer = new CookieContainer();
    request.CookieContainer.Add(cookies);
    request.Host = "secure.somesite.com";
    request.Referer = String.Format("https://secure.somesite.com/app/request.cfm?CFID={0}&CFTOKEN={1}", cookies[0].Value, cookies[1].Value);
    request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36";
    // Send the form data to the request.
    using (Stream requestStream = request.GetRequestStream())
    {
        requestStream.Write(formData, 0, formData.Length);
        requestStream.Close();
    }
    try
    {
        return request.GetResponse() as HttpWebResponse;
    }
    catch (WebException wex)
    {
        var pageContent = new StreamReader(wex.Response.GetResponseStream())
                              .ReadToEnd();
        return null;
    }
    return null;       
}

错误:

<head><title>JRun Servlet Error</title></head><h1>500 </h1><body>
<pre>
Corrupt form data: no leading boundary:  != ------WebKitFormBoundary9ewWOMyBmk0YAhTL</pre><br><pre>
java.io.IOException: Corrupt form data: no leading boundary:  != ------WebKitFormBoundary9ewWOMyBmk0YAhTL
    at com.oreilly.servlet.multipart.MultipartParser.&lt;init&gt;(MultipartParser.java:176)
    at com.oreilly.servlet.multipart.MultipartParser.&lt;init&gt;(MultipartParser.java:95)
    at coldfusion.filter.FormScope.fillMultipart(FormScope.java:170)
    at coldfusion.filter.FusionContext.SymTab_initForRequest(FusionContext.java:435)
    at coldfusion.filter.GlobalsFilter.invoke(GlobalsFilter.java:33)
    at coldfusion.filter.DatasourceFilter.invoke(DatasourceFilter.java:22)
    at coldfusion.filter.RequestThrottleFilter.invoke(RequestThrottleFilter.java:126)
    at coldfusion.CfmServlet.service(CfmServlet.java:175)
    at coldfusion.bootstrap.BootstrapServlet.service(BootstrapServlet.java:89)
    at jrun.servlet.FilterChain.doFilter(FilterChain.java:86)
    at coldfusion.monitor.event.MonitoringServletFilter.doFilter(MonitoringServletFilter.java:42)
    at coldfusion.bootstrap.BootstrapFilter.doFilter(BootstrapFilter.java:46)
    at jrun.servlet.FilterChain.doFilter(FilterChain.java:94)
    at jrun.servlet.FilterChain.service(FilterChain.java:101)
    at jrun.servlet.ServletInvoker.invoke(ServletInvoker.java:106)
    at jrun.servlet.JRunInvokerChain.invokeNext(JRunInvokerChain.java:42)
    at jrun.servlet.JRunRequestDispatcher.invoke(JRunRequestDispatcher.java:286)
    at jrun.servlet.ServletEngineService.dispatch(ServletEngineService.java:543)
    at jrun.servlet.jrpp.JRunProxyService.invokeRunnable(JRunProxyService.java:203)
    at jrunx.scheduler.ThreadPool$ThreadThrottle.invokeRunnable(ThreadPool.java:428)
    at jrunx.scheduler.WorkerThread.run(WorkerThread.java:66)
</pre></body>

不知道:由于我从Stackoverflow复制了这个源代码,我不知道该文件是否真的上传到服务器上的C:\ Path文件夹(查看Fiddler数据)

更新:当我尝试使用浏览器上传文件时,我看到内容长度:49504 ,但是当我尝试使用C#程序时内容长度:385 (即使我在浏览器和C#程序中都使用相同的文件)

另外,当我现在尝试时,我收到“上传的文件中没有收到数据SAMPLE_0001.xls

1 个答案:

答案 0 :(得分:0)

代码缺少这行代码,这是实际的文件内容。

formDataStream.Write(fileToUpload.File, 0, fileToUpload.File.Length); 

感谢大家的帮助!