【问题标题】:MVC save image to DB (with EF)MVC 将图像保存到数据库(使用 EF)
【发布时间】:2018-01-30 04:27:15
【问题描述】:

我还是 MVC 的新手,正在努力将图像上传到我的 Web 应用程序中的数据库。我已经看过大量关于该主题的文章,按照说明进行操作,但我仍然遇到以下错误消息:

输入不是有效的 Base-64 字符串,因为它包含非 base 64 字符、两个以上的填充字符或填充字符中的非法字符。

每当我使用 [Bind(Exclude = "CompetitionPicture")] 时,一切都会正常工作,当然,除了 "CompetitionPicture" 不会被包含在内。

我的 ViewModel 如下所示:

public class PhotoCompetition
{
    public int ID { get; set; }

    public string UserID { get; set; }

    public string FirstName { get; set; }

    public string Email { get; set; }

    public byte[] CompetitionPicture { get; set; }

    [Required]
    [Display(Name = "by checking this box I accept the Terms & Conditions")]
    public bool TermsAndConditionsAccepted { get; set; }

    public DateTime TimeStamp { get; set; }
}

控制器如下:

[HttpPost]
    [ValidateAntiForgeryToken]

    public ActionResult UploadCompetitionPicture(/*[Bind(Exclude = "CompetitionPicture")]*/ PhotoCompetition model)
    {
        string test = Request.Form["CompetitionPicture"];
        byte[] bt = Convert.FromBase64String(test.Split(',')[1]);
        var participation = new PhotoCompetition
        {
            CompetitionPicture = bt
        };

        //    var participation = new PhotoCompetition
        //    {
        //        UserID = User.Identity.GetUserId(),
        //        Email = User.Identity.GetUserName(),
        //        TermsAndConditionsAccepted = model.TermsAndConditionsAccepted,
        //        TimeStamp = DateTime.UtcNow.ToUniversalTime()
        //    };
        //    participation.CompetitionPicture = competitionPicture;
        //    DB.PhotoCompetition.Add(model);
        //    DB.SaveChanges();
        //    return RedirectToAction("Index");
        //}
        return View(model);
    }

和视图:

<section id="photoCompetition" class="manageForm">
    @using (Html.BeginForm("UploadCompetitionPicture", "errandom", FormMethod.Post, new { @id = "photoCompetitionForm", @class = "form-horizontal", @role = "form", @enctype = "multipart/form-data" }))
    {
        @Html.AntiForgeryToken()
        <div id="photoCompetitionSection" class="manageSection">
            <p id="photoCompetitionSectionTitle" class="manageSectionTitle">
                Upload your picture and be selected as our model!
            </p>
            @Html.HiddenFor(m => m.UserID)
            @Html.HiddenFor(m => m.Email)
            @Html.HiddenFor(m => m.FirstName)
            @Html.HiddenFor(m => m.TimeStamp)
            <div id="photoCompetitionProfilePictureArea" class="manageArea row">
                @Html.LabelFor(m => m.CompetitionPicture, new { @id = "photoCompetitionProfilePictureLabel", @class = "manageLabel col-xs-offset-1 col-xs-10 col-sm-offset-1 col-sm-10 col-md-offset-1 col-md-3 col-lg-offset-1 col-lg-4" })
                <a id="photoCompetitionProfilePictureSelectionButton" class="manageField col-xs-offset-1 col-xs-10 col-sm-offset-1 col-sm-10 col-md-offset0 col-md-7 col-lg-offset-0 col-lg-6" href="#">
                    select a file...
                </a>
                @Html.TextBoxFor(m => m.CompetitionPicture, new { @id = "photoCompetitionProfilePictureField", @class = "manageField col-xs-offset-1 col-xs-10 col-sm-offset-1 col-sm-10 col-md-offset-0 col-md-7 col-lg-offset-0 col-lg-6", @name = "CompetitionPicture", @type = "file", @style = "display: none" })
            </div>
            <div id="photoCompetitionTermsAndConditionsArea" class="manageArea row">
                @Html.CheckBoxFor(m => m.TermsAndConditionsAccepted, new { @id = "photoCompetitionTermsAndConditionsField", @class = "photoCompetitionTermsAndConditionsField" })
                @Html.LabelFor(m => m.TermsAndConditionsAccepted, new { @id = "photoCompetitionTermsAndConditionsLabel", @class = "photoCompetitionTermsAndConditionsLabel" })
            </div>
            <script>
                jQuery("#photoCompetitionProfilePictureSelectionButton").click(function () {
                    $("#photoCompetitionProfilePictureField").click();
                });
            </script>
            <script>
                $("#photoCompetitionProfilePictureField").change(function () {
                    var fullFileName = $("#photoCompetitionProfilePictureField").val()
                    $("#photoCompetitionProfilePictureSelectionButton").html(fullFileName.substr(fullFileName.lastIndexOf('\\') + 1));
                });
            </script>
            <div id="photoCompetitionButtonArea" class="manageArea row">
                <input id="photoCompetitionButtonUpload" class="manageButton col-xs-offset-1 col-xs-10 col-sm-offset-1 col-sm-10 col-md-offset-1 col-md-10 col-lg-offset-1 col-lg-10" type="submit" value="Save" />
            </div>
        </div>
    }
