首页 > 解决方案 > 如何在 asp.net mvc 中更新图像?

问题描述

我有一个包含图像路径的表。在控制器中我有这个方法

public string uploadimage(HttpPostedFileBase file)
        {
            Random r = new Random();
            string path = "-1";
            int random = r.Next();
            if (file != null && file.ContentLength > 0)
            {
                string extension = Path.GetExtension(file.FileName);
                if (extension.ToLower().Equals(".jpg") || extension.ToLower().Equals(".jpeg") || extension.ToLower().Equals(".png"))
                {
                    try
                    {
                        path = Path.Combine(Server.MapPath("~/Content/Images"), random + Path.GetFileName(file.FileName));
                        file.SaveAs(path);
                        path = "~/Content/Images/" + random + Path.GetFileName(file.FileName);
                    }
                    catch (Exception ex)
                    {
                        path = "-1";
                    }
                }
                else
                {
                    Response.Write("<script>alert('Only jpg ,jpeg or png formats are acceptable....'); </script>");
                }
            }
            else
            {
                Response.Write("<script>alert('Please select a file'); </script>");
                path = "-1";
            }
            return path;
        }

我在 Create ActionResult 中成功使用了它,但在 Edit ActionResult 中找不到正确的使用方法。我试过这段代码:

public ActionResult Edit([Bind(Include = "Id,Name,Location,Image")] Restaurant restaurant, HttpPostedFileBase imgfile)
        {
            string path = uploadimage(imgfile);
            if (ModelState.IsValid)
            {
                restaurant.Image = path;
                db.Entry(restaurant).State = EntityState.Modified;
                db.SaveChanges();
                return RedirectToAction("Success", "Home");
            }
            return View(restaurant);
        }

不幸的是,它不起作用,因为当我选择并添加新照片时,它说 Image 是必需的。编辑视图:

    @model RestaurantApp.Models.Restaurant

@{
    ViewBag.Title = "Edit";
}

<h2>Изменить</h2>

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

<div class="form-horizontal">
    <h4>Ресторан</h4>
    <hr />
    @Html.ValidationSummary(true, "", new { @class = "text-danger" })
    @Html.HiddenFor(model => model.Id)

    <div class="form-group">
        @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Location, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Location, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Location, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Image, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            <input type="file" id="imgfile" name="imgfile" class="btn btn-info" />
            @Html.ValidationMessageFor(model => model.Image, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="Сохранить" class="btn btn-default" />
        </div>
    </div>
</div>
}

我的餐厅模型:

public class Restaurant
    {

        public int Id { get; set; }
        [Required]
        [Display(Name = "Имя Ресторана")]
        public string Name { get; set; }
        [Required]
        [Display(Name = "Адрес Ресторана")]
        public string Location { get; set; }
        [Required]
        [Display(Name = "Логотип Ресторана")]
        public string Image { get; set; }
        [InverseProperty("Restaurant")]
        public ICollection<UserRole> UserRoles { get; set; }

        [InverseProperty("Restaurant")]
        public ICollection<Menu> Menus { get; set; }
    }

我认为这意味着图像路径为空,但我也尝试使用 db.Add 方法,但它也不起作用。我将编辑视图修改为创建视图,因此问题不在视图中。你能建议我如何解决这个问题吗?

标签: asp.netasp.net-mvc

解决方案


但它说 Image 是必需的。

图像按要求显示,因为在您的视图中您没有 的输入字段Model.Image,您拥有的是 的输入字段imgFile

要解决此问题,您只需提前移动restaurant.Image = path;ModelState.IsValid因为那是对正确模型属性进行评估的时间。

public ActionResult Edit([Bind(Include = "Id,Name,Location,Image")] Restaurant restaurant, HttpPostedFileBase imgfile)
{
   string path = uploadimage(imgfile);

   // move this here, so it has value before ModelState.IsValid
   restaurant.Image = path;

   if (ModelState.IsValid)
   {
      db.Entry(restaurant).State = EntityState.Modified;
      db.SaveChanges();
      return RedirectToAction("Success", "Home");
   }
   return View(restaurant);
}

然后在您的视图中,只需将 Restaurant 属性添加为隐藏,这样它们就不会被修改。使用@Html.HiddenFor().

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

   @*Add these properties*@
   @Html.HiddenFor(model=>model.Id)
   @Html.HiddenFor(model=>model.Name)
   @Html.HiddenFor(model=>model.Location)

   <div class="form-horizontal">
      <div class="form-group">
         @Html.LabelFor(model => model.Image, htmlAttributes: new { @class = "control-label col-md-2" })
         <div class="col-md-10">
            <input type="file" id="imgfile" name="imgfile" class="btn btn-info" />
               @Html.ValidationMessageFor(model => model.Image, "", new { @class = "text-danger" })
         </div>
      </div>

      <div class="form-group">
         <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="Сохранить" class="btn btn-default" />
         </div>
      </div>
   </div>
}

推荐阅读