6

MVC4アプリケーションに写真をアップロードするためのコントローラーを作成しようとしています。しかし、私はこのエラーを受け取り続けます。入力は、非Base 64文字、3つ以上のパディング文字、またはパディング文字の間に非空白文字が含まれているため、有効なBase-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);
        }
    }

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();
        }
    }
4

1 に答える 1

15

問題は、ビューモデルにタイプのプロパティがFileあり、タイプのbyte[]アクションパラメータも使用していることです。問題は、モデルバインダーがタイプのモデルのプロパティに遭遇すると、base64を使用してリクエスト値からその値をバインドしようとすることです。ただし、リクエスト内にアップロードされたファイルのエンコードされた値があり、例外が発生します。fileHttpPostedFileBasebyte[]multipart/form-data

これを修正する正しい方法は、ドメインモデルをビューに渡す代わりに、ビューモデルを使用することです。

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

    ... other properties
}

コントローラのアクションは次のようになります。

[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);
}

悪い方法であり、私がまったくお勧めしないのは、ファイル入力の名前を変更してモデルバインダーをだますことです。

<input name="PhotoFile" id="File" type="file"/>

およびコントローラーのアクション:

[HttpPost]
public ActionResult Upload(Photo photo, HttpPostedFileBase photoFile)
{
    ...
}
于 2012-06-17T06:23:36.877 に答える