mvc 一般绑定 byte[] 属性

mvc genericly binding byte[] properties

我试过使用自定义模型活页夹,但我的 request.files 没有填充。在表单集合中,byte[] 属性 的类型文件输入仅由文件名填充。

<input id="collection[@index].@p.Name" name="collection[@index].@p.Name" type="file" />
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace male.services.mvc.Binders
{
  public class CustomModelBinder : DefaultModelBinder
  {

    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
      if (bindingContext.ModelType.GetProperties().Any(o => o.PropertyType == typeof(byte[])))
      {
        HttpRequestBase request = controllerContext.HttpContext.Request;
        foreach (var pi in bindingContext.ModelType.GetProperties().Where(o => o.PropertyType == typeof(byte[])))
        {
          // can't access any property in the parameters that gives me my file input or my stream
        }
        return base.BindModel(controllerContext, bindingContext);
      }
      else
      {
        return base.BindModel(controllerContext, bindingContext);
      }
    }

  }
}

我找到了答案。这将允许我直接从 html 文件输入到 EF 模型,而无需为每个模型类型和需要它的 属性 类型手工制作文件参数。 (Aint nobody got time for that)

为了将表格 post 文件,它必须具有 enctype 属性:

<form enctype="multipart/form-data" ... />

完成后,可以通过 controllerContext.HttpContext.Request.Files

访问文件

更新 - 工作示例

注意:如果您不尝试绑定集合,则不需要 Regex 内容。你也不需要 EndsWith,你可以只使用 ==

using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Mvc;

namespace male.services.mvc.Binders
{
  public class CustomModelBinder : DefaultModelBinder
  {

    HttpRequestBase request;

    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
      request = controllerContext.HttpContext.Request;
      return base.BindModel(controllerContext, bindingContext);
    }

    protected override void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor)
    {
      if (propertyDescriptor.PropertyType == typeof(byte[]))
      {
        var key = request.Files.AllKeys.SingleOrDefault(o => o.EndsWith($"].{propertyDescriptor.Name}"));
        var fileIndex = Regex.Match(key, @"\[(.*)\]").Groups[1].Value;
        var modelIndex = Regex.Match(bindingContext.ModelName, @"\[(.*)\]").Groups[1].Value;
        if(fileIndex == modelIndex)
        {
          HttpPostedFileWrapper httpPostedFile = (HttpPostedFileWrapper)request.Files[request.Files.AllKeys.SingleOrDefault(o => o.EndsWith(propertyDescriptor.Name))];
          using (MemoryStream ms = new MemoryStream())
          {
            httpPostedFile.InputStream.CopyTo(ms);
            propertyDescriptor.SetValue(bindingContext.Model, ms.ToArray());
          }
        }
      }
      else
        base.BindProperty(controllerContext, bindingContext, propertyDescriptor);
    }
  }
}