0

I have two models Stock and Article with StockId as foreign key in Article. I'm trying to add collection of Articles that is equal to Stock.Quantite value to Article model, this is what i use: StockController:

public IActionResult AddArticle(int id)
    {
        Stock stock = _dbcontext.Stock.Where(e => e.StockId == id).FirstOrDefault();
        
        for(int i=1; i<= stock.Quantite;i++)
        {
            stock.Articles.Add(new Article() { ArticleId = i });
        }
        return PartialView("_AddArticlePartialView", stock);
    }
    [HttpPost]
    public IActionResult AddArticle(List<Article> article)
    {
        if (article != null)
        {
            _dbcontext.Article.AddRange(article);
            _dbcontext.SaveChanges();
            return RedirectToAction("Index");
        }
        return View();
        
    }

Index.cshtml:

    @model IEnumerable<Stock>

@{
    ViewData["Title"] = "Stock";
    Layout = "~/Views/Shared/_Theme.cshtml";
 }
<table class="table table-bordered table-hover" id="display">
                <thead>
                    <tr>
                        <th>
                            @Html.DisplayNameFor(model => model.CategoryId)
                        </th>
                        <th>
                            @Html.DisplayNameFor(model => model.Designation)
                        </th>
                        <th>
                            @Html.DisplayNameFor(model => model.Quantite)
                        </th>
                        <th></th>
                    </tr>
                </thead>
                <tbody>
                    @foreach (var item in Model)
                    {
                        <tr>
                            <td>
                                @Html.DisplayFor(modelItem => item.Category.CategoryName)
                            </td>
                            <td>
                                @Html.DisplayFor(modelItem => item.Designation)
                            </td>
                            <td>
                                @Html.DisplayFor(modelItem => item.Quantite)
                            </td>

                            <td>
                                <div class="btn-group-sm">
                                    <button class="btn btn-primary" data-toggle="modal" data-target="@("#AddArticle-"+item.StockId)" data-url="@Url.Action($"AddArticle/{item.StockId}")"><i class="fa fa-plus"></i>Ajouter Articles</button>
                                    @await Html.PartialAsync("_AddArticlePartialView", item)
                                </div>
                            </td>
                        </tr>
                    }
                </tbody>
            </table>

_AddArticlePartialView.cshtml:

    @model StockProject.Models.Stock

@{
    ViewData["Title"] = "_AddArticlePartialView";

}

<div class="modal fade" role="dialog" tabindex="-1" id="@("AddArticle-"+Model.StockId)" aria-labelledby="addArticleLabel" aria-hidden="true" >
    <div class="modal-dialog modal-xl modal-dialog-scrollable" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <h3 class="modal-title">Articles</h3>
            </div>
            <div class="modal-body">
                <form asp-action="AddArticle" method="post">
                    <div class="card">
                        <div class="card-header">
                            <h3 class="card-title">Articles</h3>

                        </div>
                        
                        <div class="card-body">
                            <table class="table table-bordered" id="articleTable">
                                <thead>
                                    <tr>
                                        <th>Numero de Serie</th>
                                        <th>Marque</th>
                                        <th>Etat</th>                                        
                                    </tr>
                                </thead>
                                <tbody>
                                    @for (int i = 0; i < Model.Articles.Count; i++)
                                    {
                                        <tr>
                                            <td>
                                                @Html.EditorFor(x => x.Articles[i].NumeroSerie, new { htmlAttributes = new { @class = "form-control" } })
                                            </td>

                                            <td>
                                                @Html.EditorFor(x => x.Articles[i].Marque, new { htmlAttributes = new { @class = "form-control" } })
                                            </td>
                                            <td>
                                                @Html.DropDownListFor(x => x.Articles[i].Etat, new List<SelectListItem> {
                                                       new SelectListItem { Value = "En Marche" , Text = "En Marche" },
                                                       new SelectListItem { Value = "En Panne" , Text = "En Panne" },

                                                    },
                                                  new { @class = "form-control" })
                                            </td>
                                            
                                        </tr>
                                    }

                                </tbody>
                            </table>
                        </div>
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-secondary" data-dismiss="modal">Annuler</button>
                        <button type="submit" class="btn btn-primary">Sauvegarder</button>
                    </div>
                </form>
            </div>
        </div>
    </div>
