2012-06-29 50 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

相关问题