2012-06-29 80 views
4

我需要驗證我的模型中的byte[]Required,但每當我使用Data Annotation[Required]就可以了,它什麼都不會做。即使我選擇一個文件,它也會輸出錯誤信息。如何正確設置字節[]字段?

詳情:

型號:

Public class MyClass 
{ 
    [Key] 
    public int ID {get; set;} 

    [Required] 
    public string Name {get; set;} 

    public byte[] Image {get; set;} 

    [Required] 
    public byte[] Template {get; set;} 
} 

查看:

<div class="editor-label"> 
    <%:Html.LabelFor(model => model.Image) %> 
</div> 
<div class="editor-field"> 
    <input type="file" id="file1" name="files" /> 
</div> 
<div class="editor-label"> 
    <%:Html.Label("Template") %> 
</div> 
<div class="editor-field"> 
    <input type="file" id="file2" name="files"/> 
</div> 
<p> 
    <input type="submit" value="Create" /> 
</p> 

我看了看周圍的職位,並通知人們使用自定義的驗證,但他們已經使用HttpPostedFileBase作爲文件類型而不是像我這樣的byte[],因爲某些原因,當我嘗試使用相同的錯誤,缺少ID時...儘管模型有它自己的ID聲明。

編輯:

語境 - OnModelCreating增加了Report

modelBuilder.Entity<Report>().Property(p => p.Image).HasColumnType("image"); 
modelBuilder.Entity<Report>().Property(p => p.Template).HasColumnType("image"); 

注意,我必須把image作爲ColumnType因爲Byte array truncation to a length of 4000.錯誤。

控制器:

public ActionResult Create(Report report, IEnumerable<HttpPostedFileBase> files) 
    { 

     if (ModelState.IsValid) 
     { 
      db.Configuration.ValidateOnSaveEnabled = false; 

      if (files.ElementAt(0) != null && files.ElementAt(0).ContentLength > 0) 
      { 
       using (MemoryStream ms = new MemoryStream()) 
       { 
        files.ElementAt(0).InputStream.CopyTo(ms); 
        report.Image = ms.GetBuffer(); 
       } 
      } 

      if (files.ElementAt(1) != null && files.ElementAt(1).ContentLength > 0) 
      { 
       using (MemoryStream ms1 = new MemoryStream()) 
       { 
        files.ElementAt(1).InputStream.CopyTo(ms1); 
        report.Template = ms1.GetBuffer(); 
       } 

      } 
      db.Reports.Add(report); 
      db.SaveChanges(); 

      //Temporary save method 
      var tempID = 10000000 + report.ReportID; 
      var fileName = tempID.ToString(); //current by-pass for name 
      var path = Path.Combine(Server.MapPath("~/Content/Report/"), fileName); 
      files.ElementAt(1).SaveAs(path); 

      db.Configuration.ValidateOnSaveEnabled = true; 
      return RedirectToAction("Index"); 
     } 

希望你會發現我錯過了什麼。

+0

好吧,很明顯,事情正在發生。你能檢查這些東西:1.在'report.Template = ms1.GetBuffer();放置一個斷點;'這行是否被執行? 2.在調用SaveChanges()之前,'report.Template'的值是多少?(它是否爲null,或者它是否具有長度大於0的值)?報告是否完全寫入數據庫,只有模板是空的,或根本沒有寫入任何內容? –

+0

此外,請嘗試從屬性中一起移除'RequiredAttribute',看看會發生什麼。 –

+0

如果我從模型中刪除了[[Required]],它會起作用,並且不會保存任何內容,所以我猜測值有問題。我會調試並讓你知道。對不起,遲到的回覆我昨天離開了。 – rexdefuror

回答

0

我改變了我的Create方法,這就是我想到的。似乎工作正常,但...

if (files.ElementAt(1) != null && files.ElementAt(1).ContentLength > 0) 
{ 
    using (MemoryStream ms1 = new MemoryStream()) 
    { 
     files.ElementAt(1).InputStream.CopyTo(ms1); 
     report.Template = ms1.GetBuffer(); 
    } 

} 
else // this part of code did the trick, although not sure how good it is in practice 
{ 
    return View(report); 
} 
4

RequiredAttribute檢查null和空字符串。

public override bool IsValid(object value) 
{ 
    if (value == null) 
    return false; 
    string str = value as string; 
    if (str != null && !this.AllowEmptyStrings) 
    return str.Trim().Length != 0; 
    else 
    return true; 
} 

這工作得很好,如果你的字節數組爲空,但你可能要檢查一個空數組以及(沒有看到你是如何分配你的Template財產的價值,我只能猜測,這是案子)。你可以定義你自己需要的屬性,這會檢查你的。

public class RequiredCollectionAttribute : RequiredAttribute 
{ 
    public override bool IsValid(object value) 
    { 
     bool isValid = base.IsValid(value); 

     if(isValid) 
     { 
     ICollection collection = value as ICollection; 
     if(collection != null) 
     { 
      isValid = collection.Count != 0; 
     } 
     } 
     return isValid; 
    } 
} 

現在只是我們的新RequiredCollection屬性替換您Template財產Required屬性。

[RequiredCollection] 
public byte[] Template {get; set;} 
+0

感謝您的快速響應,我現在會試試:) – rexdefuror

+0

同樣的事情發生:(它拒絕將其保存到數據庫... :(我將更新我的問題與控制器。 – rexdefuror

0

我看了看周圍的職位,並通知人們使用自定義的驗證 但他們已經使用HttpPostedFileBase作爲類型的文件,而不是 的byte []和我一樣的..

你想要將發佈的文件綁定到模型中的byterray字段?如果是的話,你必須去一個自定義模型綁定。

ASP.NET MVC已經有一個字節數組的內置模型聯編程序,因此您可以很容易地擴展它,如在此post中所建議的那樣。

public class CustomFileModelBinder : ByteArrayModelBinder 
{ 
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
        var file = controllerContext.HttpContext.Request.Files[bindingContext.ModelName]; 
  
        if (file != null) 
        { 
            if (file.ContentLength != 0 && !String.IsNullOrEmpty(file.FileName)) 
            { 
                var fileBytes = new byte[file.ContentLength]; 
                file.InputStream.Read(fileBytes, 0, fileBytes.Length); 
                return fileBytes; 
            } 
  
            return null; 
        } 
  
        return base.BindModel(controllerContext, bindingContext); 
    } 
} 

protected void Application_Start() 
{ 
    ... 
    ModelBinders.Binders.Remove(typeof(byte[])); 
    ModelBinders.Binders.Add(typeof(byte[]), new CustomFileModelBinder()); 
} 

現在上傳的文件將直接進入屬性中的bytearray。

+0

我也會檢查這一點。謝謝 – rexdefuror

+0

我也試過這個解決方案,但同樣的事情正在發生,我猜這是有點棘手,然後我想。 – rexdefuror

相關問題