【问题标题】:ViewModel for multiple file upload in ASP.NET MVC 3在 ASP.NET MVC 3 中用于多个文件上传的 ViewModel
【发布时间】:2012-08-09 09:14:55
【问题描述】:

我有多个文件上传ViewsViewModel 绑定如下:

@model IVRControlPanel.Models.UploadNewsModel
  @using (Html.BeginForm("index", "NewsUpload", FormMethod.Post, new { name = "form1", @id = "form1" }))
        {
            @Html.ValidationSummary(true)

            <div class="field fullwidth">
                <label for="text-input-normal">
                    @Html.Label("Select Active Date Time")</label>
                <input type="text" id="active" value="@DateTime.Now" />
                 @Html.ValidationMessageFor(model => model.ActiveDateTime)
            </div>

            <div class="field fullwidth">
                <label>
                    @Html.Label("Select Language")
                </label>
                @Html.DropDownList("Language", (SelectList)ViewBag.lang)
            </div>

            <div class="field">
                <label>
                    @Html.Label("General News")
                </label>
               @Html.TextBoxFor(model => model.generalnews, new { name = "files", @class="custom-file-input", type = "file" })
                @Html.ValidationMessageFor(model => model.generalnews)
            </div>
            <div class="field">
                <label>
                    @Html.Label("Sports News")
                </label>
               @Html.TextBoxFor(model => model.sportsnews, new { name = "files", @class = "custom-file-input", type = "file" })
                @Html.ValidationMessageFor(model => model.sportsnews)
            </div>         
            <div class="field">
                <label>
                    @Html.Label("Business News")
                </label>
               @Html.TextBoxFor(model => model.businessnews, new { name = "files", @class = "custom-file-input", type = "file" })
                @Html.ValidationMessageFor(model => model.businessnews)
            </div>            
            <div class="field">
                <label>
                    @Html.Label("International News")
                </label>
               @Html.TextBoxFor(model => model.internationalnews, new { name = "files", @class = "custom-file-input", type = "file" })
                @Html.ValidationMessageFor(model => model.internationalnews)
            </div>    
             <div class="field">
                <label>
                    @Html.Label("Entertaintment News")
                </label>
               @Html.TextBoxFor(model => model.entertaintmentnews, new { name = "files", @class = "custom-file-input", type = "file" })
                @Html.ValidationMessageFor(model => model.entertaintmentnews)
            </div>          

             <footer class="pane">
                <input type="submit" class="bt blue" value="Submit" />
            </footer>                              
        }

查看带有数据注释的模型,用于验证允许扩展的文件上传,如下所示:

 public class UploadNewsModel
{
    public DateTime ActiveDateTime { get; set; }

   // public IEnumerable<SelectListItem> Language { get; set; }

    [File(AllowedFileExtensions = new string[] { ".jpg", ".gif", ".tiff", ".png", ".pdf", ".wav" }, MaxContentLength = 1024 * 1024 * 8, ErrorMessage = "Invalid File")]
    public HttpPostedFileBase files { get; set; }

}

控制器:用于保存多个文件并在存在错误时返回视图

  [HttpPost]
            public ActionResult Index(UploadNewsModel news, IEnumerable<HttpPostedFileBase> files)
            {
                if (ModelState.IsValid)
                {
                    foreach (var file in files)
                    {
                        if (file != null && file.ContentLength > 0)
                        {
                            var fileName = Path.GetFileName(file.FileName);
                            var serverpath = Server.MapPath("~/App_Data/uploads/News");
                            var path = Path.Combine(serverpath, fileName);
                            if (!Directory.Exists(serverpath))
                            {
                                Directory.CreateDirectory(serverpath);
                            }

                            file.SaveAs(path);
                        }

                    }
                }
                return View(news);
            }

        }

问题说明 如何为这五个文件上传输入控件定义视图模型,以便在不允许上传文件的文件扩展名类型时显示相应的错误以显示相应的验证错误。对于所有五个文件上传控件,我只有一个视图模型项。

为那些显示各自验证错误的多文件上传控件定义视图模型的最佳方法是什么?而不是用户尝试上传不允许扩展名的文件???

【问题讨论】:

    标签: asp.net-mvc-3 file-upload asp.net-mvc-viewmodel


    【解决方案1】:

    这里真正的问题是 MVC 没有合适的 http 文件模型绑定器。

    因此,除非您使用像 mvc futures 这样的项目,它对文件上传有一些额外的支持,否则您将不得不自己解决一些问题并自己完成艰苦的工作。

    这是一个可能对您更有效的示例。

    首先我会创建一个 ViewModel 来表示一个文件,如下所示:

    public class FileViewModel
    {  
        public Guid Id { get; set; }
        public string Name { get; set; }
        public bool Delete { get; set; }
        public string ExistingUrl { get; set; }
    
        public HttpPostedFileBase FileBase { get; set; }
    }
    

    显然属性取决于您的要求,重要的是 FileBase,它是它自己的模型。

    接下来,您的页面的 ViewModel(在您的情况下为 UploadNewsModel):

    public class IndexViewModel
    { 
        public IList<FileViewModel> Files { get; set; }
    }
    

    这里的重要一点是文件的 IList,这是我们捕获多个文件的方式(在您当前使用 'file' 的实现中,您只捕获一个。

    进入页面级视图:

    @model IndexViewModel
    <form method="post" action="@Url.Action("Index")" enctype="multipart/form-data">
    @Html.ValidationSummary(true)
    @Html.EditorFor(x => x.Files)
    <input type="submit" value="Submit" />
    </form>
    

    注意 EditorFor,我们接下来要做的是为此时应该使用的 FileViewModel 创建一个 EditorTemplate。 p>

    像这样:

    @model FileViewModel
    
    <h4>@Model.Name</h4>
    @Html.HiddenFor(x => x.Id)
    @Html.CheckBoxFor(x => x.Delete)
    
    <input @( "name=" + ViewData.TemplateInfo.HtmlFieldPrefix + ".FileBase") type="file" />
    

    注意 ViewData.TemplateInfo.HtmlFieldPrefix 的用法,这有点糟糕,但就像我说的,这是因为 mvc 对文件输入类型的支持很差。我们必须自己做。我们将每个文件的名称改成 '[0].FileBase' 等。

    这将在 POST 操作中正确填充 FileViewModel

    到目前为止一切顺利,验证呢?

    您可以在服务器上手动执行此操作。自己测试文件扩展名,然后简单地使用以下代码将错误添加到模型中,例如:

    ModelState.AddModelError("","Invalid extension.")
    

    另一方面,扩展验证应该在客户端(以及服务器端)完成

    【讨论】:

      猜你喜欢
      • 2013-05-07
      • 2011-12-30
      • 2016-07-12
      • 2011-02-07
      • 1970-01-01
      • 2019-01-29
      • 1970-01-01
      • 2012-01-20
      • 2018-09-04
      相关资源
      最近更新 更多