Helper HTML per <input type = “file” />


124

Esiste un HTMLHelpercaricamento file? In particolare, sto cercando un sostituto di

<input type="file"/>

utilizzando ASP.NET MVC HTMLHelper.

Oppure, se uso

using (Html.BeginForm()) 

Qual è il controllo HTML per il caricamento del file?

Risposte:


207

File di caricamento HTML ASP MVC 3.

Modello : ( Notare che FileExtensionsAttribute è disponibile in MvcFutures. Convaliderà le estensioni dei file lato client e lato server ) .

public class ViewModel
{
    [Required, Microsoft.Web.Mvc.FileExtensions(Extensions = "csv", 
             ErrorMessage = "Specify a CSV file. (Comma-separated values)")]
    public HttpPostedFileBase File { get; set; }
}

Visualizzazione HTML :

@using (Html.BeginForm("Action", "Controller", FormMethod.Post, new 
                                       { enctype = "multipart/form-data" }))
{
    @Html.TextBoxFor(m => m.File, new { type = "file" })
    @Html.ValidationMessageFor(m => m.File)
}

Azione del controller :

[HttpPost]
public ActionResult Action(ViewModel model)
{
    if (ModelState.IsValid)
    {
        // Use your file here
        using (MemoryStream memoryStream = new MemoryStream())
        {
            model.File.InputStream.CopyTo(memoryStream);
        }
    }
}

Questo non rende un input di file <input type="file" />, ma solo una casella di testo
Ben

@PauliusZaliaduonis con la riga Microsoft.Web.Mvc.FileExtensions l'MVC è sottolineato in rosso. Come lo risolvo?
Pomster,

1
@pommy Nota che FileExtensionsAttribute è disponibile in MvcFutures (a partire da MVC3). È possibile utilizzare le fonti da qui: Fonti o è disponibile in .NET Framework 4.5, consultare la documentazione MSDN
Paulius Zaliaduonis,

1
Sfortunatamente l'attributo FileExtension non sembra funzionare con il tipo di proprietà HttpPostedFileBase, ma sembra solo una stringa. Almeno non ha mai accettato il pdf come estensione valida.
Serj Sagan,

Ciò aggiungerà un attributo value (value = "") che non viene convalidato come HTML5 valido. il valore non è valido sul file e sull'immagine dei tipi di input. Non vedo alcun modo di rimuovere l'attributo value. Sembra essere codificato.
Dan Friedman,

19

Puoi anche usare:

@using (Html.BeginForm("Upload", "File", FormMethod.Post, new { enctype = "multipart/form-data" }))
{ 
    <p>
        <input type="file" id="fileUpload" name="fileUpload" size="23" />
    </p>
    <p>
        <input type="submit" value="Upload file" /></p> 
}


6

Oppure potresti farlo correttamente:

Nella tua classe di estensione HtmlHelper:

public static MvcHtmlString FileFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression)
    {
        return helper.FileFor(expression, null);
    }

public static MvcHtmlString FileFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes)
    {
        var builder = new TagBuilder("input");

        var id = helper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(ExpressionHelper.GetExpressionText(expression));
        builder.GenerateId(id);
        builder.MergeAttribute("name", id);
        builder.MergeAttribute("type", "file");

        builder.MergeAttributes(new RouteValueDictionary(htmlAttributes));

        // Render tag
        return MvcHtmlString.Create(builder.ToString(TagRenderMode.SelfClosing));
    }

Questa linea:

var id = helper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(ExpressionHelper.GetExpressionText(expression));

Genera un ID univoco per il modello, lo sai in elenchi e cose. modello [0]. Nome ecc.

Crea la proprietà corretta nel modello:

public HttpPostedFileBase NewFile { get; set; }

Quindi è necessario assicurarsi che il modulo invierà i file:

@using (Html.BeginForm("Action", "Controller", FormMethod.Post, new { enctype = "multipart/form-data" }))

Quindi ecco il tuo aiuto:

@Html.FileFor(x => x.NewFile)

Questa soluzione è più accattivante e mi mantiene coerente con i metodi helper @Html.
Yahfoufi,

4

Versione migliorata della risposta di Paulius Zaliaduonis:

Per far funzionare correttamente la validazione ho dovuto cambiare il Modello in:

public class ViewModel
{
      public HttpPostedFileBase File { get; set; }

        [Required(ErrorMessage="A header image is required"), FileExtensions(ErrorMessage = "Please upload an image file.")]
        public string FileName
        {
            get
            {
                if (File != null)
                    return File.FileName;
                else
                    return String.Empty;
            }
        }
}

e la vista di:

@using (Html.BeginForm("Action", "Controller", FormMethod.Post, new 
                                       { enctype = "multipart/form-data" }))
{
    @Html.TextBoxFor(m => m.File, new { type = "file" })
    @Html.ValidationMessageFor(m => m.FileName)
}

Ciò è necessario perché ciò che @Serj Sagan ha scritto sull'attributo FileExtension funziona solo con stringhe.


Non puoi unire questa risposta nella risposta di Paulius?
Graviton,

2

Per usare BeginForm, ecco il modo di usarlo:

 using(Html.BeginForm("uploadfiles", 
"home", FormMethod.POST, new Dictionary<string, object>(){{"type", "file"}})

2
Prima menzioni come generare un elemento di input e ora parli di come generare un elemento modulo? Questa è davvero la tua risposta?
pupeno,

0

Questo funziona anche:

Modello:

public class ViewModel
{         
    public HttpPostedFileBase File{ get; set; }
}

Visualizza:

@using (Html.BeginForm("Action", "Controller", FormMethod.Post, new 
                                       { enctype = "multipart/form-data" }))
{
    @Html.TextBoxFor(m => m.File, new { type = "file" })       
}

Azione del controller:

[HttpPost]
public ActionResult Action(ViewModel model)
{
    if (ModelState.IsValid)
    {
        var postedFile = Request.Files["File"];

       // now you can get and validate the file type:
        var isFileSupported= IsFileSupported(postedFile);

    }
}

public bool IsFileSupported(HttpPostedFileBase file)
            {
                var isSupported = false;

                switch (file.ContentType)
                {

                    case ("image/gif"):
                        isSupported = true;
                        break;

                    case ("image/jpeg"):
                        isSupported = true;
                        break;

                    case ("image/png"):
                        isSupported = true;
                        break;


                    case ("audio/mp3"):  
                        isSupported = true;
                        break;

                    case ("audio/wav"):  
                        isSupported = true;
                        break;                                 
                }

                return isSupported;
            }

Elenco di contentTypes


-2

Questo è un po 'confuso, immagino, ma risulta che vengano applicati gli attributi di convalida corretti ecc

@Html.Raw(Html.TextBoxFor(m => m.File).ToHtmlString().Replace("type=\"text\"", "type=\"file\""))
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.