在MVC(模型视图控制器)中开发时避免使用模型并不是一个好主意。正如MVC的含义所说,大多数情况下,在使用IsValid方法将数据保存到数据库之前,您应该验证模型。我可以给你的建议是忘记你的工作方式,因为它不安全。如果不使用模型的isvalid方法,您应该保护您的网站免受XSS脚本攻击和其他类型的攻击。模型的主要优点是您可以在保存这些数据之前轻松验证它,并且您可以通过创建自己的验证属性来轻松解决此类问题,这将在服务器端和客户端中检查这些数据。忘记你正在做的事情,并试着了解自定义验证。但是,我可以分享这个代码,如果您使用的是模型,它将检查服务器中的文件类型。
public class FileTypeAttribute : ValidationAttribute
{
public string thefile{ get; set; }
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
PropertyInfo[] propriétés = validationContext.ObjectType.GetProperties();
PropertyInfo lafichies = propriétés.FirstOrDefault(p => p.Name == lefichier);
HttpPostedFileBase valFichierChoisi = thefile.GetValue(validationContext.ObjectInstance, null) as HttpPostedFileBase;
byte[] chkBytejpg = { 255, 216, 255, 224 };
byte[] chkBytejpg2 = { 255, 216, 255, 225 };
if (value != null && value.Equals(valFichierChoisi))
{//we check the type for jpeg file
//-------------------------------------------
if (valFichierChoisi.ContentType.ToLower() != "image/jpg" &&
valFichierChoisi.ContentType.ToLower() != "image/jpeg" &&
valFichierChoisi.ContentType.ToLower() != "image/pjpeg")
{
return new ValidationResult(ErrorMessage);
}
// Attempt to read the file and check the first bytes
//-------------------------------------------
try
{
if (!valFichierChoisi.InputStream.CanRead)
{
return new ValidationResult(ErrorMessage);
}
if (valFichierChoisi.ContentLength < ImageMinimumBytes)
{
return new ValidationResult(ErrorMessage);
}
byte[] buffer = new byte[valFichierChoisi.ContentLength];
valFichierChoisi.InputStream.Read(buffer, 0, valFichierChoisi.ContentLength);
string content = System.Text.Encoding.UTF8.GetString(buffer);
if (Regex.IsMatch(content, @"<script|<html|<head|<title|<body|<pre|<table|<a\s+href|<img|<plaintext|<cross\-domain\-policy",
RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Multiline))
{
return new ValidationResult(ErrorMessage);
}
//you compare buffer sequence of file and known byte of jpeg in .net
if (chkBytejpg.SequenceEqual(buffer.Take(chkBytejpg.Length)))
{
return ValidationResult.Success;
}
else if (chkBytejpg2.SequenceEqual(buffer.Take(chkBytejpg2.Length)))
{
return ValidationResult.Success;
}
}
catch (Exception)
{
return new ValidationResult(ErrorMessage);
}
//-------------------------------------------
// Try to instantiate new Bitmap, if .NET will throw exception
// we can assume that it's not a valid image
//-------------------------------------------
try
{
using (var bitmap = new System.Drawing.Bitmap(valFichierChoisi.InputStream))
{
}
}
catch (Exception)
{
return new ValidationResult(ErrorMessage);
}
}
return ValidationResult.Success;
}
}
我做了它的服务器端。对于客户端验证,仅仅因为一个原因使用jquery unobstrusive验证会更困难:它需要返回一个值。让我解释。假设这个验证结果。
$.validator.unobtrusive.adapters.add('fichimage', ['thefile'],
function (options) {
options.rules['fichimage'] = options.params;
if (options.message) {
options.messages['fichimage'] = options.message;
}
}
);
$.validator.addMethod('fichimage', function (value, element, params) {
var lechoifait = $('input[name="' + params.thefile+ '"]').val();
if (value != null && value == lechoifait) {
//suppose that your browser allow the use of filereader
//know that you can obtain the selected file by using element.files[0]
var fr = new FileReader();
fr.onloadend = function (e) {
//Because this is done asynchronously
// the return will always be true for this validation no matter the kind of file
//apart of this, if you want to use any callback function, you will use it in this function which don't allows any return
};
fr.readAsDataURL(element.files[0]);
}
//this will always be true because of the asynchronously behaviour of onloadend function
return true;
}, '');
这就是为什么我建议您实现自己的方式来解决这个
基于答案给由@Drakes(How to check file MIME type with javascript before upload?),我提出了这个答案。
假设在成功的情况下,要加载此图像在图像
<img id="imagetoshow" alt="" src="" style=" width :80%; height :300px; display:none; "/>
因为您正在使用MVC的工作,你的HTML帮助可能是类似的东西
@Html.TextBoxFor(m => m.selectedimage, new { type = "file", @class = "someclass", onchange = "checkandshow(this)" })
//this validation message is for checking for server side
//try another way if you are not using a model as claimed
@Html.ValidationMessageFor(m => m.selectedimage)
//you could use this label in the case of incorrect file
@Html.Label("", new { id = "badfile", @class = "badimageselected"})
在选择图像的情况下(我只检查jpeg),将执行checkandshow(this)函数。为他人类型的文件的签名,请参阅本(https://en.wikipedia.org/wiki/List_of_file_signatures)和/或本(https://mimesniff.spec.whatwg.org/#matching-an-image-type-pattern)
function checkandshow(input) {
//imagetoshow is the id of the image tag where you want to load your image in the case of success
$('#imagetoshow').attr('src', '');
//you first check if the element contains any file
if (input.files && input.files[0]) {
// you check if the browser support filereader
if (window.FileReader && window.Blob) {
//because the browser support this, you create an object of this class
var filerdr = new FileReader();
filerdr.onload = function (e) {
//this subarray will allows you to check the first 4 bytes of the image
var arr = (new Uint8Array(e.target.result)).subarray(0, 4);
var header = "";
for (var i = 0; i < arr.length; i++) {
header += arr[i].toString(16);
}
//typeFichier function will allows you obtaining the real mime of the file
var letype = typeFichier(header);
if (letype != 'image/jpeg') {
//in the case that it is not you type of file, just do whatever you want
//set the text in the label to prevent the user of this bad file
$("#badfile").text('The selected file is not a jpeg or jpg file.');
}
else {
//in the case of the good real MIME, you remove the text in the label and then load your image to the corresponding place
$("#badfile").text('');
//you just load the correct image
var loaderfr = new FileReader();
loaderfr.onload = function (c) {
//because the image is just show when you select the file, you change display: none and allow it be seen
$("#imagetoshow").show()
$('#imagetoshow').attr('src', c.target.result);
}
//this is for loading the image
loaderfr.readAsDataURL(input.files[0]);
}
}
//this is for loading the array buffer which will allows the bytes of the file to be checked
filerdr.readAsArrayBuffer(input.files[0]);
} else {
//in the case that File and Blob are not supported
$("#imagetoshow").show()
//you change the height because you want to reduce the space
$('#imagetoshow').height(15);
$('#imagetoshow').attr('alt', 'Sorry, your browser do not allows a preview of the selected image, migrate to another version of the browser or to other browser which allows this preview.');
}
}
};
非图像类的标签可能是这样的
.nonimage { color: Red;font-weight:bold ; font-size:24px; }
这里是函数,它允许获得文件的真实MIME
function typeFichier(entete) {
switch (entete) {
case "ffd8ffe0":
case "ffd8ffe1":
case "ffd8ffe2":
type = "image/jpeg";
break;
default:
type = "unknown";
break;
}
return type;
};
如果您想使用模型,请不要忘记添加必需的属性,以便检查在服务器侧e文件,像这样
[Required(FileType="selectedimage", ErrorMessage = "It seems that your file is incorrect, please try another one.")]
public HttpPostedFileBase selectedimage{ get; set; }
我强烈建议你使用模型这种验证
有没有的。您需要创建自己的验证属性和关联的脚本以将方法添加到'jquery.validate'。例如,请参阅[本文](http://blog.2mas.xyz/creating-custom-unobtrusive-file-extension-validation-in-asp-net-mvc-3-and-jquery/)。 –
显示你的模特类 – anand
没有模特儿。这就是为什么我纯粹使用数据注释。 它是一种自动生成的表单,因此它可以包含X个不同类型的输入标签。这就是为什么最简单的验证方法是使用数据注释。它实际上就像一个魅力一样,除了为文件上传的“接受”属性提供消息外。 –