我有一个名为ValidateFileAttribute的文件,用于验证图像上传的正确输入。就像这样:使用ValidateFileAttribute验证图像
public class ValidateFileAttribute : RequiredAttribute
{
public override bool IsValid(object value)
{
var file = value as HttpPostedFileBase;
if (file == null)
{
return false;
}
if (file.ContentLength > 1 * 1024 * 1024)
{
return false;
}
try
{
using (var img = Image.FromStream(file.InputStream))
{
return img.RawFormat.Equals(ImageFormat.Jpeg);
}
}
catch { }
return false;
}
}
,这是模型的propertie:
[DisplayName("Image")]
[ValidateFile(ErrorMessage = "Please select a PNG image smaller than 1MB")]
public byte[] Image { get; set; }
,这是我的看法:
<div id="upload-choices">
<div class="editor-label">
@Html.LabelFor(m => m.Image)
@Html.ValidationMessageFor(model => model.Image)
</div>
<div class="editor-row">
@Html.ValidationSummary(true)
</div>
</div>
但每次我尝试上传图片(这是png小于1MB)我得到这个错误:
var file = value as HttpPostedFileBase;
file is null。
谢谢
这是一个完整的视图:
<div id="tabs-2">
@using (Html.BeginForm("EditPhotos", "Account", FormMethod.Post, new { id = "form", enctype = "multipart/form-data" }))
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Photos</h4>
<hr />
@Html.HiddenFor(model => model.Id)
<div class="editor-label">
@Html.LabelFor(model => model.DisplayItem)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.DisplayItem)
</div>
<div id="upload-choices">
<div class="editor-label">
@Html.LabelFor(m => m.Image)
@Html.ValidationMessageFor(model => model.Image)
</div>
<div class="editor-row">
@Html.ValidationSummary(true)
</div>
</div>
<br />
<div class="table-responsive">
<table class="table">
<tr>
<th><img width="200" height="150" src="@Url.Action("GetImage", "Account", new { id = Model.Id })"></th>
</tr>
</table>
</div>
<input type="file" name="file" class="filestyle" data-buttontext="Find file">
<br />
<div class="progress progress-striped">
<div class="progress-bar progress-bar-success">0%</div>
</div>
<div id="status"></div>
<br />
@*@Html.ActionLink("Upload photos", "Upload")*@
<div class="pull-left">
<div class="col-md-offset-0">
<input type="submit" value="Save" accept="image/x-png, image/gif, image/jpeg" class="btn btn-default pull-left" />
</div>
</div>
</div>
}
<br /><br />
<div>
@Html.ActionLink("Back to List", "Index")
</div>
</div>
,这是操作方法:
[HttpPost]
public ActionResult EditPhotos(UserProfile userprofile, HttpPostedFileBase file)
{
if (file != null)
{
// extract only the fielname
var fileName = Path.GetFileName(file.FileName);
// store the file inside ~/App_Data/uploads folder
var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);
file.SaveAs(path);
ModelState.Clear();
}
if (ModelState.IsValid)
{
string username = User.Identity.Name;
// Get the userprofile
UserProfile user = db.userProfiles.FirstOrDefault(u => u.UserName.Equals(username));
// Update fields
user.Image = new byte[file.ContentLength];
file.InputStream.Read(user.Image, 0, file.ContentLength);
user.ImageMimeType = file.ContentType;
db.Entry(user).State = EntityState.Modified;
try
{
db.SaveChanges();
}
catch (DbEntityValidationException e)
{
foreach (var eve in e.EntityValidationErrors)
{
Console.WriteLine("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:",
eve.Entry.Entity.GetType().Name, eve.Entry.State);
foreach (var ve in eve.ValidationErrors)
{
Console.WriteLine("- Property: \"{0}\", Error: \"{1}\"",
ve.PropertyName, ve.ErrorMessage);
}
}
throw;
}
}
return RedirectToAction("Edit", routeValues: new { controller = "Account", activetab = "tabs-2" });
}
,没有:[ValidateFile(的ErrorMessage =“请选择一个PNG图像小于1MB“)]我可以上传图像。但ofcourse它必须与验证
我有现在这样的:
public override bool IsValid(object value)
{
var ImageProfile = value as byte[];
if (ImageProfile == null)
{
return false;
}
if (ImageProfile.ContentLength > 1 * 1024 * 1024)
{
return false;
}
try
{
using (var img = Image.FromStream(ImageProfile.InputStream))
{
return img.RawFormat.Equals(ImageFormat.Jpeg);
}
}
catch { }
return false;
}
和propertie:
[DisplayName("ImageProfile")]
[ValidateFile(ErrorMessage = "Please select a PNG image smaller than 1MB")]
public byte[] ImageProfile { get; set; }
奥凯,我现在有这样的:
public override bool IsValid(object value)
{
var ImageProfile = value as byte[];
if (ImageProfile == null)
{
return false;
}
if (ImageProfile.Length > 1 * 1024 * 1024)
{
return false;
}
try
{
using (var binaryReader = new BinaryReader(HttpContext.Current.Request.Files[0].InputStream))
{
//return img.RawFormat.Equals(ImageFormat.Jpeg);
ImageProfile = binaryReader.ReadBytes(HttpContext.Current.Request.Files[0].ContentLength);
}
}
catch { }
return false;
}
但ImageProfile仍为空?怎么可能?
如果我改变了:
[DisplayName("ImageProfile")]
[ValidateFile(ErrorMessage = "Please select a PNG image smaller than 1MB")]
public HttpPostedFileBase ImageProfile { get; set; }
那么这将不再工作:
user.ImageProfile = new byte[file.ContentLength];
file.InputStream.Read(user.ImageProfile, 0, file.ContentLength);
在这个方法:
[HttpPost]
//[ValidateAntiForgeryToken]
public ActionResult EditPhotos(UserProfile userprofile, HttpPostedFileBase file)
{
if (file != null)
{
// extract only the fielname
var fileName = Path.GetFileName(file.FileName);
// store the file inside ~/App_Data/uploads folder
var path = Path.Combine(Server.MapPath(@"\\Images"), fileName);
file.SaveAs(path);
ModelState.Clear();
}
if (ModelState.IsValid)
{
string username = User.Identity.Name;
// Get the userprofile
UserProfile user = db.userProfiles.FirstOrDefault(u => u.UserName.Equals(username));
// Update fields
user.ImageProfile = new byte[file.ContentLength];
file.InputStream.Read(user.ImageProfile, 0, file.ContentLength);
user.ImageMimeType = file.ContentType;
db.Entry(user).State = EntityState.Modified;
try
{
db.SaveChanges();
}
catch (DbEntityValidationException e)
{
foreach (var eve in e.EntityValidationErrors)
{
Console.WriteLine("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:",
eve.Entry.Entity.GetType().Name, eve.Entry.State);
foreach (var ve in eve.ValidationErrors)
{
Console.WriteLine("- Property: \"{0}\", Error: \"{1}\"",
ve.PropertyName, ve.ErrorMessage);
}
}
throw;
}
}
return RedirectToAction("Edit", routeValues: new { controller = "Account", activetab = "tabs-2" });
}
这:
公众的ActionResult GetImage(int id) var image = db.userProfiles.Where(p => p.Id == id).Select(img => img.ImageProfile).FirstOrDefault();
var stream = new MemoryStream(image.ToArray());
return new FileStreamResult(stream, "image/jpeg");
}
但仍得到一个错误在这条线:var stream = new MemoryStream(image.ToArray());
也许你实际上没有上传f ILE。我没有看到表单元素,因此我不能说你是否正确地做了这件事。表单的内容类型应该是'multipart/form-data'。你调试了你的代码吗?你的属性中的'value'是否真的是'null'? – 2014-10-28 10:06:24
感谢您的评论,我更新了我的文章 – 2014-10-28 10:12:59
模型上的属性是一个'byte []',但验证器试图将值作为'HttpPostedFileBase'转换,你不能这样做,与您的模型类型兼容,即更改验证器以使用字节数组。 – 2014-10-28 10:14:53