使用C#在ASP.NET MVC3中进行远程文件扩展名验证?

Cic*_*ami 3 c# file asp.net-mvc-3

我有一个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>        
    }  
Run Code Online (Sandbox Code Playgroud)

由控制器动作方法索引:

public ActionResult Index()
{
   return View("Index");
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

一旦用户尝试上传文件,我想这样做.是到了我心中的唯一事情是建立一个模型(或更好的视图模型),并使用远程验证DataAnnotations.

我看到了Scott Hanselman的现场演示,但看起来他并不是很舒服,因为应用程序正在编译但没有执行检查.

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

谢谢

弗朗切斯科

Dar*_*rov 5

你可以用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;
    });
});
Run Code Online (Sandbox Code Playgroud)

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


更新:

远程AJAX验证的示例(由于评论中的需求,我不推荐它).您可以使用优秀的jquery.validate插件,它与ASP.NET MVC 3捆绑在一起:

<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>
Run Code Online (Sandbox Code Playgroud)

并在服务器上:

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);
}
Run Code Online (Sandbox Code Playgroud)