照片上传到MVC 4应用程序 [英] Upload Photo To MVC 4 Applications
问题描述
我试图创建一个控制器上传照片在我的MVC4应用。不过,我不断收到此错误。输入不是有效的Base-64串,因为它含有非基本64字符,两个以上的填充字符,或填充字符之间的非空白字符。
PhotosController.cs
公共类PhotoController:控制器
{
公众的ActionResult指数()
{
使用(VAR CTX =新BlogContext())
{
返回查看(ctx.Photos.AsEnumerable());
}
} 公众的ActionResult上传()
{
返回查看(新照片());
} [HttpPost]
公众的ActionResult上传(PhotoViewModel模型)
{
变种照片= Mapper.Map< PhotoViewModel,照片>(模型);
如果(ModelState.IsValid)
{
PhotoRepository.Save(照片);
返回RedirectToAction(「指数」);
}
返回查看(照片);
}
}
Photo.cs
公共类照片
{
公众诠释标识{搞定;组; } 公共字节[]文件{搞定;组; } 公共字符串名称{;组; } 公共字符串描述{搞定;组; } 公共字符串还有AlternateText {搞定;组; }
}
PhotoViewModel.cs
公共类PhotoViewModel
{
公众诠释标识{搞定;组; } 公共HttpPostedFileBase文件{搞定;组; } 公共字符串名称{;组; } 公共字符串描述{搞定;组; } 公共字符串还有AlternateText {搞定;组; }
}
/Photos/Upload.cshtml
@model Rubish.Models.Photo @ {
ViewBag.Title =上传;
} < H2>&上传LT; / H> @using(Html.BeginForm(上传,照片,FormMethod.Post,新{ENCTYPE =的multipart / form-data的})){
@ Html.ValidationSummary(真) <&字段集GT;
<传奇>照片及LT; /传说> < DIV CLASS =编辑标记>
@ Html.LabelFor(型号=> model.Name)
< / DIV>
< DIV CLASS =主编场>
@ Html.EditorFor(型号=> model.Name)
@ Html.ValidationMessageFor(型号=> model.Name)
< / DIV> < DIV CLASS =编辑标记>
@ Html.LabelFor(型号=> model.Description)
< / DIV>
< DIV CLASS =主编场>
@ Html.EditorFor(型号=> model.Description)
@ Html.ValidationMessageFor(型号=> model.Description)
< / DIV>
< DIV CLASS =编辑标记>
<标签=文件>文件名:其中; /标签>
< / DIV>
< DIV CLASS =主编场>
<输入名字=文件ID =文件类型=文件/>
< / DIV>
&所述p为H.;
<输入类型=提交值=创建/>
&所述; / P>
< /字段集>
} < DIV>
@ Html.ActionLink(返回目录,索引)
< / DIV> @ Scripts.Render(〜/包/ jqueryval)
PhotoRepository
公共类PhotoRepository
{
私有静态BlogContext _ctx; 公共PhotoRepository()
{
_ctx =新BlogContext();
} 公共静态无效保存(照片P)
{
_ctx.Photos.Add(P);
_ctx.SaveChanges();
}
}
的问题是,你有你的所谓视图模型属性文件
这类型的字节[]
和您还使用名为文件
的操作参数 HttpPostedFileBase
。问题是,当模型绑定遇到你的类型模式的属性字节[]
它会尝试它的值从使用Base64请求值绑定。除非你有一个的multipart / form-data的
连接上传的文件codeD的价值,你会得到一个异常请求里面。
解决这个问题的正确方法是使用视图模型,而不是通过你的域模型的意见:
公共类PhotoViewModel
{
公共HttpPostedFileBase文件{搞定;组; } ...其他属性
}
和控制器动作,现在将变成:
[HttpPost]
公众的ActionResult上传(PhotoViewModel模型)
{
如果(ModelState.IsValid)
{
//从地图视图模型,该诉讼领域模型
//现在只需为参数
//我建议你AutoMapper用于这一目的
写真照片= ... //把域模型来进行处理DAL层
Repository.Save(照片); 返回RedirectToAction(「指数」);
}
返回查看(照片);
}
可怜的方式完全不建议我是重命名文件的输入诱骗模型绑定:
<输入名称=PhotoFileID =文件类型=文件/>
和您的控制器动作:
[HttpPost]
公众的ActionResult上传(组图照片,HttpPostedFileBase photoFile)
{
...
}
I'm trying to create a controller to upload photos in my MVC4 application. But I keep getting this error. The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or a non-white space character among the padding characters.
PhotosController.cs
public class PhotoController : Controller
{
public ActionResult Index()
{
using (var ctx = new BlogContext())
{
return View(ctx.Photos.AsEnumerable());
}
}
public ActionResult Upload()
{
return View(new Photo());
}
[HttpPost]
public ActionResult Upload(PhotoViewModel model)
{
var photo = Mapper.Map<PhotoViewModel, Photo>(model);
if (ModelState.IsValid)
{
PhotoRepository.Save(photo);
return RedirectToAction("Index");
}
return View(photo);
}
}
Photo.cs
public class Photo
{
public int Id { get; set; }
public Byte[] File { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string AlternateText { get; set; }
}
PhotoViewModel.cs
public class PhotoViewModel
{
public int Id { get; set; }
public HttpPostedFileBase File { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string AlternateText { get; set; }
}
/Photos/Upload.cshtml
@model Rubish.Models.Photo
@{
ViewBag.Title = "Upload";
}
<h2>Upload</h2>
@using (Html.BeginForm("Upload","Photo",FormMethod.Post,new {enctype="multipart/form-data"})) {
@Html.ValidationSummary(true)
<fieldset>
<legend>Photo</legend>
<div class="editor-label">
@Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Name)
@Html.ValidationMessageFor(model => model.Name)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Description)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Description)
@Html.ValidationMessageFor(model => model.Description)
</div>
<div class="editor-label">
<label for="file">FileName:</label>
</div>
<div class="editor-field">
<input name="File" id="File" type="file"/>
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
@Scripts.Render("~/bundles/jqueryval")
PhotoRepository
public class PhotoRepository
{
private static BlogContext _ctx;
public PhotoRepository()
{
_ctx = new BlogContext();
}
public static void Save(Photo p)
{
_ctx.Photos.Add(p);
_ctx.SaveChanges();
}
}
The problem is that you have a property in your view model called File
which is of type byte[]
and you are also using an action parameter called file
of type HttpPostedFileBase
. The problem is that when the model binder encounters a property on your model of type byte[]
it attempts to bind its value from the request value using base64. Except that inside the request you have a multipart/form-data
encoded value of the uploaded file and you get an exception.
The correct way to fix this is to use view models instead of passing your domain models to the views:
public class PhotoViewModel
{
public HttpPostedFileBase File { get; set; }
... other properties
}
and the controller action will now become:
[HttpPost]
public ActionResult Upload(PhotoViewModel model)
{
if (ModelState.IsValid)
{
// map the domain model from the view model that the action
// now takes as parameter
// I would recommend you AutoMapper for that purpose
Photo photo = ...
// Pass the domain model to a DAL layer for processing
Repository.Save(photo);
return RedirectToAction("Index");
}
return View(photo);
}
The poor way and totally not recommended by me is to rename your file input to trick the model binder:
<input name="PhotoFile" id="File" type="file"/>
and your controller action:
[HttpPost]
public ActionResult Upload(Photo photo, HttpPostedFileBase photoFile)
{
...
}
这篇关于照片上传到MVC 4应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!