2014-10-28 5 views
0

이미지 업로드를위한 올바른 입력을 확인하기 위해 ValidateFileAttribute라는 파일이 있습니다. 이처럼 :ValidateFileAttribute가있는 이미지의 유효성 확인

public class ValidateFileAttribute : RequiredAttribute 
    { 

     public override bool IsValid(object value) 
     { 
      var file = value as HttpPostedFileBase; 
      if (file == null) 
      { 
       return false; 
      } 

      if (file.ContentLength > 1 * 1024 * 1024) 
      { 
       return false; 
      } 

      try 
      { 
       using (var img = Image.FromStream(file.InputStream)) 
       { 
        return img.RawFormat.Equals(ImageFormat.Jpeg); 
       } 
      } 
      catch { } 
      return false; 
     } 

    } 

을이 모델의 propertie입니다 :

[DisplayName("Image")] 
    [ValidateFile(ErrorMessage = "Please select a PNG image smaller than 1MB")] 
    public byte[] Image { get; set; } 

은이 제도이다 :

<div id="upload-choices"> 
        <div class="editor-label"> 
         @Html.LabelFor(m => m.Image) 

         @Html.ValidationMessageFor(model => model.Image) 
        </div> 
        <div class="editor-row"> 
         @Html.ValidationSummary(true) 
        </div> 
       </div> 

하지만 매번 내가 (이 PNG로되어있는 이미지를 업로드하려고 그리고 적은 1 메가 바이트) 나는이 오류가 발생합니다 :

var file = value as HttpPostedFileBase; 파일이 null입니다.

<div id="tabs-2"> 
    @using (Html.BeginForm("EditPhotos", "Account", FormMethod.Post, new { id = "form", enctype = "multipart/form-data" })) 
     { 
      @Html.AntiForgeryToken() 

      <div class="form-horizontal"> 
       <h4>Photos</h4> 
       <hr /> 

       @Html.HiddenFor(model => model.Id) 


       <div class="editor-label"> 
        @Html.LabelFor(model => model.DisplayItem) 
       </div> 
       <div class="editor-field"> 
        @Html.EditorFor(model => model.DisplayItem) 

       </div> 

       <div id="upload-choices"> 
        <div class="editor-label"> 
         @Html.LabelFor(m => m.Image) 

         @Html.ValidationMessageFor(model => model.Image) 
        </div> 
        <div class="editor-row"> 
         @Html.ValidationSummary(true) 
        </div> 
       </div> 

       <br /> 

       <div class="table-responsive"> 
        <table class="table"> 

         <tr> 
          <th><img width="200" height="150" src="@Url.Action("GetImage", "Account", new { id = Model.Id })"></th> 


         </tr> 
        </table> 
       </div> 

       <input type="file" name="file" class="filestyle" data-buttontext="Find file"> 



       <br /> 
       <div class="progress progress-striped"> 
        <div class="progress-bar progress-bar-success">0%</div> 
       </div> 

       <div id="status"></div> 


       <br /> 

       @*@Html.ActionLink("Upload photos", "Upload")*@ 
       <div class="pull-left"> 
        <div class="col-md-offset-0"> 
         <input type="submit" value="Save" accept="image/x-png, image/gif, image/jpeg" class="btn btn-default pull-left" /> 

        </div> 
       </div> 

      </div> 
     } 

     <br /><br /> 
     <div> 
      @Html.ActionLink("Back to List", "Index") 
     </div> 
    </div> 

이 액션의 방법 : PNG 파일을 선택하세요 "[ValidateFile (ErrorMessage가 =

