【问题标题】:ASP.Net MVC: Image upload does not workASP.Net MVC:图片上传不起作用
【发布时间】:2018-01-31 18:16:58
【问题描述】:

我是 ASP.Net(以及一般的 webdev)的新手,我正在尝试实现一个提供类似 CV 功能的网站。其中之一是上传和查看一个人的简历照片。使用脚手架和在SO: Uploading/Displaying Images in MVC 4 找到的代码示例,我设法提出了以下代码,其中有问题的部分被更大的空间包围:

<div class="form-horizontal">
<h4>Author</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@Html.HiddenFor(model => model.PersonID)
<div class="form-group">
    @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
    <div class="col-md-10">
        @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
        @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
    </div>
</div>
<div class="form-group">
    @Html.LabelFor(model => model.Picture, htmlAttributes: new { @class = "control-label col-md-2" })

    <div class="col-md-10">            
        @using (Html.BeginForm("FileUpload", "CV", FormMethod.Post, new { enctype = "multipart/form-data" }))
         {
             <input type="file" name="file" id="file" style="width: 100%;" />
             <br/>
             <input type="submit" value="Upload" class="submit" />
         }
    </div>

</div>
<div class="form-group">
    @Html.LabelFor(model => model.MobileNum, htmlAttributes: new { @class = "control-label col-md-2" })
    <div class="col-md-10">
        @Html.EditorFor(model => model.MobileNum, new { htmlAttributes = new { @class = "form-control" } })
        @Html.ValidationMessageFor(model => model.MobileNum, "", new { @class = "text-danger" })
    </div>
</div>

<div class="form-group">
    @Html.LabelFor(model => model.Location, htmlAttributes: new { @class = "control-label col-md-2" })
    <div class="col-md-10">
        @Html.EditorFor(model => model.Location, new { htmlAttributes = new { @class = "form-control" } })
        @Html.ValidationMessageFor(model => model.Location, "", new { @class = "text-danger" })
    </div>
</div>

<div class="form-group">
    @Html.LabelFor(model => model.LinkedIn, htmlAttributes: new { @class = "control-label col-md-2" })
    <div class="col-md-10">
        @Html.EditorFor(model => model.LinkedIn, new { htmlAttributes = new { @class = "form-control" } })
        @Html.ValidationMessageFor(model => model.LinkedIn, "", new { @class = "text-danger" })
    </div>
</div>

这是负责上传的视图的相关部分,而我要处理请求的Controller CV 中的方法是这样的:

    [HttpPost]
    public ActionResult FileUpload(HttpPostedFileBase file)
    {
        if (file != null)
        {
            string pic = System.IO.Path.GetFileName(file.FileName);
            string path = System.IO.Path.Combine(
                                   Server.MapPath("~/Content/Images"), pic);
            // file is uploaded
            file.SaveAs(path);

            // save the image path path to the database or you can send image 
            // directly to database
            // in-case if you want to store byte[] ie. for DB
            using (MemoryStream ms = new MemoryStream())
            {
                file.InputStream.CopyTo(ms);
                byte[] array = ms.GetBuffer();
                //now I only have 1 mock author
                db.Authors.FirstOrDefault().Picture = array;
            }

        }
        // after successfully uploading redirect the user
        return View();
    }

我的问题是,尽管指定了 ActionController 名称,并且 VS 能够将 View 连接到 Controller,但由于某种原因,该帖子从未使用此方法(至少它会滑动到Go To Controller 命令上的相应命令)。我确定这是一些新手错误,但我似乎无法找到原因。

【问题讨论】:

  • 您显示的代码应该可以正常工作。你的 html 看起来很奇怪(在 &lt;div class="form-group"&gt; 中有一个 &lt;form&gt; 所以最好的猜测是你有嵌套的表单,它是无效的 html 并且不受支持
  • 谢谢,这是问题的根源。如果您可以将其转换为带有某种解释的答案,我很乐意接受它作为答案。
  • 您需要编辑问题以显示外部形式(否则答案将没有多大意义)
  • 我添加了更多代码

标签: c# asp.net-mvc


【解决方案1】:

您的问题中的代码没有显示它,但是您在 &lt;form&gt; 元素之前和之后有表单控件这一事实表明您有一个外部 &lt;form&gt; 元素并解释了为什么您的内部 &lt;form&gt; 没有命中 @ 987654327@方法。

嵌套表单是无效的 html,不受支持。无法保证在不同的浏览器或版本中会有什么行为,但是大多数浏览器都会为内部表单的成功表单控件生成名称/值对,但会将其发布到外部表单的action 属性中。

不清楚为什么要单独上传文件,这意味着如果用户在其他表单控件中输入数据并提交内部表单,所有这些都会丢失。删除内部表单并将整个模型(包括文件输入)回发到一个控制器方法会更容易(通过向该方法添加HttpPostedFileBase file 参数,或者更好的是,使用具有HttpPostedFileBase File 属性的视图模型) .请注意,表单需要enctype = "multipart/form-data" 属性。

如果您确实想单独上传它,那么一种选择是使用 ajax 使用 FormData 将文件输入提交给控制器,这样至少用户已经输入的任何数据都不会丢失。有关示例,请参阅 How to append whole set of model to formdata and obtain it in MVC 。在您的情况下,您将初始化 FormData.append() 的新实例,将其文件输入值。

附带说明,您的@Html.LabelFor(model =&gt; model.Picture) 不会创建与文件输入关联的标签(您没有id="Picture" 的表单控件)

【讨论】:

  • 是的,我的代码中有一个外部形式,但它更进一步,这就是我没有在此处包含它的原因。将图片与其他信息一起上传会很好,但我仍在研究如何理解 ASP 中的 Html Helper 类。如果您也能指导我找到一个好的连贯解决方案,我们将不胜感激。
  • 哪一点你不明白?除了我记下的标签之外,您显示的其余视图代码看起来都很好
  • 您应该做的是使用包含public HttpPostedFileBase File { get; set; } 属性的view model 并使用@Html.LabelFor(m =&gt; m.File) @Html.TextBoxFor(m =&gt; m.File, new { type="file" }),然后您还可以添加验证属性和@Html.ValidationMessageFor(m =&gt; m.File) - 例如@987654323 @ 或FileSizeAttribute
  • 不知道为什么你认为你需要这样做。您可以在一个操作中保存文件并保存数据(您是将文件保存到文件服务器并将路径和文件显示名称保存在数据库中,还是将文件保存在数据库中为byte[]? )
  • 我试图只将文件保存为字节[],我不一定需要路径。
猜你喜欢
  • 2018-05-02
  • 2016-06-24
  • 2013-06-23
  • 2014-06-21
  • 1970-01-01
  • 1970-01-01
  • 2010-10-05
相关资源
最近更新 更多