2016-06-11 11 views
0

Ich habe versucht, eine benutzerdefinierte Modellbinder verwenden, aber meine request.files ist nicht ausgefüllt. Bei der IN Forms-Auflistung wird die Eingabe des Typs file für die Eigenschaft byte [] nur mit dem Dateinamen gefüllt. mvc generisch binding byte [] Eigenschaften

<input id="collection[@index][email protected]" name="collection[@index][email protected]" 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); 
     } 
    } 

    } 
} 

Antwort

0

fand ich die Antwort. Dies ermöglicht es mir, direkt von HTML-Dateieingaben zu EF-Modellen zu gehen, ohne auf die manuelle Erstellung eines Dateiarguments für jeden Modelltyp und Eigenschaftstyp zurückgreifen zu müssen, der es benötigt. (Aint nobody got time for that)

Um eine Formulardatei zu schreiben, muss er das enctype Attribut:

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

Sobald dies geschehen ist, kann die Datei über controllerContext.HttpContext.Request.Files

UPDATE zugegriffen werden - Arbeits Beispiel

Hinweis: Sie benötigen die Regex-Dateien nicht, wenn Sie nicht versuchen, eine Sammlung zu binden. Sie brauchen auch nicht die EndsWith, die Sie gerade == können

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