0

I would like to create a dropdown list within a view component in my ASP.NET Core 2.2 MVC app.

I need to display more than one model in the same view, so I'm using view components. I have tried partial views, but had some trouble with them. I've been referring to this documentation.

  • The model I'm using in the view component is Tag.
  • The view component is TagListViewComponent
  • The view that invokes the view component is Edit.cshtml. (This view uses a different model, Post, which is why I'm invoking the view component to accecss the Tag model.)
  • The view component Razor page is Default.cshtml
  • I don't think there are any routing issues, because I can successfully render each Tag in the view:
public class Tag
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string Description { get; set; }
}

public class TagListViewComponent : ViewComponent
{
    private readonly Website.Data.ApplicationDbContext db;
    public TagListViewComponent(Website.Data.ApplicationDbContext context)
    {
        db = context;
    }

    public async Task<IViewComponentResult> InvokeAsync()
    {
        var tag = await db.Tag.ToListAsync();
        return View(tag);
    }
}

Views:

Edit.cshtml

// (using a different model and removing irrelevant HTML)
<div>
    @await  Component.InvokeAsync("TagList")
</div>

Default.cshtml

@model IEnumerable<Website.Models.Tag>
@foreach (var item in Model)
{
    @Html.ActionLink(item.Title, "Details", "Tags", new { item.Id }, new { @class = "btn btn-outline-primary btn-sm" })
    <br />
}

The above code renders the six tags listed in the database when I navigate to a page using edit.cshtml, e.g., https://localhost:xxxxx/Posts/Edit/2.

The problem I'm having is that I can't for the life of me figure out how to display the tags in a dropdown list. I can add to the Default.cshtml view the following:

@Html.DropDownList("Title", new SelectList(Model))

This does create a dropdown list, with six options (which is the correct number), but all options say Website.Models.Tag. I'm unable to access the Tag.Title property or any other properties.

I've also tried @Html.DropDownListFor(), but it doesn't let me access any properties either.

In the TagListViewComponent.cs, I've tried including more info (PostTags is a navigation property of Tag, and it contains a tag property which links back to the tags...). But the below code just provides the same level of access as the original InvokeAsync method:

public async Task<IViewComponentResult> InvokeAsync()
{
   var tag = await db.Tag
            .Include(t => t.PostTags)
            .ThenInclude(pt => pt.tag)
            .ToListAsync();
   return View(tag);
}

I haven't been able to find any information about using dropdown lists with view components. Any direction would be very appreciated.

1 Answer 1

2

Create an IEnumerable<SelectListItem> from your model and pass that into @Html.DropDownList("Title", selectListItems)

var selectListItems = Model
    .Select(tag => new SelectListItem{ Text = tag.Title, Value = tag.Id });
Sign up to request clarification or add additional context in comments.

1 Comment

Fantastic. If anyone else sees this, I had to add the [NotMapped] attribute to public IEnumerable<SelectListItem> selectListItems { get; set; } in my model (as no primary key was defined). Thank you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.