Một khả năng là để viết một thuộc tính xác nhận tùy chỉnh:
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());
}
}
và sau đó bạn có thể có một mô hình điểm:
public class MyViewModel
{
[Required]
[MaxFileSize(8 * 1024 * 1024, ErrorMessage = "Maximum allowed file size is {0} bytes")]
public HttpPostedFileBase File { get; set; }
}
điều khiển:
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");
}
}
và một cái nhìn:
@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>
}
Bây giờ tất nhiên để làm việc này bạn sẽ phải tăng tối đa cho phép kích thước tập tin tải lên trong web.config đến một giá trị đủ lớn:
<!-- 1GB (the value is in KB) -->
<httpRuntime maxRequestLength="1048576" />
và cho IIS7:
<system.webServer>
<security>
<requestFiltering>
<!-- 1GB (the value is in Bytes) -->
<requestLimits maxAllowedContentLength="1073741824" />
</requestFiltering>
</security>
</system.webServer>
Bây giờ chúng tôi có thể mang thuộc tính xác thực tùy chỉnh của mình thêm một bước nữa và bật xác thực phía máy khách để tránh lãng phí băng thông. Tất nhiên xác minh kích thước tập tin trước khi tải lên chỉ có thể với HTML5 File API. Kết quả là chỉ những trình duyệt hỗ trợ API này mới có thể tận dụng lợi thế của nó.
Vì vậy, bước đầu tiên là làm cho thuộc tính xác nhận tùy chỉnh của chúng tôi thực hiện các giao diện IClientValidatable mà sẽ cho phép chúng tôi đính kèm một bộ chuyển đổi tùy chỉnh trong 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;
}
}
và tất cả những gì còn lại là cấu hình adapter tùy chỉnh:
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;
}, '');
Trước hết, cảm ơn Darin rất nhiều. Tôi đang cố gắng để thực hiện giải pháp của bạn tuy nhiên tôi dường như không thể sử dụng 'IClientValidatable'. Tôi có System.Web.Mvc cả hai được thêm vào trong các tài liệu tham khảo của dự án và trong các trang sử dụng. Tôi đang làm gì sai? –
Tôi không biết bạn đang làm gì sai. 'IClientValidatable' được thêm vào trong ASP.NET MVC 3 trong phần' System.Web.Mvc.dll' bên trong không gian tên 'System.Web.Mvc'. –
Tôi đã xác minh và tôi đã nhầm lẫn khi nghĩ rằng chúng tôi đang sử dụng MVC3, chúng tôi đang sử dụng MVC2. Kể từ khi nâng cấp không phải là một lựa chọn cho tôi, bất kỳ phần nào của giải pháp này vẫn được áp dụng? –