ASP.Net Utilisation d'une liste dans un modèle complexe

Fermé
thibaut212121 Messages postés 1 Date d'inscription mercredi 25 décembre 2019 Statut Membre Dernière intervention 25 décembre 2019 - Modifié le 26 déc. 2019 à 03:29
Whismeril Messages postés 19038 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 7 mai 2024 - 26 déc. 2019 à 03:34
Bonjour à tous et Joyeuses fêtes à ceux qui liront ce poste !

Je suis sur un projet depuis plusieurs jours et impossible de trouver la solution à mon problème ... qui reste assez basique je pense ;)

A titre d'info et pour mieux visualiser le projet, voici sont arborescence :


Je dois réaliser un site Web en ASP.NET en utilisant les pages Razor. Ce site doit afficher des playlists contenant des musiques. Afin de ne pas dubliquer mes musiques en base de données, je suis parti sur un modèle "Many To Many" que voici :

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;

namespace SupPlayer.Models
{
    public class Playlists
    {
        public int ID { get; set; }

        [Required]
        [Display(Name = "Name")]
        public string Name { get; set; }

        [Required]
        [Display(Name = "Gender")]
        public string Gender { get; set; }

        public string Author { get; set; }

        public List<Musics> MusicsList { get; set; }
    }

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

        [Required]
        [Display(Name = "Name")]
        public string Name { get; set; }

        [Required]
        [Display(Name = "Path")]
        public string Path { get; set; }
    }
}


A partir de ce modèle Visual Studio me génère donc 2 tables dans une même DB ce qui est top :


Dans ma vue Razor j'arrive parfaitement à afficher toutes les playlists liée à un utilisateur avec une boucle [CODE]Foreach() {}[/CODE]. Le problème arrive quand je veux afficher une playlist plus en détail. J'aimerais pouvoir afficher toutes les musiques qui appartiennent à une Playlist. Pour cela voici ma vue Razor affichant le détail d'une musique :

@page
@model SupPlayer.DetailsModel

@{
    ViewData["Title"] = "SupPlayer";
}

<link href="/css/site.css" rel="stylesheet" type="text/css" />

<section class="backgroundDynamique">
    <h1>Details</h1>

    <div>
        <h4>Playlists</h4>
        <hr />
        <dl class="row">
            <dt class="col-sm-2">
                @Html.DisplayNameFor(model => model.Playlists.Name)
            </dt>
            <dd class="col-sm-10">
                @Html.DisplayFor(model => model.Playlists.Name)
            </dd>
            <dt class="col-sm-2">
                @Html.DisplayNameFor(model => model.Playlists.Gender)
            </dt>
            <dd class="col-sm-10">
                @Html.DisplayFor(model => model.Playlists.Gender)
            </dd>
        </dl>
        <table>
            @for (var i = 0; i < Model.Playlists.MusicsList.Count; i++)
                {
                    <tr>
                        <td>
                            @Html.HiddenFor(m => Model.Playlists.MusicsList[i].Name)
                        </td>
                        <td>
                            @Html.HiddenFor(m => Model.Playlists.MusicsList[i].Path)
                        </td>
                    </tr>
                }
        </table>
    </div>
    <div>
        <a class="linkOrange" asp-page="./Edit" asp-route-id="@Model.Playlists.ID">Edit</a> |
        <a class="linkOrange" asp-page="./Index">Back to List</a>
    </div>
</section>


Associé a cette vue le contrôleur permettant de lui faire parvenir les données depuis la DB :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using SupPlayer.Data;
using SupPlayer.Models;

namespace SupPlayer
{
    public class DetailsModel : PageModel
    {
        private readonly SupPlayer.Data.SupPlayerContext _context;

        public DetailsModel(SupPlayer.Data.SupPlayerContext context)
        {
            _context = context;
        }

        public Playlists Playlists { get; set; }

        public async Task<IActionResult> OnGetAsync(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }

            Playlists = await _context.Playlists.FirstOrDefaultAsync(m => m.ID == id);

            if (Playlists == null)
            {
                return NotFound();
            }
            return Page();
        }
    }
}


Quand j'affiche la page détail d'une Playlist, un jolie message m'annonce que mon objet "MusicsList" n'est pas itérable ... j'en déduit que je dois mal le remplir ... ou mal l'initialiser. C'est là que je vois flou et que je n'arrive pas à comprendre mon erreur :



Je ne pense pas que le problème vienne d'ici, mais à titre d'information voici comment je créer mes objets "Playlists" et "Musics" dans le controlleur "Create" :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.Rendering;
using SupPlayer.Data;
using SupPlayer.Models;
using Microsoft.AspNetCore.Identity;

namespace SupPlayer
{
    public class CreateModel : PageModel
    {
        private readonly SupPlayer.Data.SupPlayerContext _context;

        public CreateModel(SupPlayer.Data.SupPlayerContext context)
        {
            _context = context;
        }

        public IActionResult OnGet()
        {
            return Page();
        }

        [BindProperty]
        public Playlists Playlists { get; set; }

        // To protect from overposting attacks, please enable the specific properties you want to bind to, for
        // more details see https://aka.ms/RazorPagesCRUD.
        public async Task<IActionResult> OnPostAsync()
        {
            if (!ModelState.IsValid)
            {
                return Page();
            }

            Playlists playlist = new Playlists { Name = Playlists.Name, Gender = Playlists.Gender, Author = User.Identity.Name, MusicsList = new List<Musics> { new Musics { Name = "test", Path = "testtest@test" } } };


            /* Ne pas tenir compte de cette ligne en commentaire ;)
             * Playlists playlist = new Playlists { Name = Playlists.Name, Gender = Playlists.Gender, Author = User.Identity.Name };*/
            
            
            _context.Playlists.Add(playlist);
            await _context.SaveChangesAsync();

            return RedirectToPage("./Index");
        }
    }
}



Merci par avance de votre aide, qui me serait très utile ... j'ai fait de très nombreuses recherche avant de demander de l'aide sur un forum en vain ... :/
Bien cordialement,
A voir également:

1 réponse

Whismeril Messages postés 19038 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 7 mai 2024 931
26 déc. 2019 à 03:34
Bonjour
Je ne fais pas d’ASP, donc je ne saurais te dire exactement ce qui ne va pas.
Mais ton message d’erreur ne dit pas que ta playlist n’est pas iterable, il dit qu’un objet de la ligne qui plante est null.

A priori, soit Model, soit Model.PlayLists, soit Model.Playlists.Musiclist.
1