HTML-Helfer für <input type = “file” />

124

Gibt es einen HTMLHelperUpload für Dateien? Insbesondere suche ich einen Ersatz für

<input type="file"/>

Verwenden von ASP.NET MVC HTMLHelper.

Oder wenn ich benutze

using (Html.BeginForm()) 

Was ist das HTML-Steuerelement für den Datei-Upload?

Graviton
quelle

Antworten:

207

HTML-Upload-Datei ASP MVC 3.

Modell : ( Beachten Sie, dass FileExtensionsAttribute in MvcFutures verfügbar ist. Es überprüft die Dateierweiterungen clientseitig und serverseitig. )

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

HTML-Ansicht :

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

Controller-Aktion :

[HttpPost]
public ActionResult Action(ViewModel model)
{
    if (ModelState.IsValid)
    {
        // Use your file here
        using (MemoryStream memoryStream = new MemoryStream())
        {
            model.File.InputStream.CopyTo(memoryStream);
        }
    }
}
Paulius Zaliaduonis
quelle
Dies macht keine Dateieingabe <input type="file" />, nur ein Textfeld
Ben
@PauliusZaliaduonis mit der Zeile Microsoft.Web.Mvc.FileExtensions wird die MVC rot unterstrichen. Wie behebe ich das?
Pomster
1
@pommy Beachten Sie, dass FileExtensionsAttribute in MvcFutures (ab MVC3) verfügbar ist. Sie können Quellen von hier aus verwenden: Quellen oder es ist in .NET Framework 4.5 verfügbar, siehe MSDN-Dokumentation
Paulius Zaliaduonis
1
Leider scheint das FileExtension-Attribut nicht mit den Eigenschaften des HttpPostedFileBase-Typs zu funktionieren, sondern nur mit Zeichenfolgen. Zumindest hat es PDF nie als gültige Erweiterung akzeptiert.
Serj Sagan
Dadurch wird ein Wertattribut (value = "") hinzugefügt, das nicht als gültiges HTML5 validiert wird. Der Wert ist für die Eingabetypen Datei und Bild nicht gültig. Ich sehe keine Möglichkeit, das Wertattribut zu entfernen. Es scheint fest codiert zu sein.
Dan Friedman
19

Sie können auch verwenden:

@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> 
}
Balexandre
quelle
6

Oder Sie könnten es richtig machen:

In Ihrer HtmlHelper-Erweiterungsklasse:

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

Diese Linie:

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

Erzeugt eine für das Modell eindeutige ID, die Sie in Listen und anderen Dingen kennen. Modell [0] .Name etc.

Erstellen Sie die richtige Eigenschaft im Modell:

public HttpPostedFileBase NewFile { get; set; }

Dann müssen Sie sicherstellen, dass Ihr Formular Dateien sendet:

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

Dann ist hier dein Helfer:

@Html.FileFor(x => x.NewFile)
Tod
quelle
Diese Lösung ist mehr Augenweide und hält mich mit den @ HTML-Hilfsmethoden im Einklang.
Yahfoufi
4

Verbesserte Version der Antwort von Paulius Zaliaduonis:

Damit die Validierung ordnungsgemäß funktioniert, musste ich das Modell ändern 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;
            }
        }
}

und der Blick auf:

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

Dies ist erforderlich, da das, was @Serj Sagan über das FileExtension-Attribut geschrieben hat, nur mit Zeichenfolgen funktioniert.

BornToCode
quelle
Können Sie diese Antwort nicht mit Paulius 'Antwort zusammenführen?
Graviton
2

Zur Verwendung BeginForm, hier ist die Art und Weise , es zu benutzen:

 using(Html.BeginForm("uploadfiles", 
"home", FormMethod.POST, new Dictionary<string, object>(){{"type", "file"}})
Graviton
quelle
2
Zuerst erwähnen Sie, wie ein Eingabeelement generiert wird, und jetzt sprechen Sie darüber, wie ein Formularelement generiert wird. Ist das wirklich deine Antwort?
Pupeno
0

Das funktioniert auch:

Modell:

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

Aussicht:

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

Controller-Aktion:

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

Liste der Inhaltstypen

Eyal
quelle
-2

Ich denke, das ist ein bisschen hackig, aber es führt dazu, dass die richtigen Validierungsattribute usw. angewendet werden

@Html.Raw(Html.TextBoxFor(m => m.File).ToHtmlString().Replace("type=\"text\"", "type=\"file\""))
Luke Schafer
quelle