0

我的解决方案基于这篇文章; http://dotnetslackers.com/articles/aspnet/ASP-NET-MVC-and-File-Uploads.aspx

但是,当我尝试上传图片时,我得到的是 null 而不是文件名。

我的观点是这样的;

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<SHP.Models.HrViewModel>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    Edit Employee
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
    <fieldset>
    <legend>Add details to the selected employee</legend>
    <p>The photo you select for an employee will appear on MNet.</p>
    <p>The qualifications you add for an employee will appear on their business cards when required.</p>
        <% using (Html.BeginForm("EditEmployee", "HumanResources", FormMethod.Post,
         new{enctype = "multipart/form-data"}))
           {%>
        <%: Html.AntiForgeryToken() %>
        <%: Html.ValidationSummary(true) %>
        <%: Html.EditorFor(model => model.EmployeeSelector) %>
        <% if (Model.SelectedEmployee != null)
           { %>
                <%: Html.HiddenFor(model => model.SelectedEmployee.EmployeeId) %>
                <%: Html.HiddenFor(model => model.EmployeeName) %>
                <table class="groupBorder" style="margin-top:15px; width:617px;">
                <tbody>
                <tr>
                    <th colspan="2">Add Details for <%: Model.EmployeeName %></th>
                </tr>
                <tr>
                    <td style="text-align: right;">
                <%: Html.LabelFor(model => model.SelectedEmployee.Photo)%>
                   </td>                    
                    <td>
                        <input type="file" id="Picture" name="Picture" />
                    </td>
                </tr>
                <tr>
                    <td style="text-align: right;">
                <%: Html.LabelFor(model => model.SelectedEmployee.Qualifications)%>
                   </td>                    
                    <td>
                <%: Html.TextBoxFor(model => model.SelectedEmployee.Qualifications, new {style = "width:500px;"})%>
                    </td>
                </tr>
                <tr>
                    <td colspan="2" style="text-align: center;padding-top:20px;">
                    <input type="submit" value="Save" id="btnSubmit" /></td>
                </tr>
                </table>
       <% } %>
        <% } %>
        </fieldset>
</asp:Content>

当您单击“保存”按钮时,您将转到此控制器操作;

    [HttpPost]
    [Authorize(Roles = "Administrator, HumanResources, ManagerAccounts, ManagerIT")]
    [ValidateAntiForgeryToken]
    [ValidateOnlyIncomingValues]
    public ActionResult EditEmployee(HrViewModel hrvm)
    {
        if (ModelState.IsValid)
        {
            if (hrvm.SelectedEmployee == null
                || hrvm.EmployeeSelector.SearchTextId != hrvm.SelectedEmployee.EmployeeId)
            {
                return this.RedirectToAction(
                    "EditEmployee", new { employeeId = hrvm.EmployeeSelector.SearchTextId });
            }

            if (hrvm.SelectedEmployee.Picture.HasFile())
            {
                var destinationFolder = Server.MapPath("/Users");
                var postedFile = hrvm.SelectedEmployee.Picture;
                var fileName = Path.GetFileName(postedFile.FileName);
                var path = Path.Combine(destinationFolder, fileName);
                postedFile.SaveAs(path);
                hrvm.SelectedEmployee.Photo = path;
            }   

            var emp = Employee.GetEmployee(hrvm.SelectedEmployee.EmployeeId);
            this.TryUpdateModel<IEmployeeHrBindable>(emp, "SelectedEmployee");
            emp.Update();
            this.TempData["Message"] = string.Format(
                "At {0} Details updated for {1}", DateTime.Now.ToString("T"), hrvm.EmployeeName);
            return this.View(hrvm);
        }

        return this.View(new HrViewModel());
    }

那么我做错了什么?

4

2 回答 2

1

默认情况下,MVC3 根据视图中输入元素的 Name 属性执行模型绑定。

要获取文件上传数据,请使用 HttpPostedFileBase 类作为 ActionResult 的参数并调用参数“文件”。

[HttpPost]
[Authorize(Roles = "Administrator, HumanResources, ManagerAccounts, ManagerIT")]
[ValidateAntiForgeryToken]
[ValidateOnlyIncomingValues]
public ActionResult EditEmployee(HrViewModel hrvm, HttpPostedFileBase file)
{
    if (ModelState.IsValid)
    {
        if (hrvm.SelectedEmployee == null
            || hrvm.EmployeeSelector.SearchTextId != hrvm.SelectedEmployee.EmployeeId)
        {
            return this.RedirectToAction(
                "EditEmployee", new { employeeId = hrvm.EmployeeSelector.SearchTextId });
        }
        if (file.ContentLength > 0)
        {
            hrvm.SelectedEmployee.Picture = file;
            var destinationFolder = Server.MapPath("/Users");
            var postedFile = hrvm.SelectedEmployee.Picture;
            var fileName = Path.GetFileName(postedFile.FileName);
            var path = Path.Combine(destinationFolder, fileName);
            postedFile.SaveAs(path);
            hrvm.SelectedEmployee.Photo = path;
        }   

        var emp = Employee.GetEmployee(hrvm.SelectedEmployee.EmployeeId);
        this.TryUpdateModel<IEmployeeHrBindable>(emp, "SelectedEmployee");
        emp.Update();
        this.TempData["Message"] = string.Format(
            "At {0} Details updated for {1}", DateTime.Now.ToString("T"), hrvm.EmployeeName);
        return this.View(hrvm);
    }

    return this.View(new HrViewModel());
}

(因此,如果您可以使用模型绑定来获取图像数据,它将位于 hrvm.Picture 而不是 hrvm.SelectedEmployee.Picture)

于 2012-09-13T16:05:26.223 回答
1

在您的视图中,请改用以下内容,默认模型绑定应该可以工作:

<%: Html.TextBoxFor(model => model.SelectedEmployee.Photo, new { type = "file" }) %>

那是假设SelectedEmployee.Photo是 type HttpPostedFileBase

它目前不起作用的原因是默认模型绑定器将尝试直接在模型上查找名为 Picture 的属性,因为这是您的文件输入的名称。它不会找到它,因为 Picture 是 SelectedEmployee 的属性。

将其更改为我上面建议的内容会为标记中的文件输入生成正确的 id 和名称,因此在回发时具有正确的路径。这意味着默认模型绑定器能够在表单发布值和属性之间进行映射。

于 2012-09-13T16:47:47.793 回答