将照片上传到 MVC 4 应用程序 [英] Upload Photo To MVC 4 Applications

查看:15
本文介绍了将照片上传到 MVC 4 应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个控制器来在我的 MVC4 应用程序中上传照片.但我不断收到此错误.输入不是有效的 Base-64 字符串,因为它包含非 Base-64 字符、两个以上的填充字符或填充字符中的非空白字符.

PhotosController.cs

 公共类 PhotoController : 控制器{公共 ActionResult 索引(){使用 (var ctx = new BlogContext()){返回视图(ctx.Photos.AsEnumerable());}}公共动作结果上传(){返回视图(新照片());}[HttpPost]公共动作结果上传(PhotoViewModel 模型){var photo = Mapper.Map(model);如果(模型状态.IsValid){PhotoRepository.Save(照片);return RedirectToAction("索引");}返回视图(照片);}}

Photo.cs

公开课照片{公共 int Id { 获取;放;}公共字节[]文件{获取;放;}公共字符串名称 { 获取;放;}公共字符串 描述 { 获取;放;}公共字符串 AlternateText { 获取;放;}}

PhotoViewModel.cs

公共类 PhotoViewModel{公共 int Id { 获取;放;}公共 HttpPostedFileBase 文件 { 获取;放;}公共字符串名称 { 获取;放;}公共字符串 描述 { 获取;放;}公共字符串 AlternateText { 获取;放;}}

/Photos/Upload.cshtml

 @model Rubish.Models.Photo@{ViewBag.Title = "上传";}<h2>上传</h2>@using (Html.BeginForm("Upload","Photo",FormMethod.Post,new {enctype="multipart/form-data"})) {@Html.ValidationSummary(true)<字段集><图例>照片</图例><div class="editor-label">@Html.LabelFor(model => model.Name)

<div class="editor-field">@Html.EditorFor(model => model.Name)@Html.ValidationMessageFor(model =>model.Name)

<div class="editor-label">@Html.LabelFor(model => model.Description)

<div class="editor-field">@Html.EditorFor(model => model.Description)@Html.ValidationMessageFor(model => model.Description)

<div class="editor-label"><label for="file">文件名:</label>

<div class="editor-field"><input name="File" id="File" type="file"/>

<p><输入类型=提交"值=创建"/></p></fieldset>}<div>@Html.ActionLink("返回列表", "索引")

@Scripts.Render("~/bundles/jqueryval")

图片库

公共类 PhotoRepository{私有静态 BlogContext _ctx;公共照片库(){_ctx = new BlogContext();}公共静态无效保存(照片p){_ctx.Photos.Add(p);_ctx.SaveChanges();}}

解决方案

问题是您的视图模型中有一个名为 File 的属性,其类型为 byte[] 并且您还使用了类型为 HttpPostedFileBase 的名为 file 的操作参数.问题在于,当模型绑定器在您的模型上遇到 byte[] 类型的属性时,它会尝试使用 base64 将其值与请求值绑定.除了在请求中你有一个上传文件的 multipart/form-data 编码值并且你得到一个异常.

解决此问题的正确方法是使用视图模型而不是将域模型传递给视图:

公共类 PhotoViewModel{公共 HttpPostedFileBase 文件 { 获取;放;}... 其他属性}

控制器动作现在将变成:

[HttpPost]公共动作结果上传(PhotoViewModel 模型){如果(模型状态.IsValid){//从视图模型映射域模型//现在作为参数//为此,我会推荐您使用 AutoMapper照片照片= ...//将领域模型传递给 DAL 层进行处理Repository.Save(照片);return RedirectToAction("索引");}返回视图(照片);}

我完全不推荐的糟糕方法是重命名您的文件输入以欺骗模型绑定器:

和您的控制器操作:

[HttpPost]公共动作结果上传(照片照片,HttpPostedFileBase 照片文件){...}

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屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