MVC3 HttpPostedFileBase首次上传不提供数据,但后续操作

时间:2012-05-17 22:30:43

标签: .net asp.net-mvc asp.net-mvc-3 httppostedfilebase

问题的背景。

编辑3 我可以验证这似乎在Chrome 20中再次有效。谢谢!

TLDR更新

编辑2 在进一步捣乱后,这似乎是Chrome 19中的一个错误。请看这里:

http://groups.google.com/a/chromium.org/group/chromium-bugs/browse_thread/thread/15bc4992bcd4be1d/b905e8de20ee58fa?lnk=raot

没有什么比最新的错误! : - )

Firefox-latest和IE8 / 9按预期工作。 Fiddler日志显示相同的行为,主要区别在于第二次401授权检查不会发送格式有效负载乱码并且按预期工作。

这听起来像一个测试用例,并且正在修复!所以,希望对于那些可能遇到过这种情况的人来说,这会有所帮助!

END TLDR

我有一个控制器操作,只接受一个上传的文件,该文件是"事件"的CSV文件。在幕后,此CSV被解析出来,变成了事件对象,数据在数据库中同步。结果输出时,系统会提示用户下载一个Excel电子表格,其中包含发生的每一行的所有错误。

这在我的开发机器上本地工作正常。但是,一旦部署到DEV环境,我得到的结果会有所不同。上传文件的第一次尝试导致了流,我在这里寻找的单词是什么,不可读?它正确地报告了它的长度,但试图将信息拉出来却一无所获。后续读取确实有数据,一切都按预期工作。

我会告诉你相关的代码。首先,简化了HTML格式:

<form action="/Events/ImportLocal" enctype="multipart/form-data" method="post">

<input id="uploadFile" name="uploadFile" type="file" />
<input type="submit" value="Upload Events" />    

</form>

非常直接:

控制器行动(原谅这个烂摊子,我现在已经被黑客攻击了几个小时):

[HttpPost]
public ActionResult ImportLocal(HttpPostedFileBase uploadFile)
{
    if (uploadFile == null || uploadFile.ContentLength <= 0)
    {
        BaseLogger.Info("uploadFile is null or content length is zero...");
        //Error content returned to user
    }

    BaseLogger.InfoFormat("Community Import File Information: Content Length: {0}, Content Type: {1}, File Name: {2}",
    uploadFile.ContentLength, uploadFile.ContentType, uploadFile.FileName);

//This logger line is always reporting as correct. Even on the attempts where I can't pull out the stream data, I'm seeing valid values here.
//EXAMPLE output on failed attempts:
//Import File Information: Content Length: 315293, Content Type: application/vnd.ms-excel, File Name: Export_4-30-2012.csv

    BaseLogger.InfoFormat("Upload File Input Stream Length: {0}", uploadFile.InputStream.Length);           
//This is reporting the correct length on failed attempts as well


//I know the below is overly complicated and convoluted but I'm at a loss for why the inputstream in HttpPostedFileBase is not pulling out as expected
//so I've been testing
        var target = new MemoryStream();
        uploadFile.InputStream.CopyTo(target);
        byte[] data = target.ToArray();
        BaseLogger.InfoFormat("File stream resulting length = {0}", data.Length);
//This reports correctly. So far so good.

        StringReader stringOut;
        var stream = new MemoryStream(data) {Position = 0};

        using (var reader = new StreamReader(stream))
        {
            string output = reader.ReadToEnd();
            BaseLogger.InfoFormat("Byte[] converted to string = {0}", output);
//No go...output is reported to be empty at this point so no data ever gets sent on to the service call below
            stringOut = new StringReader(output);
        }


        //Build up a collection of CommunityEvent objects from the CSV file
        ImportActionResult<Event> importActionResults = _eventImportServices.Import(stringOut);

目标是将文本阅读器或字符串阅读器传递给服务方法,因为它使用的是需要这些类型的CSV处理实现。

为什么第一个请求失败但后续工作的任何想法?我觉得自己需要一双新鲜的眼睛,因为我对想法不屑一顾。

最后一点,IIS 7.5是本地通过IIS Express和目标服务器上的目标。

由于

编辑获得赏金:

我在这里复制我的赏金信息和每个请求的Fiddler输出

我在这个问题上添加了一些评论。该问题似乎与NTLM有关。我在Fiddler看到的是401 Unauthorized on request 1 with valid form data(点,我的理解是前两个401 Unauthorized请求是&#34; normal&#34;在只有Windows身份验证的情况下;请确认?)。列出的请求2再次是具有相同表单数据的401,除了上传的文件数据现在只是一堆框,完全相同大小的数据,而不是确切的上传数据。请求3是200 OK,包含乱码数据,这就是我的控制器操作。如何让NTLM在文件上传方面发挥出色?

这是每个请求的Fiddler输出:

要求1) enter image description here

要求2) enter image description here

最后请求3即已处理的HTTP 200 OK enter image description here

编辑2 在进一步捣乱后,这似乎是Chrome 19中的一个错误。请看这里:

http://groups.google.com/a/chromium.org/group/chromium-bugs/browse_thread/thread/15bc4992bcd4be1d/b905e8de20ee58fa?lnk=raot

没有什么比最新的错误! : - )

Firefox-latest和IE8 / 9按预期工作。 Fiddler日志显示相同的行为,主要区别在于第二次401授权检查不会发送格式有效负载乱码并且按预期工作。

这听起来像一个测试用例,并且正在修复!所以,希望对于那些可能遇到过这种情况的人来说,这会有所帮助!

由于

3 个答案:

答案 0 :(得分:1)

这只是一个尝试的想法。请注意,StreamReader有许多构造函数:

http://msdn.microsoft.com/en-us/library/system.io.streamreader.aspx

在某些构造函数中,它尝试自动检测编码(如果指定),如果它无法检测到,则它会回退到指定的编码。使用的构造函数使用UTF-8编码。您可以更改构造函数以自动检测编码,如果不是,则使用UTF-8。

答案 1 :(得分:1)

我认为您需要检查上传文件的IIS文件夹/虚拟网站的权限,如果它们位于最不适合的地方,则需要检查dir本身。

答案 2 :(得分:1)

好问题。认证是我想到的第一件事。获得两个未经授权的和第三个授权是正常的。这就是NTLM的工作方式。

如果需要让它在Chrome上运行并且不能等待修复,我建议启用Forms身份验证,重定向到同一个域,但在不同的端口上,其中带有Windows身份验证的LOGIN应用程序驻留在其中。此应用程序是否设置表单cookie,并将您发送回主应用程序。这个过程在这里有详细描述:http://msdn.microsoft.com/en-us/library/ms972958.aspx

这样,你的NTLM就完成了一次然后你就有了一个cookie,所以NTLM不会与你的POST请求一起使用,一切都应该按预期工作。

想到我会分享这个:)