[HttpPost] 
    public ActionResult EditPhotos(UserProfile userprofile, HttpPostedFileBase file) 
    { 
     if (file != null) 
     { 
      // extract only the fielname 
      var fileName = Path.GetFileName(file.FileName); 
      // store the file inside ~/App_Data/uploads folder 
      var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName); 
      file.SaveAs(path); 
      ModelState.Clear(); 
     } 

     if (ModelState.IsValid) 
     { 
      string username = User.Identity.Name; 
      // Get the userprofile 
      UserProfile user = db.userProfiles.FirstOrDefault(u => u.UserName.Equals(username)); 

      // Update fields 
      user.Image = new byte[file.ContentLength]; 
      file.InputStream.Read(user.Image, 0, file.ContentLength); 
      user.ImageMimeType = file.ContentType; 
      db.Entry(user).State = EntityState.Modified; 
      try 
      { 
       db.SaveChanges(); 
      } 
      catch (DbEntityValidationException e) 
      { 
       foreach (var eve in e.EntityValidationErrors) 
       { 
        Console.WriteLine("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:", 
         eve.Entry.Entity.GetType().Name, eve.Entry.State); 
        foreach (var ve in eve.ValidationErrors) 
        { 
         Console.WriteLine("- Property: \"{0}\", Error: \"{1}\"", 
          ve.PropertyName, ve.ErrorMessage); 
        } 
       } 
       throw; 
      } 
     } 
     return RedirectToAction("Edit", routeValues: new { controller = "Account", activetab = "tabs-2" }); 
    } 

및없이

이것이 전체보기 당신

감사 1MB보다 작은 이미지 ")] 이미지를 업로드 할 수 있습니다.

public override bool IsValid(object value) 
     { 
      var ImageProfile = value as byte[]; 
      if (ImageProfile == null) 
      { 
       return false; 
      } 

      if (ImageProfile.ContentLength > 1 * 1024 * 1024) 
      { 
       return false; 
      } 

      try 
      { 
       using (var img = Image.FromStream(ImageProfile.InputStream)) 
       { 
        return img.RawFormat.Equals(ImageFormat.Jpeg); 
       } 
      } 
      catch { } 
      return false; 
     } 

과 propertie :하지만 당연히 그것이 내가 이렇게 지금이 검증

함께하는

[DisplayName("ImageProfile")] 
     [ValidateFile(ErrorMessage = "Please select a PNG image smaller than 1MB")] 
     public byte[] ImageProfile { get; set; } 

두면,이 같은 지금이 :

public override bool IsValid(object value) 
     { 
      var ImageProfile = value as byte[]; 
      if (ImageProfile == null) 
      { 
       return false; 
      } 

      if (ImageProfile.Length > 1 * 1024 * 1024) 
      { 
       return false; 
      } 

      try 
      { 
       using (var binaryReader = new BinaryReader(HttpContext.Current.Request.Files[0].InputStream)) 
       { 
        //return img.RawFormat.Equals(ImageFormat.Jpeg); 
        ImageProfile = binaryReader.ReadBytes(HttpContext.Current.Request.Files[0].ContentLength); 
       } 
      } 
      catch { } 
      return false; 
     } 

하지만 ImageProfile은 여전히 ​​null입니까 ?? 어떻게 그렇게 될수 있니?

나는 이것이 변경하는 경우 :

[DisplayName("ImageProfile")] 
[ValidateFile(ErrorMessage = "Please select a PNG image smaller than 1MB")] 
public HttpPostedFileBase ImageProfile { get; set; } 

다음이 더 이상 작동하지 않습니다 :이 방법에

   user.ImageProfile = new byte[file.ContentLength]; 
      file.InputStream.Read(user.ImageProfile, 0, file.ContentLength); 

:

[HttpPost] 
     //[ValidateAntiForgeryToken] 
     public ActionResult EditPhotos(UserProfile userprofile, HttpPostedFileBase file) 
     { 
      if (file != null) 
      { 
       // extract only the fielname 
       var fileName = Path.GetFileName(file.FileName); 
       // store the file inside ~/App_Data/uploads folder 
       var path = Path.Combine(Server.MapPath(@"\\Images"), fileName); 
       file.SaveAs(path); 
       ModelState.Clear(); 
      } 

      if (ModelState.IsValid) 
      { 
       string username = User.Identity.Name; 
       // Get the userprofile 
       UserProfile user = db.userProfiles.FirstOrDefault(u => u.UserName.Equals(username)); 

       // Update fields 
       user.ImageProfile = new byte[file.ContentLength]; 
       file.InputStream.Read(user.ImageProfile, 0, file.ContentLength); 
       user.ImageMimeType = file.ContentType; 

       db.Entry(user).State = EntityState.Modified; 

       try 
       { 
        db.SaveChanges(); 
       } 
       catch (DbEntityValidationException e) 
       { 
        foreach (var eve in e.EntityValidationErrors) 
        { 
         Console.WriteLine("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:", 
          eve.Entry.Entity.GetType().Name, eve.Entry.State); 
         foreach (var ve in eve.ValidationErrors) 
         { 
          Console.WriteLine("- Property: \"{0}\", Error: \"{1}\"", 
           ve.PropertyName, ve.ErrorMessage); 
         } 
        } 
        throw; 
       }    

      } 

      return RedirectToAction("Edit", routeValues: new { controller = "Account", activetab = "tabs-2" }); 
     } 

