【问题标题】:Remote file extension validation in ASP.NET MVC3 with C#?使用 C# 在 ASP.NET MVC3 中进行远程文件扩展验证?
【发布时间】:2011-04-29 10:03:54
【问题描述】:

我有一个 MVC3 应用程序,它从用户的硬盘上传文件并对其进行操作。一项要求是文件扩展名应为 .xls(或 xlsx)。

我想验证文件名,但我想知道在可重用性性能方面什么是最佳选择(当然还有最佳编码实践)。

我有以下索引视图:

@using (Html.BeginForm("Index", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
    {
        <br />
        <p><input type="file" id="file" name="file" size="23"/></p><br />
        <p><input type="submit" value="Upload file" /></p>        
    }  

由控制器动作方法调用Index

public ActionResult Index()
{
   return View("Index");
}

并且用户响应由 Index 操作方法(HttpPost)处理:

[HttpPost]
public ActionResult Index(HttpPostedFileBase file)
{
    FileServices lfileServices = new FileServices();
    var lfilePath = lfileServices.UploadFile(file, "~/App_Data/uploads");
    //Manipulation;
}

现在我可以使用 FileServices 中的Path.GetExtension(filename) 来获取扩展名,然后执行检查,但它将在上传完成后执行。

我想在用户尝试上传文件后执行此操作。我唯一想到的就是创建一个模型(或者更好的是 ViewModel)并使用 DataAnnotations 中的远程验证。 p>

我在现场看到了 Scott Hanselman 的演示,但他似乎对此并不满意,因为应用程序正在编译但没有执行检查。

有没有人有一个好的方法来执行这种远程验证或任何其他解决方案(例如 jQuery)?

谢谢

弗朗西斯科

【问题讨论】:

    标签: c# file asp.net-mvc-3


    【解决方案1】:

    您可以使用 javascript 来做到这一点:

    $(function () {
        $('form').submit(function () {
            var selectedFile = $('#file').val();
            var matches = selectedFile.match(/\.(xlsx?)$/i);
            if (matches == null) {
                alert('please select an Excel file');
                return false;
            }
            return true;
        });
    });
    

    当然,这在任何情况下都不能免除您在服务器上执行相同检查的义务,因为如果客户端没有启用 javascript,那将是唯一的方法。即使这样也不是 100% 可靠的,因为没有什么可以阻止用户将任何垃圾文件重命名为 .xls 并上传它。可以在服务器上使用启发式算法通过查看一些已知的字节序列来尝试猜测实际文件类型。


    更新:

    远程 AJAX 验证示例(由于 cmets 的需求,我不推荐它)。您可以使用与 ASP.NET MVC 3 捆绑在一起的出色的 jquery.validate plugin

    <script src="@Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script>
    
    @using (Html.BeginForm("Index", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
    {
        <input type="file" id="file" name="file" size="23" data-remote-val-url="@Url.Action("CheckExtension")"/>
        <br />
        <input type="submit" value="Upload file" />
    }
    
    <script type="text/javascript">
        $('form').validate({
            rules: {
                file: {
                    remote: $('#file').data('remote-val-url')
                }
            },
            messages: {
                file: {
                    remote: 'Please select an Excel file'
                }
            }
        });
    </script>
    

    在服务器上:

    public ActionResult CheckExtension(string file)
    {
        var extension = Path.GetExtension(file ?? string.Empty);
        var validExtensions = new[] { ".xls", ".xlsx" };
        var isValid = validExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase);
        return Json(isValid, JsonRequestBehavior.AllowGet);
    }
    

    【讨论】:

    • @Darin Dimitrov:感谢您的回答。您如何看待调用操作方法而不是在 jQuery 中执行检查?
    • @Francesco,我认为没有必要。如果此操作所做的只是验证扩展,则可以在客户端上完成。为什么要浪费带宽?
    • @Darin Dimitrov:例如,如果您概括案例并希望在具有不同文件类型的其他应用程序中重用该功能。
    • @Francesco,custom jquery plugin 似乎是在不同应用程序之间重用功能的好方法。
    • @Darin Dimitrov:适用于应用程序的文件类型存储在数据库中的情况如何?
    猜你喜欢
    • 1970-01-01
    • 2017-03-10
    • 2021-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-17
    • 1970-01-01
    相关资源
    最近更新 更多