首页 > 解决方案 > 尝试在 MVC 中上传图像文件时返回 null

问题描述

我正在尝试使用 MVC 上传照片,但它返回 null,我已经使用了 HttpPostedFileBase,但我仍然不知道为什么我没有得到文件。我看到他们在控制器操作结果中使用 HTTPPost 的 youtube 教程,但我的不同,我无法更新它。这是我的代码:

控制器:

public ActionResult CreateOrUpdateOperator(Operator_Profiles operator_Profiles) {
        string fileName = Path.GetFileNameWithoutExtension(operator_Profiles.ImageFile.FileName);
        string extension = Path.GetExtension(operator_Profiles.ImageFile.FileName);
        fileName = fileName + DateTime.Now.ToString("yymmssfff") + extension;
        operator_Profiles.OperatorPic = "../Content/assets/images/operators/" + fileName;
        fileName = Path.Combine(Server.MapPath("../Content/assets/images/operators/"), fileName);
        operator_Profiles.ImageFile.SaveAs(fileName);

        using (db) {
            if (operator_Profiles.OperatorID > 0) {
                db.Entry(operator_Profiles).State = System.Data.Entity.EntityState.Modified;
            } else {
                db.Operator_Profiles.Add(operator_Profiles);
            }
            db.SaveChanges();
            ModelState.Clear();
            return Json(true, JsonRequestBehavior.AllowGet);
        }
    }

模型:

public partial class Operator_Profiles
{
    public int OperatorID { get; set; }

    [DisplayName("Upload Operator Photo")]
    public string OperatorPic { get; set; }

    [NotMapped]
    public HttpPostedFileBase ImageFile { get; set; }

    public string Lastname { get; set; }

    public string Firstname { get; set; }

    public string Email { get; set; }

    [DisplayName("Phone Number")]
    public string PhoneNumber { get; set; }

