Pregunta

¿Hay alguna manera de obtener imágenes comentadas (<input type="file" />) para participar en modelo de unión en ASP.NET MVC sin mirar manualmente en el contexto de la petición en una carpeta de modelo personalizado, y sin crear un método de acción separada que sólo toma un archivo enviado como entrada?

Me habría pensado que esto funcionaría:

class MyModel {
  public HttpPostedFileBase MyFile { get; set; }
  public int? OtherProperty { get; set; }
}

<form enctype="multipart/form-data">
  <input type="file" name="MyFile" />
  <input type="text" name="OtherProperty" />
</form>

public ActionResult Create(MyModel myModel) { ... } 

Sin embargo, dado el escenario anterior, MyFile ni siquiera es parte de los valores del proveedor de valor en el contexto de unión (OtherProperty es, por supuesto.) Pero funciona si hago esto:.

public ActionResult Create(HttpPostedFileBase postedFile, ...) { ... } 

Así que, ¿por qué no hay unión se producen cuando el parámetro es un modelo, y cómo puedo hacer que funcione? No tengo ningún problema con el uso de un aglomerante modelo personalizado, pero ¿cómo puedo hacer esto en un aglomerante modelo personalizado sin mirar a Request.Files["MyFile"]?

Para mantener la coherencia, la claridad y la capacidad de prueba, me gustaría que mi código para proporcionar la unión automática de todas las propiedades de un modelo, incluyendo los que están atados a los archivos publicados, sin inspeccionar manualmente el contexto de la petición. Actualmente estoy probando modelo de unión utilizando el enfoque de Scott Hanselman escribió sobre .

O voy sobre esto en el camino equivocado? Como resolverias esto? ¿O es que esto no sea posible por diseño debido a la historia de la separación entre Request.Form y Request.Files?

¿Fue útil?

Solución

Resulta que la razón es que sólo se ve en ValueProviderDictionary Request.Form, RouteData y Request.QueryString para poblar el diccionario proveedor de valor en el contexto de enlace de modelos. Así que no hay manera para que un aglutinante de modelo personalizado para permitir que los archivos enviados a participar en modelo de unión sin inspeccionar la colección de archivos en el contexto de la petición directamente. Este es el camino más cercano que he encontrado para lograr lo mismo:

public ActionResult Create(MyModel myModel, HttpPostedFileBase myModelFile) { }

Mientras myModelFile es en realidad el nombre del campo de formulario de entrada file, no hay necesidad de ningún material personalizado.

Otros consejos

Otra forma es añadir un campo oculto con el mismo nombre que la entrada:

<input type="hidden" name="MyFile" id="MyFileSubmitPlaceHolder" />

El DefaultModelBinder entonces ver un campo y crear el aglutinante correcta.

¿Has mirado en este post que vincula a partir de el que se ha vinculado a (a través de otra ...)?

Si no es así, se ve bastante simple. Este es el modelo de aglutinante que utiliza:

public class HttpPostedFileBaseModelBinder : IModelBinder {
    public ModelBinderResult BindModel(ModelBindingContext bindingContext) {
        HttpPostedFileBase theFile =
            bindingContext.HttpContext.Request.Files[bindingContext.ModelName];
        return new ModelBinderResult(theFile);
    }
}

Se registra en Global.asax.cs de la siguiente manera:

ModelBinders.Binders[typeof(HttpPostedFileBase)] = 
    new HttpPostedFileBaseModelBinder();

y postes con una forma que se parece a esto:

<form action="/File/UploadAFile" enctype="multipart/form-data" method="post">
    Choose file: <input type="file" name="theFile" />
    <input type="submit" />
</form>

Todo el código se copia directamente de la entrada de blog ...

No es necesario registrar una carpeta de encargo, HttpPostedFileBase se ha registrado de forma predeterminada en el marco:

public ActionResult Create(HttpPostedFileBase myFile)
{
    ...
}

Esto ayuda a leer un libro de vez en cuando, en lugar de confiar únicamente en los blogs y foros web.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top