【问题标题】:Html helper for <input type="file" /><input type="file" /> 的 HTML 助手
【发布时间】:2010-09-23 04:59:15
【问题描述】:

是否有HTMLHelper 用于文件上传?具体来说,我正在寻找替换

<input type="file"/>

使用 ASP.NET MVC HTMLHelper。

或者,如果我使用

using (Html.BeginForm()) 

文件上传的 HTML 控件是什么?

【问题讨论】:

    标签: asp.net-mvc razor file-upload upload html-helper


    【解决方案1】:

    或者你可以正确地做到这一点:

    在您的 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));
        }
    

    这一行:

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

    生成模型唯一的 id,你知道在列表和东西中。型号[0].名称等

    在模型中创建正确的属性:

    public HttpPostedFileBase NewFile { get; set; }
    

    那么你需要确保你的表单会发送文件:

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

    那么这是你的助手:

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

    【讨论】:

    • 这个解决方案更吸引眼球,并且让我与@Html 辅助方法保持一致。
    【解决方案2】:

    这也有效:

    型号:

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

    查看:

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

    控制器动作:

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

    List of contentTypes

    【讨论】:

      【解决方案3】:

      我猜这有点 hacky,但它会导致应用正确的验证属性等

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

      【讨论】:

        【解决方案4】:

        Paulius Zaliaduonis 回答的改进版:

        为了使验证正常工作,我不得不将模型更改为:

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

        和视图:

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

        这是必需的,因为 @Serj Sagan 写的关于 FileExtension 属性仅适用于字符串。

        【讨论】:

        • 你不能将此答案合并到 Paulius 的答案中吗?
        【解决方案5】:

        HTML 上传文件 ASP MVC 3.

        模型:(请注意,FileExtensionsAttribute 在 MvcFutures 中可用。它将验证客户端和服务器端的文件扩展名。

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

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

        控制器动作

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

        【讨论】:

        • 这不会渲染文件输入&lt;input type="file" /&gt;,只是一个文本框
        • @PauliusZaliaduonis 行 Microsoft.Web.Mvc.FileExtensions MVC 下划线为红色。我该如何解决?
        • @pommy 注意 FileExtensionsAttribute 在 MvcFutures 中可用(从 MVC3 开始)。您可以使用此处的源代码:Sources 或在 .NET Framework 4.5 中可用,请参阅 MSDN documentation
        • 不幸的是,FileExtension 属性似乎不适用于 HttpPostedFileBase 类型的属性,而似乎只是字符串。至少它从未接受 pdf 作为有效的扩展名。
        • 这将添加一个不验证为有效 HTML5 的值属性 (value="")。值对输入类​​型文件和图像无效。我看不到任何删除 value 属性的方法。它似乎是硬编码的。
        【解决方案6】:

        不久前我也有同样的问题,偶然发现了 Scott Hanselman 的一篇帖子:

        Implementing HTTP File Upload with ASP.NET MVC including Tests and Mocks

        希望这会有所帮助。

        【讨论】:

        • 谢谢,但我特意寻找使用 (Html.BeginForm()) 的实现,而不是其他变体。
        【解决方案7】:

        你也可以使用:

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

        【讨论】:

          【解决方案8】:

          要使用BeginForm,使用方法如下:

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

          【讨论】:

          • 先说怎么生成输入元素,现在说怎么生成表单元素?这真的是你的答案吗?
          猜你喜欢
          • 1970-01-01
          • 2011-04-01
          • 2017-12-04
          • 2011-04-01
          • 2017-11-26
          • 1970-01-01
          • 1970-01-01
          • 2013-12-07
          相关资源
          最近更新 更多