2012-09-13 3 views
0

이 기사에서 내 솔루션을 기반으로합니다. http://dotnetslackers.com/articles/aspnet/ASP-NET-MVC-and-File-Uploads.aspxMVC 파일 업 로더가 null을 반환합니다.

그러나 사진을 업로드하려고하면 파일 이름 대신 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()); 
} 

보기에

+0

오늘 내 생일 이니, 그것이 올바른 대답입니다! 사실 내보기 모델의 그림 필드를 사용하여 제안한 것을 시도했습니다. 내 실수는 파일 매개 변수의 이름을 포함하는 클래스의 이름도 incude해야한다는 것을 고려하지 않았다는 것입니다. 귀찮게하지 않고 대신 솔루션을 사용하는 것이 훨씬 간단합니다! – arame3333

1

(당신이 모델 바인딩을 사용하여 이미지 데이터를 잡을 수 있다면 그래서, 대신 hrvm.SelectedEmployee.Picture의 hrvm.Picture에 위치했을)는 대신 다음을 사용 및 바인딩 기본 모델은 작동합니다 : SelectedEmployee.Photo를 가정 한 것입니다

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

유형 HttpPostedFileBase이다.

현재 작동하지 않는 이유는 기본 모델 바인더가 파일 입력의 이름이기 때문에 모델에서 직접 그림이라는 속성을 찾으려고하기 때문입니다. Picture는 SelectedEmployee의 속성이기 때문에 찾을 수 없습니다.

위의 내용으로 변경하면 게시 된 파일에 올바른 경로가있을 때 마크 업에 입력 한 파일의 올바른 ID와 이름이 생성됩니다. 즉, 기본 모델 바인더는 양식 게시 값과 속성간에 매핑 할 수 있습니다.

+0

나는 당신의 해결책을 시도하지는 않았지만 잘못 사용 된 매개 변수의 이름에 대해 좋은 지적을했습니다. – arame3333

관련 문제