Search code examples
c#asp.netasp.net-mvctag-helpers

ASP.NET Tag helpers and Bootstrap Dropdown. How to use together?


Faced such peculiar problem. For a better understanding, I will try to describe in more detail.

I have two metod in ArticleController:

[HttpGet]
public async Task<IActionResult> Create()
{
        var sources = await _sourceServices.GetSourceNameAndId();

        var listSources = new List<SourceNameAndIdModel>();

        foreach (var source in sources)
        {
            listSources.Add(_mapper.Map<SourceNameAndIdModel>(source));
        }

        var viewModel = new ArticleCreateViewModel()
        {
            SourceNameAndIdModels = listSources
        };

        return View(viewModel);
}


[HttpPost]
public async Task<IActionResult> Create(ArticleCreateViewModel viewModel)
{
      await _articleService.CreateArticle(_mapper.Map<ArticleDTO>(viewModel));

      return RedirectToAction("Index", "Article");
}

As you can see, in the Get-method, I get the names and ids of all Sources from the database via _sourceService in the form of IEnumerable :

public class SourceNameAndIdDTO
{
    public Guid Id { get; set; }
    public string Name { get; set; }
}

Next, I enumerate them in a foreach loop and add each SourceNameAndIdDTO object to the List listSources I created before:

public class SourceNameAndIdModel
{
    public string Name { get; set; }
    public Guid Id { get; set; }
}

Next, I create an instance of the ArticleCreateViewModel model, which I will use further in the View:

public class ArticleCreateViewModel
{
    public Guid Id { get; set; } = Guid.NewGuid();
    public string Title { get; set; }
    public string Description { get; set; }
    public string Body { get; set; }

    public Guid SourceId { get; set; }

    public DateTime CreationDate { get; set; }
    public List<SourceNameAndIdModel> SourceNameAndIdModels { get; set; }
}

And I assign to the field public List SourceNameAndIdModels { get; set; } List listSources values:

var viewModel = new ArticleCreateViewModel()
{
     SourceNameAndIdModels = listSources
};

You can see this in the controller code I posted above. Next, I send the viewModel to the View.

Code of my View:

@model ArticleCreateViewModel

<div class="container">
    <h2>Edit article</h2>
    <div class="row gx-5">
        <form asp-controller="Article" asp-action="Create" asp-antiforgery="true" method="post">
            <div>
                <input type="hidden" asp-for="Id" />
                <div class="mb-3">
                    <label class="col-sm-2 col-form-label" asp-for="Title"></label>
                    <input class="form-control" type="text" asp-for="Title">
                </div>
                <div class="mb-3">
                    <label class="col-sm-2 col-form-label" asp-for="Description"></label>
                    <textarea class="form-control" asp-for="Description"></textarea>
                </div>
                <div class="mb-3">
                    <label class="col-sm-2 col-form-label" asp-for="Body"></label>
                    <textarea class="form-control" asp-for="Body"></textarea>
                </div>

                <div class="dropdown">
                    <a class="btn btn-secondary dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
                        Source
                    </a>
                    <ul class="dropdown-menu">
                        @foreach (var item in @Model.SourceNameAndIdModels)
                        {
                            <li><select class="dropdown-item" asp-for="SourceId" asp-items="@item.Id">@item.Name</select></li>
                        }
                    </ul>
                </div>

                <div class="mb-3">
                    <label class="col-sm-2 col-form-label" asp-for="CreationDate"></label>
                    <input type="datetime-local" class="form-control" asp-for="CreationDate">
                </div>
            </div>
            <button type="submit" class="btn btn-primary">Submit</button>
        </form>
    </div>
</div>

And finally, in this place of the code, in which I want to set the Source of the article I am creating, I have an error:

enter image description here

Can you please tell me how in my case to make friends with my code with dropdown on my request? What am I doing wrong?


Solution

  • Using asp-items in this way is incorrect.
    The Select Tag Helper asp-items specifies the option elements

    Details and example:
    https://learn.microsoft.com/...netcore-6.0#the-select-tag-helper