Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何正确设置字节[]字段必填字段?_C#_.net_Asp.net Mvc_Entity Framework_Data Annotations - Fatal编程技术网

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);
}