Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/33.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 上载时验证是否存在大文件_C#_Asp.net_Validation_File Upload_Asp.net Mvc 2 - Fatal编程技术网

C# 上载时验证是否存在大文件

C# 上载时验证是否存在大文件,c#,asp.net,validation,file-upload,asp.net-mvc-2,C#,Asp.net,Validation,File Upload,Asp.net Mvc 2,我正在使用c MVC 2和ASP.NET。我的一个表单包含一个文件输入字段,允许用户选择任何文件类型,然后将其转换为blob并保存到数据库中。我的问题是,每当用户选择的文件超过了大约8 Mb的特定数量时,就会出现如下页面错误: The connection was reset The connection to the server was reset while the page was loading. 我不介意用户上传的文件有8Mb的限制,但是我需要阻止当前错误的发生,最好使用Model

我正在使用c MVC 2和ASP.NET。我的一个表单包含一个文件输入字段,允许用户选择任何文件类型,然后将其转换为blob并保存到数据库中。我的问题是,每当用户选择的文件超过了大约8 Mb的特定数量时,就会出现如下页面错误:

The connection was reset
The connection to the server was reset while the page was loading.

我不介意用户上传的文件有8Mb的限制,但是我需要阻止当前错误的发生,最好使用ModelState.addmodeleror函数显示正确的验证消息。有人能帮我吗?我似乎无法在页面中发生任何其他事情之前“捕获”错误,因为它发生在控制器的上载功能中。

我在谷歌上搜索了一下,找到了以下两个URL,这两个URL似乎表明最好在Global.asax中的应用程序错误事件中处理此问题或异常


一种可能是编写自定义验证属性:

public class MaxFileSizeAttribute : ValidationAttribute
{
    private readonly int _maxFileSize;
    public MaxFileSizeAttribute(int maxFileSize)
    {
        _maxFileSize = maxFileSize;
    }

    public override bool IsValid(object value)
    {
        var file = value as HttpPostedFileBase;
        if (file == null)
        {
            return false;
        }
        return file.ContentLength <= _maxFileSize;
    }

    public override string FormatErrorMessage(string name)
    {
        return base.FormatErrorMessage(_maxFileSize.ToString());
    }
}
控制器:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View(new MyViewModel());
    }

    [HttpPost]
    public ActionResult Index(MyViewModel model)
    {
        if (!ModelState.IsValid)
        {
            // validation failed => redisplay the view
            return View(model);
        }

        // the model is valid => we could process the file here
        var fileName = Path.GetFileName(model.File.FileName);
        var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);
        model.File.SaveAs(path);

        return RedirectToAction("Success");
    }
}
还有一个观点:

@model MyViewModel

@using (Html.BeginForm(null, null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    @Html.TextBoxFor(x => x.File, new { type = "file" })
    @Html.ValidationMessageFor(x => x.File)
    <button type="submit">OK</button>
}
当然,要使其正常工作,您必须将web.config中允许的最大上载文件大小增加到足够大的值:

<!-- 1GB (the value is in KB) -->
<httpRuntime maxRequestLength="1048576" />
对于IIS7:

<system.webServer>
    <security>
        <requestFiltering>
           <!-- 1GB (the value is in Bytes) -->
            <requestLimits maxAllowedContentLength="1073741824" />
        </requestFiltering>
    </security>
</system.webServer>
现在,我们可以进一步使用自定义验证属性,并启用客户端验证以避免浪费带宽。当然,上传前验证文件大小只能使用。因此,只有支持此API的浏览器才能利用它

因此,第一步是让我们的自定义验证属性实现接口,该接口将允许我们在javascript中附加自定义适配器:

public class MaxFileSizeAttribute : ValidationAttribute, IClientValidatable
{
    private readonly int _maxFileSize;
    public MaxFileSizeAttribute(int maxFileSize)
    {
        _maxFileSize = maxFileSize;
    }

    public override bool IsValid(object value)
    {
        var file = value as HttpPostedFileBase;
        if (file == null)
        {
            return false;
        }
        return file.ContentLength <= _maxFileSize;
    }

    public override string FormatErrorMessage(string name)
    {
        return base.FormatErrorMessage(_maxFileSize.ToString());
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        var rule = new ModelClientValidationRule
        {
            ErrorMessage = FormatErrorMessage(_maxFileSize.ToString()),
            ValidationType = "filesize"
        };
        rule.ValidationParameters["maxsize"] = _maxFileSize;
        yield return rule;
    }
}
剩下的就是配置自定义适配器:

jQuery.validator.unobtrusive.adapters.add(
    'filesize', [ 'maxsize' ], function (options) {
        options.rules['filesize'] = options.params;
        if (options.message) {
            options.messages['filesize'] = options.message;
        }
    }
);

jQuery.validator.addMethod('filesize', function (value, element, params) {
    if (element.files.length < 1) {
        // No files selected
        return true;
    }

    if (!element.files || !element.files[0].size) {
        // This browser doesn't support the HTML5 API
        return true;
    }

    return element.files[0].size < params.maxsize;
}, '');

您可以在web.config中增加某些URL的请求最大长度:

<location path="fileupload">
  <system.web>
    <httpRuntime executionTimeout="600" maxRequestLength="10485760" />
  </system.web>
</location>

首先,非常感谢你,达林。我正在尝试实现您的解决方案,但我似乎无法使用“IClientValidable”。我将System.Web.Mvc添加到项目的参考和页面使用中。我做错了什么?我不知道你做错了什么。IClientValidable被添加到ASP.NET MVC 3中System.Web.MVC.dll程序集的System.Web.MVC命名空间中。回答太棒了!不过,有一个问题。MaxFileSizeAttribute.IsValid在值为null时返回false,实际上需要上载文件。客户端javascript验证中存在一个小错误。最后一行应该是return元素。files[0]。size为防止进行所需检查,只需键入IsValid:if file==null return true;
<location path="fileupload">
  <system.web>
    <httpRuntime executionTimeout="600" maxRequestLength="10485760" />
  </system.web>
</location>