Helper html untuk <input type = “file” />

124

Apakah ada HTMLHelperuntuk mengunggah file? Secara khusus, saya sedang mencari pengganti

<input type="file"/>

menggunakan ASP.NET MVC HTMLHelper.

Atau, Jika saya menggunakan

using (Html.BeginForm()) 

Apa kontrol HTML untuk upload file?

Graviton
sumber

Jawaban:

207

File Unggah HTML ASP MVC 3.

Model : ( Perhatikan bahwa FileExtensionsAttribute tersedia di MvcFutures. Ini akan memvalidasi ekstensi file sisi klien dan sisi server. )

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

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

Tindakan pengontrol :

[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
sumber
Ini tidak membuat input file <input type="file" />, hanya kotak teks
Ben
@PauliusZaliaduonis dengan baris Microsoft.Web.Mvc.FileExtensions MVC digarisbawahi sebagai merah. Bagaimana cara memperbaikinya?
Pomster
1
@pommy Perhatikan bahwa FileExtensionsAttribute tersedia di MvcFutures (Pada MVC3). Anda dapat menggunakan sumber dari sini: Sumber atau tersedia di .NET Framework 4.5, lihat dokumentasi MSDN
Paulius Zaliaduonis
1
Sayangnya atribut FileExtension tampaknya tidak berfungsi dengan tipe properti HttpPostedFileBase, tetapi tampaknya hanya string. Setidaknya itu tidak pernah menerima pdf sebagai ekstensi yang valid.
Serj Sagan
Ini akan menambahkan atribut nilai (value = "") yang tidak divalidasi sebagai HTML5 yang valid. nilai tidak valid pada file jenis input dan gambar. Saya tidak melihat cara apa pun untuk menghapus atribut nilai. Tampaknya di-hardcode.
Dan Friedman
19

Anda juga bisa menggunakan:

@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
sumber
6

Atau Anda bisa melakukannya dengan benar:

Di kelas Ekstensi HtmlHelper Anda:

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

Garis ini:

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

Menghasilkan id unik untuk model, Anda tahu dalam daftar dan barang. model [0]. Nama dll.

Buat properti yang benar dalam model:

public HttpPostedFileBase NewFile { get; set; }

Maka Anda perlu memastikan formulir Anda akan mengirim file:

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

Lalu inilah pembantu Anda:

@Html.FileFor(x => x.NewFile)
Rubah
sumber
Solusi ini lebih menarik, dan membuat saya konsisten dengan metode bantuan @Html.
Yahfoufi
4

Versi perbaikan dari jawaban Paulius Zaliaduonis:

Agar validasi berfungsi dengan baik, saya harus mengubah Model menjadi:

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

dan pandangan untuk:

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

Ini diperlukan karena apa yang ditulis @Serj Sagan tentang atribut FileExtension yang hanya berfungsi dengan string.

BornToCode
sumber
Tidak bisakah Anda menggabungkan jawaban ini menjadi jawaban Paulius?
Graviton
2

Untuk menggunakannya BeginForm, berikut cara menggunakannya:

 using(Html.BeginForm("uploadfiles", 
"home", FormMethod.POST, new Dictionary<string, object>(){{"type", "file"}})
Graviton
sumber
2
Pertama, Anda menyebutkan cara menghasilkan elemen masukan, dan sekarang Anda berbicara tentang cara membuat elemen formulir? Apakah ini benar-benar jawaban Anda?
pupeno
0

Ini juga berfungsi:

Model:

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

Melihat:

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

Tindakan pengontrol:

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

Daftar jenis konten

Eyal
sumber
-2

Ini sedikit hacky saya kira, tetapi ini menghasilkan atribut validasi yang benar, dll. Yang diterapkan

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