Создайте элемент и добавьте изображения для элемента за один шаг

#c# #asp.net-mvc #asp.net-mvc-4

#c# #asp.net-mvc #asp.net-mvc-4

Вопрос:

Я пытаюсь научиться ASP.net создав сайт электронной коммерции. Я пытаюсь настроить возможность создавать элементы и назначать изображения создаваемому элементу посредством загрузки файла.

Мне удалось заставить работать загрузку нескольких файлов, но только в папку content / Images. Я не могу понять, как связать это с созданием элементов, чтобы вы могли назначить несколько изображений элементу при создании элемента.

Было бы справедливо сказать, что я не знаю, куда идти дальше, и был бы признателен за любую помощь.

Класс модели элемента: таблица в базе данных для хранения каждого элемента. На него ссылаются из таблицы изображений с отношением от 1 до многих.

  public class Item
 {
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int ItemId { get; set; }
    public int CategoryId { get; set; }
    public int DesignerId { get; set; }
    public int ImageId { get; set; }
    [Required]
    [MaxLength(250)]
    public string ItemName { get; set; }
    [Required]
    [Range(0,9999)]
    public decimal ItemPrice { get; set; }
    [MaxLength(1000)]
    public string ItemDescription { get; set; }
    [Range(4,22)]
    public int ItemSize { get; set; }

    [Column("CategoryId")]
    public virtual List<Category> Category { get; set; }
    public virtual List<OrderDetail> OrderDetails { get; set; }
    public virtual List<Image> Images { get; set; }
}
  

Класс модели изображения: хранит URL для каждого изображения в каталоге содержимого сайта. Может иметь много изображений для каждого элемента.

 public class Image
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int ImageId { get; set; }
    [Required]
    public string ImageURL { get; set; }
    [Required]
    public string ItemId { get; set; }

    //Files Being Uploaded by the User
    public IEnumerable<HttpPostedFileBase> Files { get; set; }

    [Column("ItemId")]
    public virtual List<Item> Item { get; set; }
}
  

Контроллер менеджера магазина

     [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create(Item item,HttpPostedFileBase file)
    {
        if (ModelState.IsValid)
        {

            //The below successfully saves the file to the content folder when separated into the Index Action.
            foreach (var f in item.Files)
            {
                if (file.ContentLength > 0)
                {
                    var fileName = Path.GetFileName(f.FileName);
                    var path =   Path.Combine(Server.MapPath("~/Content/ItemImages/" item), fileName);
                    file.SaveAs(path);
                }
            }

    // The below also works when I dont have the Above in the Action.
            db.Items.Add(item);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        return View(item);
    }
  

Создать представление элемента

     @model Project.Models.Item

    @{
       ViewBag.Title = "Create";
     }

    <h2>Create</h2>

    @using (Html.BeginForm()) {
       @Html.AntiForgeryToken()
       @Html.ValidationSummary(true)

    <fieldset>
        <legend>Item</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.ItemName)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.ItemName)
            @Html.ValidationMessageFor(model => model.ItemName)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.ItemPrice)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.ItemPrice)
            @Html.ValidationMessageFor(model => model.ItemPrice)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.ItemDescription)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.ItemDescription)
            @Html.ValidationMessageFor(model => model.ItemDescription)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.ItemColour)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.ItemColour)
            @Html.ValidationMessageFor(model => model.ItemColour)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.ItemSize)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.ItemSize)
            @Html.ValidationMessageFor(model => model.ItemSize)
        </div>

        <p>
           <input type="submit" value="Create" />
        </p>
</fieldset>
}

    @using (Html.BeginForm(null, null, FormMethod.Post, new { enctype = "multipart/form-data" }))
    {
        <div>
        <table>
            <tr>
                <td>Files</td>
                <td><input type="file" name="Files" id="Files" multiple/></td>
            </tr>
            <tr>
                <td></td>
                <td><input type="submit" name="submit" value="Upload" /></td>
            </tr>
        </table>
        </div> 
    }

   <div>
       @Html.ActionLink("Back to List", "Index")
   </div>
  

Ответ №1:

Похоже, вы довольно близки.

Вам просто нужно добавить изображения к элементу, прежде чем добавлять его в базу данных.

Поскольку вы используете EF, это должно быть что-то похожее на это

  //in your action

 //add the images to the item
 item.Images.Add(new Image { ImageUrl = ... });

 //you should be able to just insert the whole entity graph here
 db.Items.Add(item);
 db.SaveChanges();
  

Что-то подобное, я думаю, это то, что вы ищете.

Кроме того, в вашем конструкторе модели обычно я думаю, что вы хотите инициализировать эти списки, чтобы вы не получали нулевые ссылки при выполнении чего-то подобного выше

 public class Item 
{
    public Item()
    {
        this.Images = new List<Image>();
    }
    //...
}
  

Комментарии:

1. Привет, Кайл, спасибо за ответ. Самая большая проблема, с которой я сталкиваюсь, связана с самим представлением. В настоящее время у меня есть как кнопка загрузки, так и кнопка создания. Конечно, мне нужна только одна кнопка, которая будет загружать и создавать в одном и том же связанном процессе?