C# 如何正确设置字节[]字段必填字段?
我需要在我的模型中将C# 如何正确设置字节[]字段必填字段?,c#,.net,asp.net-mvc,entity-framework,data-annotations,C#,.net,Asp.net Mvc,Entity Framework,Data Annotations,我需要在我的模型中将字节[]验证为必需的,但每当我在其上使用数据注释[Required]时,它不会做任何事。即使我选择了一个文件,它也会输出错误消息 详情: 型号: Public class MyClass { [Key] public int ID {get; set;} [Required] public string Name {get; set;} public byte[] Image {get; set;} [Required] pub
字节[]
验证为必需的
,但每当我在其上使用数据注释
[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;}
}
视图:
注意,由于字节数组的长度被截断为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");
}
创建公共操作结果(报告、IEnumerable文件)
{
if(ModelState.IsValid)
{
db.Configuration.ValidateOnSaveEnabled=false;
if(files.ElementAt(0)!=null&&files.ElementAt(0).ContentLength>0)
{
使用(MemoryStream ms=new MemoryStream())
{
files.ElementAt(0).InputStream.CopyTo(ms);
report.Image=ms.GetBuffer();
}
}
if(files.ElementAt(1)!=null&&files.ElementAt(1).ContentLength>0)
{
使用(MemoryStream ms1=新的MemoryStream())
{
files.ElementAt(1).InputStream.CopyTo(ms1);
report.Template=ms1.GetBuffer();
}
}
db.Reports.Add(报告);
db.SaveChanges();
//临时保存方法
var tempID=10000000+report.ReportID;
var fileName=tempID.ToString();//name的当前旁路
var path=path.Combine(Server.MapPath(“~/Content/Report/”),文件名);
files.ElementAt(1).SaveAs(路径);
db.Configuration.ValidateOnSaveEnabled=true;
返回操作(“索引”);
}
希望您能注意到我遗漏了什么。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;
}
如果您的字节数组为null,则此方法可以正常工作,但您可能也希望检查空数组(在没有看到如何分配模板
属性的值的情况下,我只能猜测是这种情况)。您可以定义自己所需的属性来执行此检查
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;}
我查看了一下帖子,注意到人们使用自定义验证
但是他们使用HttpPostedFileBase作为文件类型,而不是
像我一样
是否要将发布的文件绑定到模型中的byterray字段?如果是,则必须使用自定义模型绑定器
ASP.NET MVC已经为字节数组提供了内置的模型绑定器,因此您可以按照本文的建议轻松地扩展它
现在上传的文件将直接以bytearray的形式出现在属性中。我已经更改了我的
创建方法,这就是我所想到的。看起来效果不错,但是
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);
}
感谢您的快速响应,我现在将尝试以下操作:)同样的情况发生:(它拒绝将其保存到数据库…:(我将使用Controller更新我的问题。好的,显然发生了一些事情。您可以检查以下事项:1.在report.Template=ms1.GetBuffer()上放置断点这一行正在执行吗?2.在调用SaveChanges()
之前,report.Template
的值是多少(是空值,还是长度大于0的值)?报表是否在模板为空的情况下写入数据库,或者根本没有写入任何内容?此外,请尝试同时从属性中删除RequiredAttribute
,看看会发生什么情况。如果我删除[Required]
从模型上看,它可以工作,不,它不会保存任何东西,所以我猜值有问题。我会调试并让您知道。很抱歉,我昨天不在。我已经调试了它,它甚至没有到达创建/发布
方法。它会将模板
视为空。无论RequiredCollectionAtt如何ribute
或RequiredAttribute
的情况也一样。您说过如果删除RequiredAttribute
它会起作用吗?在这种情况下,模板
设置为什么?在您将值设置为模板
的上面一行,files.ElementAt(1)是什么返回?我也会检查一下。谢谢。我也尝试过这个解决方案,但同样的事情正在发生。我猜这比我想的要复杂一些。
[RequiredCollection]
public byte[] Template {get; set;}
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());
}
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);
}