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

本文关键字:Chrome Firefox false 返回 File IO Exists fpath System | 更新日期: 2023-09-27 18:24:47

我有以下代码,可以在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!它找不到文件。为什么会这样?

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

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中上传文件的博客文章。

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

大概他们给IE的文件名是不同的格式。你应该记录file.FileName是什么,这应该会让它更清楚地发生了什么。看到你只是使用浏览器发布的确切的文件名,这有点令人担忧-如果是相对文件名,它可能与你想要的目录无关,在绝对文件名的情况下,您要比较客户端计算机上存在的文件是否存在于服务器的同一位置,这同样不是一个好主意。

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

  • 你无法判断,File.Exists当然不是正确的检查。它运行在服务器上,谢天谢地,该服务器无法访问客户端的文件系统
  • 你不应该在意。也许客户端实际上并没有本地文件系统——也许它是从一些云存储或类似的地方模拟它的。你不应该关心这一点:你收到了一个关于"文件上传"的信息请求,而这正是你应该关心的

为了补充人们已经说过的话,如果用户已经将文件添加到文件输入控件,那么它必须存在于客户端计算机的某个位置,因为他们已经将它添加到了网站上的表单中。

单击提交后,HttpPostedFileBase inputstream属性包含文件的字节数,只需给定文件名,就可以知道上传的文件名是什么。正如其他人建议的那样,使用Path.GetFilename(字符串)只检索文件名而不检索目录路径(如果提供),并将其保存到服务器。通常,我会在文件中添加一些时间戳,以避免覆盖以前上传的

InternetExplorer发布原始文件名,包括type="file"输入控件的路径,而其他浏览器只提供文件名。

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

与其尝试使用发送到控制器的路径(正如其他人所提到的,仅由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    
}