【问题标题】:Handling file upload from HTML form in ASP.net MVC 3 c#在 ASP.net MVC 3 c# 中处理从 HTML 表单上传的文件
【发布时间】:2026-01-25 06:00:02
【问题描述】:

我在 PHP 方面有丰富的经验,但对 ASP.net 还是很陌生。我在网上找到了一些教程,这些教程让我走到了这一步,但我目前遇到了问题。

总结一下我想要完成的工作,我有一个页面,我希望用户可以在其中提交参赛作品。我使用 HTML 表单来收集条目标题、描述等内容,并希望他们能够提交代表其条目的图像。

当他们选择提供图片时,我希望它使用如下路径上传: //条目//条目图像。

我的数据库将只保存一个表示图像路径的 varchar。我还想为文件上传添加一些明显的验证,例如限制文件大小,只允许某些文件扩展名。图像应使用标准名称(如上述路径中的“entry-image”)保存,覆盖该入口目录中可能已经存在的任何图像。

现在从我的 HTML 表单获取文本输入不是问题,但获取文件是。我目前还没有对表单进行验证,只是想让它在最基本的状态下工作。这是我的 HTML 的截断版本:

<form method="post" action="../Entry/Create">
            <input type="text" id="EntryTitle" name="EntryTitle" />
            <p id="char-remaining">(100 characters remaining)</p>

            <input type="text" id="EntryVideo" name="EntryVideo" />
            <p id="vid-desc">(URL of the Video to Embed)</p>

            <input type="file" id="ImageFile" name="ImageFile" />
            <p id="file-desc">(200x200px, jpeg, png, gif)</p>

            <textarea id="EntryDesc" name="EntryDesc"></textarea>
            <p id="entry-desc"></p>
            <button id="new-entry-save">save</button>
</form>

现在,这是我的 EntryController 类中的 Create 操作:

public ActionResult Create(string EntryTitle, string EntryVideo, HttpPostedFileBase ImageFile, string EntryDesc)
    {
        if (Session["User"] != null)
        {
            User currentUser = (User)Session["User"];

            //string savedFileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Path.GetFileName(ImageFile.FileName)); 
            //ImageFile.SaveAs(savedFileName);

            Entry newEntry = new Entry();

            newEntry.Title = EntryTitle;
            newEntry.EmbedURL = EntryVideo;
            newEntry.Description = EntryDesc;
            //newEntry.ImagePath = savedFileName;
            newEntry.UserId = currentUser.UserId;

            db.Entries.Add(newEntry);
            db.SaveChanges();


        }

        return RedirectToAction("MyPage", "User");
    }

你会注意到我有几行注释掉了。当被注释掉时,文本输入值被很好地接收并存储在我的数据库中。但是,如果不加注释,则会在第一个被注释掉的行上引发 NullReferenceException。

我在操作中使用的代码几乎只是从教程中复制和粘贴的,我意识到如果它确实有效,它就不会实现我上面写的目标,因为它不检查文件扩展名或将文件名更改为标准。

所以我的主要问题是:

1.) 当我实际上在 HTML 表单上提供文件时,为什么会收到 NullReferenceException?

2.) 我将如何验证提交的文件? (大小、扩展、尺寸等)

3.) 如何将文件名更改为“entry-image”之类的名称?

【问题讨论】:

  • &lt;form 标签中使用:enctype="multipart/form-data"
  • 在你上面的 Create 动作中,我想那是 ActionResult 的 [HttpPost] 版本?

标签: c# html asp.net-mvc-3 forms upload


【解决方案1】:

这是上面第 2 点的答案:

在您的提交操作上为该视图调用 JavaScript 函数

<input type="submit" id="thePageSubmit" value="Upload" onclick="return IsValidExtention();" /> 

然后在 Javascript 函数中执行类似的操作

    function IsValidExtention() {
        var it = document.forms[0].elements["ImageFile"].value;
        it = it.substring(it.lastIndexOf('\\') + 1);
        if (it.length > 0) {
            if (it.toLowerCase().indexOf(".exe")!=-1) {
                alert("We are unable to upload .exe files.");
                return false;
            }
            if (it.toLowerCase().indexOf(".js") != -1) {
                alert("We are unable to upload .js files.");
                return false;
            }
        }
        else{
            return false;
        } 
        return true;
    }

【讨论】:

  • 难道没有一种无需 javascript 的方式来处理我的操作中的所有这些以将所有内容集中在一个位置吗?如果 javascript 发现所有输入都是有效的,那么该操作将如何被调用?
  • 如果 Submit 控件在其 Onclick 事件上返回 true(即,表单已提交),则会自动调用该操作。你可以在你的控制器中处理这个。但是,如果扩展无效,您的页面必须发布到服务器,然后重定向回您的页面。有点糟糕的用户体验,IMO。
【解决方案2】:

如果还没有,请将enctype="multipart/form-data" 属性添加到您的表单元素。

【讨论】:

  • 好的,解决了我的第一个问题,不再抛出异常。