【问题标题】:ASP.NET MVC - How to upload an image and save URL in the databaseASP.NET MVC - 如何上传图像并将 URL 保存在数据库中
【发布时间】:2017-01-04 01:54:17
【问题描述】:

如果有人可以帮助我,我将不胜感激。我在视图中的表单中输入了文件控件,当有人选择图片并单击表单上的提交按钮时,该文件必须保存在应用程序的 /Pictures 文件夹中,并且文件路径需要保存在 SQL 数据库中字符串(如:/图片/文件名)。

模型类部分:

[Table("Automobil")]
public partial class Automobil
{   .....
    [Required]
    [StringLength(30)]
    public string Fotografija{ get; set; }
    ......

查看(创建)文件部分:

@using (Html.BeginForm("Create", "Automobili", FormMethod.Post, new { enctype = "multipart/form-data" }))

....
<div class="form-group">
            <div class="editor-field">
                @Html.TextBoxFor(model => model.Fotografija, new { type = "file" })
                @Html.ValidationMessageFor(model => model.Fotografija, "", new { @class = "text-danger" })
            </div>
        </div>
....

控制器部分:

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create([Bind(Include = "AutomobilID,Marka,Model,Godiste,Zapremina_motora,Snaga,Gorivo,Karoserija,Fotografija,Opis,Cena,Kontakt")] Automobil automobil)
    {
        if (ModelState.IsValid)
        {
                db.Automobils.Add(automobil);
                db.SaveChanges();
                return RedirectToAction("Index");
        }

        return View(automobil);
    }

我需要做什么才能将照片(Fotografija)保存在应用程序文件夹 Pictures 中,以及 SQL 库中的文件路径(如 /Pictures/filename)?

提前感谢您对初学者的帮助。

【问题讨论】:

  • 不要将完整路径放入数据库 - 只需放入文件名。这样,如果您重新定位或重命名包含文件夹,您将不需要进行任何数据更改,您只需要在一个地方更改代码(假设您的代码结构正确)
  • 当我只使用上面的代码时,我得到验证错误,图片必须有多达 30 个字符。此外,它不会将图片本身保存在应用程序中。
  • 删除[StringLength(30)]
  • 还是不行。如果我删除 [StringLength(30)] 代码会通过,但图片会以“System.Web.HttpPostedFileWrapper”的名称保存在 SQL 数据库中,并且图片文件不会保存在应用程序中。所以我在数据库中保存url肯定是缺少一些东西,很明显,在应用程序中保存图片文件的代码也丢失了。
  • Почему бы тебе не задать свой вопрос на русском форуме?

标签: c# jquery html asp.net asp.net-mvc


【解决方案1】:

看起来您的Fotografija 属性是字符串类型,您希望在其中保存唯一文件名。您不想使用该字段从浏览器获取文件。让我们为此使用另一个输入字段。

@using (Html.BeginForm("Index", "Home", FormMethod.Post, 
                                                   new { enctype = "multipart/form-data" }))
{
  <div class="form-group">
        <div class="editor-field">
            @Html.TextBoxFor(model => model.Model)
            @Html.ValidationMessageFor(model => model.Model)
        </div>
    </div>
    <!-- TO DO : Add other form fields also -->

    <div class="form-group">
        <div class="editor-field">
           <input type="file" name="productImg" />
        </div>
    </div>
    <input type="submit" />
}

现在更新您的 HttpPost 操作方法,增加一个 HttpPostedFileBase 类型的参数。这个参数的名字应该和我们添加的输入文件字段名一样(productImg)

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "AutomobilID,Marka,Model,Godiste,
          Zapremina_motora,Snaga,Gorivo,Karoserija,Opis,Cena,Kontakt")] Automobil automobil, 
                                           HttpPostedFileBase productImg)
{
    if (ModelState.IsValid)
    {
        if(productImg!=null)
        {
          var fileName = Path.GetFileName(productImg.FileName);
          var directoryToSave = Server.MapPath(Url.Content("~/Pictures"));

           var pathToSave = Path.Combine(directoryToSave, fileName);
           productImg.SaveAs(pathToSave);
           automobil.Fotografija= fileName;
        } 

        db.Automobils.Add(automobil);
        db.SaveChanges();
        return RedirectToAction("Index");
    }

    return View(automobil);
}

您必须删除 Fotografija 字段上的任何验证数据注释装饰(例如:[Required][MinLength] 等)。

我还强烈建议您在保存为唯一文件之前更新fileName,以避免现有文件发生冲突/覆盖。您可以将 DateTime 当前值添加到文件名(在扩展名之前)以使其唯一

【讨论】:

  • 非常感谢您抽出宝贵时间帮助我。我很感激。现在可以了。如果你有更多的时间,你能告诉我现在在没有 Fotografija 属性注释的情况下该怎么做吗?我应该对 productImg 进行限制(以及将它们放在哪里)?非常感谢。
  • 你可以保留MaxLength来控制表格列的长度。该属性仅用于存储文件名。
  • 再次感谢。享受这一天。
  • 你好,Shyju,我现在在编辑部分。你能帮我吗?我在上面发布了基本代码,您的第一个答案。不知道怎么写在评论里。
  • 我正在努力完成这项工作,现在我不知道该怎么做的唯一一件事是当我单击编辑时如何使编辑页面将文件存储在输入控件中。因此,当我在编辑页面上时,我需要以某种方式制作“productImg”以将我的文件存储在那里。
【解决方案2】:

我在控制器中的代码是基本的:

// GET: Automobili/Edit/5
    public ActionResult Edit(int? id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        Automobil automobil = db.Automobils.Find(id);
        if (automobil == null)
        {
            return HttpNotFound();
        }
        return View(automobil);
    }

    // POST: Automobili/Edit/5
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Edit([Bind(Include = "AutomobilID,Marka,Model,Godiste,Zapremina_motora,Snaga,Gorivo,Karoserija,Fotografija,Opis,Cena,Kontakt")] Automobil automobil)
    {
        if (ModelState.IsValid)
        {
            db.Entry(automobil).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        return View(automobil);
    }

如何改成与上面的创建代码兼容?

谢谢。

【讨论】:

    猜你喜欢
    • 2015-10-26
    • 2017-04-26
    • 1970-01-01
    • 2016-03-17
    • 2017-06-28
    • 2014-08-09
    • 2018-09-05
    • 2011-10-25
    相关资源
    最近更新 更多