System.IO.File.Exists(fpath)在Chrome和Firefox中返回false

时间:2012-02-15 14:27:48

标签: c# asp.net-mvc-3

我有以下代码在Internet Explorer中有效,但在Firefox和Google Chrome中无效。

public ActionResult LogoForm(HttpPostedFileBase file)
{
    if (file != null)
    {
        string fpath = file.FileName;
        if (System.IO.File.Exists(fpath))
        {
            // Logic comes here
        }
    }
}

在我看来,我有这个:

@using (Html.BeginForm("LogoForm", "LogoEditor", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    <text>Logo Image &nbsp;&nbsp;&nbsp;</text>
    <input type="file" name="file" id="file" /> <text> &nbsp; &nbsp; &nbsp;</text>
    <input type="submit" name="upload" value="Upload" />
}

如果Firefox和Chrome中有任何文件,则行'if(System.IO.File.Exists(fpath))'始终返回false!它找不到该文件。为什么这样?

5 个答案:

答案 0 :(得分:6)

file.FileName包含客户端计算机上的文件路径,而不包含在服务器上。您不应该在服务器上使用它。这在IE中工作的原因是因为IE恰好将文件的完整路径发送到服务器,并且因为您在同一台机器上运行客户端和服务器。出于安全原因,Chrome和FF永远不会发送文件路径。 IIRC他们向服务器发送虚拟路径,该路径不存在于任何地方。当您在IIS中部署应用程序并远程访问它时,这不适用于IE。

你永远不应该依赖file.FileName的路径部分。您应该只提取文件名,然后将其连接到服务器上的路径

例如

[HttpPost]
public ActionResult LogoForm(HttpPostedFileBase file)
{
    if (file != null)
    {
        string path = Path.GetFileName(file.FileName);
        string fileName = Path.Combine(Server.MapPath("~/App_Data"), path);
        if (File.Exists(fileName))
        { 
            // logic comes here
        }
    }
}

我还建议您查看有关在ASP.NET MVC中上传文件的following blog post

答案 1 :(得分:2)

当你说它在Chrome和Firefox中返回false时 - 当然不是执行代码的浏览器。它是服务器执行代码以响应请求。

据推测,他们以不同的格式向IE提供文件名。您应该记录file.FileName的内容,这样可以更清楚地了解正在发生的事情。看到你只是采用浏览器发布的完全文件名,这有点令人担忧 - 在相对文件名的情况下,它可能与您想要的目录无关,而在绝对情况下您正在比较客户端计算机上存在的文件是否存在于服务器上的相同位置的文件名 - 这也不是一个好主意。

编辑:听起来您对该文件是否真的存在于客户端计算机上感兴趣。两点:

  • 您无法分辨,File.Exists 当然不是正确的检查。这是在服务器上运行的,它无法访问客户端的文件系统,谢天谢地。
  • 你不应该在乎。也许客户端并不真正拥有本地文件系统 - 也许它是从某些云存储模拟它,或类似的东西。您并不打算关心这一点:您已收到一些请求,其中包含有关“文件上传”的信息以及 您应该关注的内容。

答案 2 :(得分:1)

Internet Explorer发布原始文件名,包括type =“file”输入控件的路径,而其他浏览器只发送文件名。

由于浏览器通常不在服务器上运行,为什么要检查服务器上是否存在完整的文件名?

答案 3 :(得分:1)

不要尝试使用发送到控制器的路径(如其他人所提到的,仅由Internet Explorer本地支持),请尝试以下操作:

if (file != null && file.ContentLength > 0) 
{
    // The fielname
    var fileName = Path.GetFileName(file.FileName);

    // Store the file inside ~/App_Data/uploads folder for example
    var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);

     // Other stuff    
}

答案 4 :(得分:1)

只是添加人们已经说过的内容,如果用户已将文件添加到文件输入控件,它必须存在于客户端的某个计算机上,因为他们已将其添加到表单中在网站上。

一旦他们点击了提交,HttpPostedFileBase输入流属性就会包含文件的字节,简单地给出文件名,以便您知道上传文件的名称。正如其他人建议使用Path.GetFilename(string)来仅检索没有目录路径的文件名(如果提供)并将其保存到您的服务器。通常,我会在文件中添加某种时间戳,以便不覆盖以前的上传