Trình trợ giúp Html cho <kiểu nhập = tập tin


124

Có một HTMLHelpertập tin tải lên? Cụ thể, tôi đang tìm kiếm một sự thay thế của

<input type="file"/>

sử dụng ASP.NET MVC HTMLHelper.

Hoặc, nếu tôi sử dụng

using (Html.BeginForm()) 

Kiểm soát HTML để tải lên tập tin là gì?

Câu trả lời:


207

Tải lên tệp HTML ASP MVC 3.

Model : ( Lưu ý rằng FileExtensionsAttribution có sẵn trong MvcFutures. Nó sẽ xác nhận phần mở rộng tệp phía máy khách và phía máy chủ. )

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

Chế độ xem 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)
}

Hành động điều khiển :

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

Điều này không hiển thị đầu vào tệp <input type="file" />, chỉ có một hộp văn bản
Ben

@PauliusZaliaduonis với dòng Microsoft.Web.Mvc.FileExtensions, MVC được gạch chân màu đỏ. Làm thế nào để tôi sửa nó?
Pomster

1
@pommy Lưu ý rằng FileExtensionsAttribution có sẵn trong MvcFutures (Kể từ MVC3). Bạn có thể sử dụng các nguồn từ đây: Nguồn hoặc nó có sẵn trong .NET Framework 4.5, xem tài liệu MSDN
Paulius Zaliaduonis

1
Thật không may, thuộc tính FileExtension dường như không hoạt động với loại thuộc tính httpPostedFileBase, nhưng có vẻ như chỉ có chuỗi. Ít nhất là nó không bao giờ chấp nhận pdf như một phần mở rộng hợp lệ.
Serj Sagan

Điều này sẽ thêm một thuộc tính value (value = "") không xác thực là HTML5 hợp lệ. giá trị không hợp lệ trên tập tin loại hình ảnh và hình ảnh. Tôi không thấy bất kỳ cách nào để loại bỏ thuộc tính giá trị. Nó dường như được mã hóa cứng.
Dan Friedman

19

Bạn cũng có thể dùng:

@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

Hoặc bạn có thể làm điều đó đúng:

Trong lớp Mở rộng HtmlHelper của bạn:

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

Đường thẳng này:

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

Tạo một id duy nhất cho mô hình, bạn biết trong danh sách và công cụ. mô hình [0]. Tên, v.v.

Tạo thuộc tính chính xác trong mô hình:

public HttpPostedFileBase NewFile { get; set; }

Sau đó, bạn cần đảm bảo rằng biểu mẫu của bạn sẽ gửi tệp:

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

Sau đó, đây là người trợ giúp của bạn:

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

Giải pháp này là nhiều kẹo mắt hơn, và giữ cho tôi phù hợp với các phương pháp trợ giúp @Html.
Yahfoufi

4

Phiên bản cải tiến của câu trả lời của Paulius Zaliaduonis:

Để xác thực hoạt động chính xác, tôi đã phải thay đổi Mô hình thành:

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

và quan điểm:

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

Điều này là bắt buộc vì những gì @Serj Sagan đã viết về thuộc tính FileExtension chỉ hoạt động với các chuỗi.


Bạn không thể hợp nhất câu trả lời này vào câu trả lời của Paulius?
Graviton

2

Để sử dụng BeginForm, đây là cách sử dụng:

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

2
Trước tiên, bạn đề cập đến cách tạo một phần tử đầu vào, và bây giờ bạn nói về cách tạo một phần tử biểu mẫu? Đây thực sự là câu trả lời của bạn?
Pupeno

0

Điều này cũng hoạt động:

Mô hình:

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

Lượt xem:

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

Hành động điều khiển:

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

Danh sách nội dung


-2

Đây là một chút hack tôi đoán, nhưng nó dẫn đến các thuộc tính xác nhận chính xác vv được áp dụng

@Html.Raw(Html.TextBoxFor(m => m.File).ToHtmlString().Replace("type=\"text\"", "type=\"file\""))
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.