이 :

공공 ActionResult GetImage (int id) { var image = db.userProfiles.Where (p => p.Id == id) .Select (img => img.ImageProfile) .FirstOrDefault();

 var stream = new MemoryStream(image.ToArray()); 

     return new FileStreamResult(stream, "image/jpeg"); 
    } 

하지만 여전히이 라인에 오류가 발생합니다 : var stream = new MemoryStream(image.ToArray());

+0

아마 실제로 f ile. 나는 폼 요소를 보지 못한다. 그러므로 당신이 올바르게하고 있는지 아닌지 말할 수 없다. 양식의 내용 유형은'multipart/form-data'이어야합니다. 코드를 디버그 했습니까? 속성의'value'는 실제로'null'입니까? –

+0

의견을 주셔서 감사합니다. 내 게시물을 업데이트했습니다. –

+0

모델의 속성이'byte []'이지만 유효성 검사기가 값을 'HttpPostedFileBase'로 캐스팅하려고 시도 할 때 값 유형을 지정할 수 없습니다 모델의 타입과 호환되도록, 즉, 유효성 검사기를 바꿔 바이트 배열로 작업하도록 변경하십시오. –

답변

2

but ImageProfile is still null?? How can that be?

내가 name="ImageProfile"으로보기에 입력 필드를 볼 수 없습니다. 따라서이 속성이 null 인 것이 정상입니다.그래서 당신은 그 고정하여 시작할 수 :

<input type="file" name="ImageProfile" class="filestyle" data-buttontext="Find file"> 

그런 다음 당신은 ASP.NET MVC 기본 모델 바인더는 HttpPostedFileBase 타입이 아닌 byte[]이 파일 입력을 변환하는 방법을 알고 있다는 것을 알고 있어야합니다.

은 그래서 당신이 당신의 뷰 모델에서 수정해야 다음 일이 될 것입니다 :

[DisplayName("ImageProfile")] 
[ValidateFile(ErrorMessage = "Please select a PNG image smaller than 1MB")] 
public HttpPostedFileBase ImageProfile { get; set; } 

분명히 유효성 검사 속성의 변화 반영이 제거 마지막으로

public override bool IsValid(object value) 
{ 
    var file = value as HttpPostedFileBase; 
    if (file == null) 
    { 
     return false; 
    } 

    if (file.ContentLength > 1 * 1024 * 1024) 
    { 
     return false; 
    } 

    try 
    { 
     using (var img = Image.FromStream(file.InputStream)) 
     { 
      return img.RawFormat.Equals(ImageFormat.Png); 
     } 
    } 
    catch { } 
    return false; 
} 

과 파일 인수를 더 이상 사용하지 않으므로 컨트롤러 작업에 더 이상 사용되지 않습니다.

[HttpPost] 
public ActionResult EditPhotos(UserProfile userprofile) 
{ 
    ... 
} 
+0

대린 감사합니다! 귀하의 answare. 위의 편집을 참조하십시오 –

+0

메서드에서 일부 오류가 발생합니다. 내 편집 게시글을 참조하십시오. –

+0

컨트롤러 작업은 실제 EntityFramework 모델이 아닌 뷰 모델을 매개 변수로 사용해야합니다. 뷰 모델은 HttpPostedFileBase를 사용해야하며 이것을 EF 모델의 바이트 []에 매핑하여 데이터베이스에 전달합니다. –