</div>

But this code doesn't add articles to the articleTable in _AddArticlePartialView.cshtml, it displays only the header of the table. Any suggestions??

EDIT

I followed the answer of Ruikai Feng and now the table is appearing in the partial view but i have another problem now it does not saved the articles. where is the problem now?

user3309231
  • 186
  • 3
  • 20
  • I would suggest moving away from loading a modal for each item in index.cshtml. I'm guessing your index get method doesn't set any articles when setting Model which is why nothing is displaying in your partial view – Alex Grogan Mar 06 '23 at 16:33

2 Answers2

0
@await Html.PartialAsync("_AddArticlePartialView", item) 

Would render the page with the model you passed to it directly without get into the controller

If you add breakpoint on your partial view controller, you would find it won't be executed.

for (int i = 1; i <= stock.Quantite; i++)
{
    stock.Articles.Add(new Article() { ArticleId = i });
}

You have to attach the articles to stock in index controller.

I tried with a minimal example based on your codes:

public IActionResult Index()
{
    var vm = new List<Stock>()
            {
                new Stock() { Quantite = 2, StockId = 1, Designation = "De1" },
                new Stock() { Quantite = 3, StockId = 2, Designation = "De2" }
            };

    foreach (var item in vm)
    {
        for (int i = 1; i <= item.Quantite; i++)
        {
            item.Articles.Add(new Article() { ArticleId = i });
        }
    }

    return View(vm);
}

Index Page:

<table class="table table-bordered table-hover" id="display">
                <thead>
                    <tr>
                       
                        <th>
                            @Html.DisplayNameFor(model => model.Designation)
                        </th>
                        <th>
                            @Html.DisplayNameFor(model => model.Quantite)
                        </th>
                        <th></th>
                    </tr>
                </thead>
                <tbody>
                    @foreach (var item in Model)
                    {
                        <tr>
                           
                            <td>
                                @Html.DisplayFor(modelItem => item.Designation)
                            </td>
                            <td>
                                @Html.DisplayFor(modelItem => item.Quantite)
                            </td>

                            <td>
                                <div class="btn-group-sm">
                                    <button class="btn btn-primary" data-toggle="modal" data-target="@("#AddArticle-"+item.StockId)" data-url="@Url.Action($"AddArticle/{item.StockId}")"><i class="fa fa-plus"></i>Ajouter Articles</button>
                                   
                                   
                                </div>
                            </td>
                        </tr>
                         @await Html.PartialAsync("_AddArticlePartialView", item)
                    }
                </tbody>
            </table>

Partial view:

@model Stock

@{
    ViewData["Title"] = "_AddArticlePartialView";

}
<tr>
    <th>Numero de Serie</th>
    <th>Marque</th>
    <th>Etat</th>
</tr>

@for (int i = 0; i < Model.Articles.Count; i++)
{
    <tr>
        <td>
            @Html.EditorFor(x => x.Articles[i].NumeroSerie, new { htmlAttributes = new { @class = "form-control" } })
        </td>

        <td>
            @Html.EditorFor(x => x.Articles[i].Marque, new { htmlAttributes = new { @class = "form-control" } })
        </td>
        <td>
            @Html.DropDownListFor(x => x.Articles[i].Etat, new List<SelectListItem> {
        new SelectListItem { Value = "En Marche" , Text = "En Marche" },
        new SelectListItem { Value = "En Panne" , Text = "En Panne" },

        },
        new { @class = "form-control" })
        </td>

    </tr>
}

Result:

enter image description here

You could keep the controller for refresh the partial view, a related case

Update:

it does not saved the articles

Put a breakpoint on your AddArticle endpoint and check if the articles were passed to it correctly.

In my case, it failed, try modify the name of the argument:

[HttpPost]
public IActionResult AddArticle(List<Article> articles)
{
    // ......
    return View();
}

enter image description here

The document related with model binding

Result:

enter image description here

enter image description here

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Ruikai Feng
  • 6,823
  • 1
  • 2
  • 11
0

You need Include in your stock query and SaveChanges

Stock stock = _dbcontext.Stock.Include(x => x.Articles).Where(e => e.StockId == id).FirstOrDefault();
//.....
_dbcontext.SaveChanges();
Darkk L
  • 889
  • 1
  • 4
  • 14