</section>

非常感谢您的支持!

【问题讨论】:

  • 在通过添加个人资料图片来自定义用户个人资料(ASP 身份)时,我可能必须指定同样的方法对我有用。因此,我假设相同的逻辑/代码也适用于任何其他站点?!

标签: sql asp.net-mvc image entity-framework


【解决方案1】:

我在这个问题上卡了几天,我会简单地解决。

首先:我将图像路径保存为 DB 中的字符串而不是字节 和图像文件作为模型中的 HttpPostedFileBase 像:`

public string ProductImage { get; set; }
[Required(ErrorMessage = "Image is required")]
public HttpPostedFileBase ImageFile { get; set; }

鉴于你会写:

  <div class="form-group">
            <div class="col-md-10">
                <input type="file" name="ImageFile" required />
            </div>
            @Html.ValidationMessageFor(model => model.ImageFile, "", new { @class = "text-danger" })
        </div>

输入的名称必须与模型中的名称相同,这里我将其命名为 ImageFile

在控制器中会写

 public void SaveImage(Product pro)
    {
        string fileName = Path.GetFileNameWithoutExtension(pro.ImageFile.FileName);
        string exetention = Path.GetExtension(pro.ImageFile.FileName);
        fileName = fileName + DateTime.Now.ToString("yymmssfff") + exetention;
        pro.ProductImage = "~/ProductDropBox/" + fileName;
        fileName = Path.Combine(Server.MapPath("~/ProductDropBox/"), fileName);
        pro.ImageFile.SaveAs(fileName);
    }

我使用此功能将图像保存在数据库和为图像创建的文件夹中

最终你会写出行动结果:

 public ActionResult AddProducts(Product pro)
    {

        if (ModelState.IsValid)
        {
            SetCategories();
            SaveImage(pro);
            pro.UPID = Guid.NewGuid();

            using (db)
            {
                db.Products.Add(pro);
                db.SaveChanges();
            }                
            return RedirectToAction("Index");
        }
        else
        {
            return View("AddProducts",pro);
        }
    }

希望对你有用

【讨论】:

  • 感谢 Mahmoud 在这里的支持!我真的无法判断这是否有效,因为现在系统抱怨当我通过 add-migration PS 命令添加必要的迁移时没有定义主键。我试图通过将 [Key] 标签添加到 ID 来解决此问题,但收效甚微.. 有什么建议吗?另外,您介意解释一下为什么需要进行上述更改吗?作为我的用户个人资料(身份)的一部分,我的个人资料图片上传工作完全相同。这看起来很奇怪,不是吗?
  • 另外,在更仔细地研究了你的方法之后,我想强调我的意图是将图像作为字节保存到数据库,而不是通过保存在数据库中的路径来引用它.谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-08-04
  • 2020-02-10
  • 2019-06-27
  • 1970-01-01
相关资源
最近更新 更多