.net MVC3 HttpPostedFileBase首次上载时不提供数据,但随后会提供数据
问题的背景 编辑3 我可以证实,这似乎是在Chrome20再次工作。谢谢 TLDR更新 编辑2 在对这个问题进行了进一步的研究之后,Chrome19中似乎出现了一个bug。请看这里: 没有什么比最新的bug更好的了!:-) Firefox最新版本和IE8/9正常工作。Fiddler日志显示了相同的行为,主要区别在于第二次401授权检查没有发送乱码的表单有效负载,并且按照预期工作 这听起来像是一个测试用例,正在进行修复!所以,希望你们中的任何一个可能遇到这种情况的人,这会有所帮助 结束TLDR 我有一个控制器动作,只接收一个上传的文件,这是一个“事件”的CSV文件。在幕后,这个CSV被解析出来,转换成事件对象,数据在数据库中同步。作为结果输出,将提示用户下载Excel电子表格,其中包含每行发生的所有错误 在我的开发机器上,这一切都可以在本地正常工作。然而,一旦部署到开发环境中,我会得到不同的结果。第一次尝试上传文件的结果是,流是,我在这里寻找的单词是什么,不可读?它正确地报告了它的长度,但试图提取信息却一无所获。后续读取确实包含数据,所有操作都按预期进行 我会给你相关的代码图片。首先,简化了生成的HTML表单:.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
<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);