是什么在httpwebrequest期间导致.docx文件损坏? [英] What could be causing this corruption in .docx files during httpwebrequest?

查看:93
本文介绍了是什么在httpwebrequest期间导致.docx文件损坏?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 httpwebrequest 将带有其他表单数据的文件从MVC应用程序发布到经典ASP站点。

I am using httpwebrequest to post a file with some additional form data from an MVC app to a classic ASP site.

如果文件是.docx,则总是以损坏的形式到达。其他人似乎打开得很好,但是可能是他们的格式更灵活。

If the file is a .docx, it always arrives as corrupted. Others seem to open fine, but it could be that their formats are more flexible.

当我在Sublime Text中打开原始文件和损坏的文件时,我注意到损坏的文件缺少 0000 最后。当我手动替换此块时,文件将打开正常。

When I open the original and corrupted files in Sublime Text, I noticed that the corrupted file is missing a block of 0000 at the end. When I manually replace this block the file opens fine.

我在做错什么吗?在我的.NET代码中导致这种情况发生?还是问题更神秘?

Is there something I'm doing incorrectly in my .NET code that is causing this happen? Or is the problem more esoteric?

经典的ASP代码使用坚持使用AspUpload 接收文件。接收站点其他地方的许多地方都使用了此方法,以前从未引起任何问题。因此,我认为错误不存在于此。另外,这只是一个简单的电话,我看不出哪里出了问题!

The classic ASP code uses Persist's AspUpload to receive the file. This is used in numerous places elsewhere on the receiving site and has never caused any problems before. So I don't think the error lies there. Plus, it's just a simple call, and I can't see what there is to get wrong!

设置文件= Upload.Files( fileField)

我不知道如何开始进一步调试此问题。

I'm at a loss as to how to start debugging this problem further.

这是我用来发布文件的代码:

public async Task<string> TestFileSend()
{
    string result;

    var postToUrl = "https://www.mywebsite.com/receive-file.asp";

    Dictionary<string, string> extraData = new Dictionary<string, string>();
    extraData.Add("colour", "red");
    extraData.Add("name", "sandra");

    var filePath = "/path-to-file/file.docx";
    byte[] fileAsByteArray = File.ReadAllBytes(filePath);


    // setup data  to send
    var dataBoundry = "---------------------------9849436581144108930470211272";
    var dataBoundryAsBytes = Encoding.ASCII.GetBytes(Environment.NewLine + "--" + dataBoundry + Environment.NewLine);

    var startOfFileData = "--" + dataBoundry + Environment.NewLine +
        @"Content-Disposition: form-data; name=""fileField""; filename=""file.docx""" + Environment.NewLine;

    startOfFileData += @"Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document" + Environment.NewLine + Environment.NewLine;
    var startOfFileDataAsBytes = Encoding.UTF8.GetBytes(startOfFileData);
    var endOfRequest = "--" + dataBoundry + "--";
    byte[] endOfRequestAsBytes = Encoding.UTF8.GetBytes(endOfRequest);


    // perform request
    HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(postToUrl);
    httpWebRequest.ContentType = "multipart/form-data; boundary=" + dataBoundry;
    httpWebRequest.Method = "POST";
    using (var stream = await httpWebRequest.GetRequestStreamAsync())
    {
        foreach (KeyValuePair<string, string> item in extraData)
        {
            var dataItemBytes = DataItemAsBytes(item.Key, item.Value);
            stream.Write(dataBoundryAsBytes, 0, dataBoundryAsBytes.Length);
            stream.Write(dataItemBytes, 0, dataItemBytes.Length);
        }
        stream.Write(startOfFileDataAsBytes, 0, startOfFileDataAsBytes.Length);
        stream.Write(fileAsByteArray, 0, fileAsByteArray.Length);
        stream.Write(endOfRequestAsBytes, 0, endOfRequestAsBytes.Length);
    }
    try
    {
        using (WebResponse response = httpWebRequest.GetResponse())
        {
            HttpWebResponse httpResponse = (HttpWebResponse)response;
            using (Stream myData = response.GetResponseStream())
            using (var reader = new StreamReader(myData))
            {
                result = reader.ReadToEnd();
            }
        }
    }
    catch (WebException e)
    {
        result = e.Message;
    }

    return result;
}






