将照片上传到MVC 4应用程序

Ant*_*yrd 6 asp.net-mvc controller file-upload view

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

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);
        }
    }
Run Code Online (Sandbox Code Playgroud)

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; }
    }
Run Code Online (Sandbox Code Playgroud)

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; }
    }
Run Code Online (Sandbox Code Playgroud)

/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")
Run Code Online (Sandbox Code Playgroud)

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();
        }
    }
Run Code Online (Sandbox Code Playgroud)

Dar*_*rov 15

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

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

public class PhotoViewModel
{
    public HttpPostedFileBase File { get; set; }

    ... other properties
}
Run Code Online (Sandbox Code Playgroud)

控制器动作现在变为:

[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);
}
Run Code Online (Sandbox Code Playgroud)

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

<input name="PhotoFile" id="File" type="file"/>
Run Code Online (Sandbox Code Playgroud)

和你的控制器动作:

[HttpPost]
public ActionResult Upload(Photo photo, HttpPostedFileBase photoFile)
{
    ...
}
Run Code Online (Sandbox Code Playgroud)