    [DataType(DataType.Date, ErrorMessage = "Date only")]
    [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
    public Nullable<System.DateTime> Birthdate { get; set; }

    public string Gender { get; set; }

    public string Status { get; set; }
}

看法:

<form name="operatorForm" method="post" enctype="multipart/form-data">
@Html.AntiForgeryToken();
<div class="modal-header">
    <h4 class="modal-title">
        <span id="headertitle"></span>
    </h4>
    <button type="button" class="close" data-dismiss="modal" aria-label="Close" aria-hidden="true">&times;</button>
</div>
<div class="modal-body">
    @Html.HiddenFor(c => c.OperatorID)
    <div class="form-row mb-3">
        <div class="col-6">
            @Html.LabelFor(x => x.OperatorPic, htmlAttributes: new { @class = "control-label" })
            <input type="file" name="ImageFile" class="form-control-file" />
        </div>
    </div>
    <div class="form-row">
        <div class="col-md-6 col-sm-12 form-group">
            @Html.LabelFor(x => x.Lastname, htmlAttributes: new { @class = "control-label" })
            @Html.EditorFor(x => x.Lastname, new { htmlAttributes = new { @class = "form-control", required = true } })
            @Html.ValidationMessageFor(x => x.Lastname, "Invalid Lastname", new { @class = "invalid-feedback" })
        </div>
        <div class="col-md-6 col-sm-12 form-group">
            @Html.LabelFor(x => x.Firstname, htmlAttributes: new { @class = "control-label" })
            @Html.EditorFor(x => x.Firstname, new { htmlAttributes = new { @class = "form-control", required = true } })
            @Html.ValidationMessageFor(x => x.Firstname, "Invalid Firstname", new { @class = "invalid-feedback" })
        </div>
    </div>
    <div class="form-row">
        <div class="col-md-6 col-sm-12 form-group">
            @Html.LabelFor(x => x.Email, htmlAttributes: new { @class = "control-label" })
            @Html.EditorFor(x => x.Email, new { htmlAttributes = new { @class = "form-control", type = "email", required = true } })
            @Html.ValidationMessageFor(x => x.Email, "Invalid Email", new { @class = "invalid-feedback" })
        </div>
        <div class="col-md-6 col-sm-12 form-group">
            @Html.LabelFor(x => x.PhoneNumber, htmlAttributes: new { @class = "control-label" })
            @Html.EditorFor(x => x.PhoneNumber, new { htmlAttributes = new { @class = "form-control", type = "tel", required = true } })
            @Html.ValidationMessageFor(x => x.PhoneNumber, "Invalid Phone Number", new { @class = "invalid-feedback" })
        </div>
    </div>
    <div class="form-row">
        <div class="col form-group">
            @Html.LabelFor(x => x.Birthdate, htmlAttributes: new { @class = "control-label" })
            @Html.EditorFor(x => x.Birthdate, new { htmlAttributes = new { @class = "form-control", type = "date", required = true } })
            @Html.ValidationMessageFor(x => x.Birthdate, "Invalid Birthdate", new { @class = "invalid-feedback" })
        </div>
    </div>
    <div class="form-row">
        <div class="col form-group">
            @Html.LabelFor(x => x.Gender, htmlAttributes: new { @class = "control-label" })
            @{
                var genderList = new SelectList(new List<SelectListItem> { new SelectListItem { Text = "Male", Value = "Male" }, new SelectListItem { Text = "Female", Value = "Female" }, }, "Value", "Text");
            }
            @Html.DropDownListFor(x => x.Gender, genderList, "Select Gender", new { @class = "form-control", required = true })
            @Html.ValidationMessageFor(x => x.Gender, "Please choose a Gender", new { @class = "invalid-feedback" })
        </div>
    </div>
    <div class="form-row">
        <div class="col form-group">
            @Html.LabelFor(x => x.Status, htmlAttributes: new { @class = "control-label" })
            @{
                var statusList = new SelectList(new List<SelectListItem> { new SelectListItem { Text = "Clear", Value = "Clear" }, new SelectListItem { Text = "Suspended", Value = "Suspended" }, }, "Value", "Text");
            }
            @Html.DropDownListFor(x => x.Status, statusList, "Select Status", new { @class = "form-control", required = true })
            @Html.ValidationMessageFor(x => x.Status, "Invalid Status", new { @class = "invalid-feedback" })
        </div>
    </div>
</div>
<div class="modal-footer">
    <button type="button" class="btn btn-danger ml-auto" data-dismiss="modal">Cancel</button>
    <button type="submit" class="btn btn-success mr-auto" onclick="SaveOperatorProfile()">Submit</button>
</div>

JS:

function SaveOperatorProfile() {
var modal = $("#operatorModal");
var form = $('form[name = operatorForm]');
form.validate({
    errorClass: 'is-invalid',
    validClass: 'is-valid',
    highlight: function (element, errorClass, validClass) {
        $(element).removeClass(validClass).addClass(errorClass);
    },
    unhighlight: function (element, errorClass, validClass) {
        $(element).removeClass(errorClass).addClass(validClass);
    },
    errorPlacement: function () {
        // Done in highlight/unhighlight
    },
    submitHandler: function (form) {
        alert('Operator Profile has been successfuly saved.');
    }
});
if (!form.valid()) {
    return;
} else {
    var data = form.serialize();
    $.post("/Admin/CreateOrUpdateOperator", data, function (res) {
        if (res) {
            modal.modal('hide');
            OprTable.ajax.reload();
        }
    })
}

}

标签: c#asp.net-mvcfile-upload

解决方案


您没有从表单中获得 ActionResult 中的任何内容,因为您没有要求它。根据您的 HTML 输入,您的图像对象的“名称”是“ImageFile”。这需要在您的 POST 方法中匹配。例如,

[HttpPost]
public ActionResult CreateOrUpdateOperator(HttpPostedFileBase ImageFile, FormCollection col) {
    Operater_Profiles operater_Profiles = new Operator_Profiles();
    string myString1 = col["SomeName1"].ToString();
    string myString2 = col["SomeName2"].ToString();
}

参数的名称需要与 HTML 中的名称匹配。

编辑:

除了您的控制器之外,您还需要将其实际标记为 POST 方法,强烈推荐。为此,只需在方法声明之前添加属性 [HttpPost]。

您正在使用 jquery/js 也通过 ajax 方法发布。这不是您应该这样做的方式,因为您没有在此处进行任何动态页面加载。您应该充分利用 MVC 架构——为什么还要使用 ASP.NET 的 MVC?

而不是使用 jquery,您可以改为将输入更改为:

@using (Html.BeginForm("ACTIONNAME", "CONTROLLERNAME", null, FormMethod.Post, new { enctype = "multipart/form-data" })) {
    <input type="file" name="ImageFile" class="form-control-file" />
    @Html.LabelFor(x => x.Lastname, htmlAttributes: new { @class = "control-label", @name = "SomeName1" })
    @Html.LabelFor(x => x.Firstname, htmlAttributes: new { @class = "control-label", @name = "SomeName2" })
    @Html.LabelFor(x => x.Email, htmlAttributes: new { @class = "control-label", @name = "SomeName3" })

}

如您所见,我在您发布的数据中添加了名称。这些名称可以通过控制器中的 FormCollection 获取。


推荐阅读