问题已解决-这是经修订的工作代码

Jon一直在回答他。写入文件流后,我立即添加了他建议的行,现在它们传输没有任何问题。

Jon was bang on with his answer. I added the line he suggested immediately after writing the file stream and they now transfer without any problems.

public async Task<string> TestFileSend()
{
    string result;

    var postToUrl = "https://www.mywebsite.com/receive-file.asp";

    Dictionary<string, string> extraData = new Dictionary<string, string>();
    extraData.Add("colour", "red");
    extraData.Add("name", "sandra");

    var filePath = "/path-to-file/file.docx";
    byte[] fileAsByteArray = File.ReadAllBytes(filePath);


    // setup data  to send
    var dataBoundry = "---------------------------9849436581144108930470211272";
    var dataBoundryAsBytes = Encoding.ASCII.GetBytes(Environment.NewLine + "--" + dataBoundry + Environment.NewLine);

    var startOfFileData = "--" + dataBoundry + Environment.NewLine +
        @"Content-Disposition: form-data; name=""fileField""; filename=""file.docx""" + Environment.NewLine;

    startOfFileData += @"Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document" + Environment.NewLine + Environment.NewLine;
    var startOfFileDataAsBytes = Encoding.UTF8.GetBytes(startOfFileData);
    var endOfRequest = "--" + dataBoundry + "--";
    byte[] endOfRequestAsBytes = Encoding.UTF8.GetBytes(endOfRequest);


    // perform request
    HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(postToUrl);
    httpWebRequest.ContentType = "multipart/form-data; boundary=" + dataBoundry;
    httpWebRequest.Method = "POST";
    using (var stream = await httpWebRequest.GetRequestStreamAsync())
    {
        foreach (KeyValuePair<string, string> item in extraData)
        {
            var dataItemBytes = DataItemAsBytes(item.Key, item.Value);
            stream.Write(dataBoundryAsBytes, 0, dataBoundryAsBytes.Length);
            stream.Write(dataItemBytes, 0, dataItemBytes.Length);
        }
        stream.Write(startOfFileDataAsBytes, 0, startOfFileDataAsBytes.Length);
        stream.Write(fileAsByteArray, 0, fileAsByteArray.Length);
        // *** THIS ADDITIONAL LINE IS THE KEY 
        stream.Write(new byte[] { 45, 45 }, 0, 2);
        // ***
        stream.Write(endOfRequestAsBytes, 0, endOfRequestAsBytes.Length);
    }
    try
    {
        using (WebResponse response = httpWebRequest.GetResponse())
        {
            HttpWebResponse httpResponse = (HttpWebResponse)response;
            using (Stream myData = response.GetResponseStream())
            using (var reader = new StreamReader(myData))
            {
                result = reader.ReadToEnd();
            }
        }
    }
    catch (WebException e)
    {
        result = e.Message;
    }

    return result;
}


推荐答案

我最近玩过multipart / form-data,并注意到在最后的多部分边界的末尾有一个额外的- stackoverflow答案中有一个示例。我认为那是您丢失两个字节的地方。

I recently played about with multipart/form-data and noticed it has an extra –- on the end of the final multipart boundary. There is an example in this stackoverflow answer. I think that is where you are losing the two bytes.

如果这样,解决方案是向请求流中添加最后一个写入,即两个字节的45(ASCII-)字节。

If so the solution is to add a final write to the request stream of two bytes of 45 (ASCII -).

stream.Write(new byte[]{45, 45}, 0, 2);

我不确定,但这看起来很合适。希望对您有所帮助。

I can't be sure, but it looks like a good fit. Hope it helps.

这篇关于是什么在httpwebrequest期间导致.docx文件损坏?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