<input type="file" /> 的 HTML 助手

Posted

技术标签:

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

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

<input type="file"/>

使用 ASP.NET MVC HTMLHelper。

或者,如果我使用

using (Html.BeginForm()) 

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

【问题讨论】:

【参考方案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")

【讨论】:

先说怎么生成输入元素,现在说怎么生成表单元素?这真的是你的答案吗?

以上是关于<input type="file" /> 的 HTML 助手的主要内容,如果未能解决你的问题,请参考以下文章

样式 <input type="file"> [重复]

如何重置 <input type = "file">

我们可以改变 <input type="file"> 样式吗? [复制]

<input type="file"> 的事件 [重复]

从 <input type="file"> 上传文件

触发 <input type="file"/> 的 javascript 事件 onchange 事件