2015-07-12 14 views
8

Próbuję przesłać plik przy użyciu kontrolki HTML FileUpload w MVC. Chcę zweryfikować plik, aby zaakceptować tylko określone rozszerzenia. Próbowałem użyć atrybutu FileExtensions przestrzeni nazw DataAnnotations, ale nie działa. Zobacz poniższy kod -Atrybut FileExtensions z DataAnnotations nie działa w MVC

public class FileUploadModel 
    { 
     [Required, FileExtensions(Extensions = (".xlsx,.xls"), ErrorMessage = "Please select an Excel file.")] 
     public HttpPostedFileBase File { get; set; } 
    } 

w sterowniku, piszę kod jak poniżej -

[HttpPost] 
     public ActionResult Index(FileUploadModel fileUploadModel) 
     { 
      if (ModelState.IsValid) 
       fileUploadModel.File.SaveAs(Path.Combine(Server.MapPath("~/UploadedFiles"), Path.GetFileName(fileUploadModel.File.FileName))); 

      return View(); 
     } 

na uwadze, pisałem poniżej kodu -

@using (Html.BeginForm("Index", "FileParse", FormMethod.Post, new { enctype = "multipart/form-data"})) 
{ 
    @Html.Label("Upload Student Excel:") 
    <input type="file" name="file" id="file"/> 
    <input type="submit" value="Import"/> 
    @Html.ValidationMessageFor(m => m.File) 
} 

gdy uruchomię aplikacji i podać nieprawidłowe rozszerzenie pliku, nie wyświetlając mi komunikatu o błędzie. Jestem świadomy rozwiązania, aby napisać niestandardowy atrybut sprawdzania poprawności, ale nie chcę używać niestandardowego atrybutu. Proszę wskazać, gdzie idę źle.

+0

mogą być pomocne: http://stackoverflow.com/questions/14718425/cant-get-mvc-4-fileextensions-attribute-to-work-on-viewmodel-property – serhiyb

+0

@serhiyb Dzięki za odpowiedź. Przeszedłem przez to rozwiązanie. Ale nie chcę używać niestandardowego atrybutu, chcę użyć atrybutu, który jest już dostarczany przez .NET. Czy robię coś złego, czy jest jakiś problem z atrybutem dostarczonym przez Microsoft? – DfrDkn

+0

Ponieważ atrybut FileExtensions działa poprawnie w MVC5 (właśnie testowałem) zakładam, że jest problem z nim w niższych wersjach. – serhiyb

Odpowiedz

2

Atrybut FileExtensions nie wie, jak zweryfikować HttpPostedFileBase. Spróbuj poniżej

[FileExtensions(Extensions = "xlsx|xls", ErrorMessage = "Please select an Excel file.")] 
public string Attachment{ get; set; } 

W kontrolerze:

[HttpPost] 
    public ActionResult Index(HttpPostedFileBase Attachment) 
    { 
     if (ModelState.IsValid) 
     { 
      if (Attachment.ContentLength > 0) 
      { 
       string filePath = Path.Combine(HttpContext.Server.MapPath("/Content/Upload"), Path.GetFileName(Attachment.FileName)); 
       Attachment.SaveAs(filePath); 
      } 
     } 
     return RedirectToAction("Index_Ack"}); 
    } 
4

miałem ten sam problem i rozwiązać tworząc nową ValidationAttribute.

Jak to:

[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = true)] 
    public class FileExtensionsAttribute : ValidationAttribute 
    { 
     private List<string> AllowedExtensions { get; set; } 

     public FileExtensionsAttribute(string fileExtensions) 
     { 
      AllowedExtensions = fileExtensions.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList(); 
     } 

     public override bool IsValid(object value) 
     { 
      HttpPostedFileBase file = value as HttpPostedFileBase; 

      if (file != null) 
      { 
       var fileName = file.FileName; 

       return AllowedExtensions.Any(y => fileName.EndsWith(y)); 
      } 

      return true; 
     } 
    } 

Teraz wystarczy użyć tego:

[FileExtensions("jpg,jpeg,png,gif", ErrorMessage = "Your error message.")] 
public HttpPostedFileBase Imagem { get; set; } 

pomogłem. Uściski!

2

Jak odpowiedział marai, atrybut FileExtension działa tylko na właściwościach ciągów.

W moim kodu używam atrybut następująco:

public class MyViewModel 
{ 
    [Required] 
    public HttpPostedFileWrapper PostedFile { get; set; } 

    [FileExtensions(Extensions = "zip,pdf")] 
    public string FileName 
    { 
     get 
     { 
      if (PostedFile != null) 
       return PostedFile.FileName; 
      else 
       return ""; 
     } 
    } 
} 

Następnie, po stronie serwera, ModelState.IsValid będzie false, jeśli postedfile nie ma entensions które określają w atrybucie (.zip i .pdf w moim przykładzie).

Uwaga: Jeśli używasz HTML.ValidationMessageFor pomocnika do renderowania komunikat o błędzie po odświeżenie strony (rozszerzenie pliku Atrybut nie sprawdza poprawności po stronie klienta, tylko po stronie serwera), trzeba określić inną pomocnika dla właściwości FileName w celu wyświetli komunikat o błędzie rozszerzenia:

@Html.ValidationMessageFor(m => m.PostedFile) 
@Html.ValidationMessageFor(m => m.FileName) 
Powiązane problemy