我有一個名爲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