简体   繁体   English

ASP.Net MVC:图像上传不起作用

[英]ASP.Net MVC: Image upload does not work

I'm new to ASP.Net (and webdev in general) and I'm trying to implement a site offering CV-like capabilities. 我是ASP.Net(和Webdev的新手)的新手,我正试图实现一个提供类似CV功能的站点。 One of such things would be to upload and view a CV photo of a person. 这样的事情之一就是上传和查看一个人的简历照片。 Using scaffolding and a code sample found at SO: Uploading/Displaying Images in MVC 4 I managed to get as far as coming up with the following code where the problematic part is enclosed with a larger body of space: 使用脚手架和在SO上找到的代码示例:在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>

which is the relevant part of the view responsible for uploading, while the method in the Controller CV that I want to handle the request goes like this: 这是负责上传的视图的相关部分,而我要处理请求的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();
    }

My problem is that the post never hits this method for some reason despite having specified both the Action and the Controller name and VS being capable of connecting the View to the Controller (at least it swipes to the appropriate one on the Go To Controller command). 我的问题是,尽管同时指定了ActionController名称,但该帖子出于某种原因却从未使用过此方法,并且VS能够将View连接到Controller (至少在“ Go To Controller命令上滑动至相应的View ) 。 I'm sure it's some rookie mistake, but I just can't seem to find the cause. 我敢肯定这是菜鸟犯的错误,但是我似乎找不到原因。

The code in your question does not show it, but the fact you have form controls before and after the <form> element suggest you have an outer <form> element and explains why your inner <form> dos not hit the FileUpload() method. 您问题中的代码没有显示它,但是实际上您在<form>元素之前和之后都具有表单控件,这表明您有一个外部<form>元素,并说明了为什么内部<form>不会点击FileUpload()方法。

Nested forms are invalid html and not supported. 嵌套表单是无效的html,不受支持。 There is no guarantee what the behavior will be in different browsers or versions, but most browsers generate the name/value pairs for the successful form controls of the inner form, but post it to the action attribute of the outer form. 无法保证在不同的浏览器或版本中行为会如何,但是大多数浏览器会为内部表单的成功表单控件生成名称/值对,但将其发布到外部表单的action属性。

Its not clear why you want to upload the file separately and it would mean that if a user entered data in the other form controls and submitted the inner form, all that would be lost. 目前尚不清楚为什么要单独上传文件,这意味着如果用户在其他表单控件中输入数据并提交内部表单,那么所有这些都将丢失。 It would be easier to remove the inner form and just post back the whole model including the file input to one controller method (by adding a HttpPostedFileBase file parameter to that method, or better, using a view model with a HttpPostedFileBase File property). 删除内部表单并只将包括文件输入在内的整个模型回发到一个控制器方法(通过向该方法添加HttpPostedFileBase file参数,或者最好使用带有HttpPostedFileBase File属性的视图模型)会更容易。 Note that the form will need the enctype = "multipart/form-data" attribute. 请注意,表单将需要enctype = "multipart/form-data"属性。

If you do want to upload it separately, then one option would be to use ajax to submit the file input to the controller using FormData so at least any data the user has already entered will not be lost. 如果确实要单独上传,则一种选择是使用Ajax使用FormData将文件输入提交到控制器,这样至少用户已经输入的任何数据都不会丢失。 Refer How to append whole set of model to formdata and obtain it in MVC for an example. 有关示例,请参见如何将整个模型集附加到formdata并在MVC中获取它 In your case, you would initialize a new instance of FormData and .append() the value of the file input to it. 在您的情况下,您将初始化一个FormData的新实例,并使用.append()作为输入文件的值。

As a side note, your @Html.LabelFor(model => model.Picture) does not create a label associated with the file input (you do not have a form control with id="Picture" ) 附带说明一下,您的@Html.LabelFor(model => model.Picture)不会创建与文件输入关联的标签(您没有带有id="Picture"的表单控件)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM