4

byte[]モデルでa を検証する必要があり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 が宣言されています。

編集:

コンテキスト -OnModelCreatingの追加Report

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

エラーのためにimageasを付けなければならなかったことに注意してください。ColumnTypeByte 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");
        }

うまくいけば、私が見逃していることに気付くかもしれません。

4

3 に答える 3

5

RequiredAttributenull と空文字列のチェック。

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の場合、これは正常に機能しますが、おそらく空の配列もチェックする必要があります(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;
    }
}

Requiredプロパティの属性をTemplate新しい属性に置き換えるだけRequiredCollectionです。

[RequiredCollection]
public byte[] Template {get; set;}
于 2012-06-29T18:22:45.780 に答える
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);
}
于 2012-07-04T20:21:31.567 に答える
0

私は投稿を見回して、人々がカスタム検証を使用していることに気付きましたが、私のように byte[] の代わりに HttpPostedFileBase をファイルの種類として使用しています..

投稿されたファイルをモデルのバイトレイ フィールドにバインドしますか? はいの場合は、カスタム モデル バインダーを使用する必要があります。

ASP.NET MVC には既にバイト配列用のモデル バインダーが組み込まれているため、この投稿で提案されているように簡単に拡張できます。

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 として配置されます。

于 2012-06-30T05:12:46.203 に答える