.net MVC3 HttpPostedFileBase首次上载时不提供数据,但随后会提供数据

.net MVC3 HttpPostedFileBase首次上载时不提供数据,但随后会提供数据,.net,asp.net-mvc,asp.net-mvc-3,httppostedfilebase,.net,Asp.net Mvc,Asp.net Mvc 3,Httppostedfilebase,问题的背景 编辑3 我可以证实,这似乎是在Chrome20再次工作。谢谢 TLDR更新 编辑2 在对这个问题进行了进一步的研究之后,Chrome19中似乎出现了一个bug。请看这里: 没有什么比最新的bug更好的了!:-) Firefox最新版本和IE8/9正常工作。Fiddler日志显示了相同的行为,主要区别在于第二次401授权检查没有发送乱码的表单有效负载,并且按照预期工作 这听起来像是一个测试用例,正在进行修复!所以,希望你们中的任何一个可能遇到这种情况的人,这会有所帮助 结束TLDR

问题的背景

编辑3 我可以证实,这似乎是在Chrome20再次工作。谢谢

TLDR更新

编辑2 在对这个问题进行了进一步的研究之后,Chrome19中似乎出现了一个bug。请看这里:

没有什么比最新的bug更好的了!:-)

Firefox最新版本和IE8/9正常工作。Fiddler日志显示了相同的行为,主要区别在于第二次401授权检查没有发送乱码的表单有效负载,并且按照预期工作

这听起来像是一个测试用例,正在进行修复!所以,希望你们中的任何一个可能遇到这种情况的人,这会有所帮助

结束TLDR

我有一个控制器动作,只接收一个上传的文件,这是一个“事件”的CSV文件。在幕后,这个CSV被解析出来,转换成事件对象,数据在数据库中同步。作为结果输出,将提示用户下载Excel电子表格,其中包含每行发生的所有错误

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

我会给你相关的代码图片。首先,简化了生成的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]
公共操作结果导入本地(HttpPostedFileBase上载文件)
{

如果(uploadFile==null | | uploadFile.ContentLength这只是一个尝试的想法。请注意,StreamReader有许多构造函数:


在某些构造函数中,它尝试自动检测编码(如果指定)如果检测不到,则返回到指定的值。使用的构造函数使用UTF-8编码。您可以将构造函数更改为自动检测编码,如果没有,则使用UTF-8。

我认为您需要检查在IIS文件夹/虚拟网站上上载文件的权限,如果文件位于不同的位置,则需要将其自身定向是。

好问题。我首先想到的是身份验证。两次未经授权,第三次授权是正常的。这就是NTLM的工作方式

如果需要在Chrome上运行,并且无法等待修复,我建议启用表单身份验证,将其重定向到同一域但位于另一个端口,具有windows身份验证的登录应用程序驻留在该端口。此应用程序设置表单cookie或不设置表单cookie,并将您发送回主应用程序。该过程在在此:

这样,您的NTLM只完成一次,然后您就有了一个cookie,因此NTLM不会与POST请求一起使用,并且一切都应该按预期工作


我想我会分享这个:)

作为后续行动,每个人,这似乎与严格使用Windows身份验证有关。Windows身份验证在网站上处于打开状态,而Anonymous处于关闭状态。启动Fiddler后,我看到标准的2个失败的401授权请求和NTLM。这就是问题发生的地方。在第一个失败的401授权请求中,我看到了与一起发布的表单正确的文件上载数据。在第二次失败的401授权请求中,表单数据被篡改。其大小正确,但数据不正确。我得到309KB(或任意大小)或者在notepad++中查看输出时使用NUL字符继续:我们在应用程序中有多个级别的授权,这取决于用户的身份,因此将应用程序更改为在服务帐户下运行也不是一个选项,至少我不认为是这样。有没有办法不必打开模拟和u使用服务帐户可以成功上传?+1用于记录良好的问题并保持所有内容的更新。我在您发布的代码中没有看到try catch。您是否尝试过查看错误?
[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);