2012-09-13 66 views
0

我基於本文的解決方案; http://dotnetslackers.com/articles/aspnet/ASP-NET-MVC-and-File-Uploads.aspxMVC文件上傳器返回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()); 
    } 

那麼我做錯了什麼?

回答

1

默認情況下,MVC3根據視圖中輸入元素的Name屬性執行模型綁定。

要獲取文件上傳數據,請使用HttpPostedFileBase類作爲您的ActionResult的參數並調用參數'file'。

[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)

+0

今天是我的生日,那是正確的答案!其實我試圖通過使用我的視圖模型中的圖片字段來進行建議。我的錯誤是,我沒有考慮到這將使文件參數的名稱也必須包含包含類的名稱。更簡單的是不要打擾,並使用您的解決方案! – arame3333

1

在您看來改用以下和默認的模型綁定應該工作:

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

這是假設SelectedEmployee.PhotoHttpPostedFileBase類型。

目前不工作的原因是,默認模型聯編程序將試圖直接在模型上查找名爲Picture的屬性,因爲這是您的文件輸入的名稱。它不會找到它,因爲Picture是SelectedEmployee的一個屬性。

將其更改爲我上面建議的內容會爲標記中的文件輸入生成正確的標識和名稱,以便在回傳時具有正確的路徑。這意味着默認模型聯編程序可以在表單帖子值和屬性之間進行映射。

+0

我沒有嘗試你的解決方案,但你對我用錯的參數名稱做了一個好點。 – arame3333