1

I can not find the answer nor can I fix my issue with grabbing Json data from a MVC WepApi and sending it to a drop down list.

I get the following error:

RuntimeBinderException: The best overloaded method match for 'Microsoft.AspNetCore.Mvc.Rendering.SelectList.SelectList(System.Collections.IEnumerable, string, string)' has some invalid arguments

I grab the Json data using the following code, this code is sitting in the Controlller right now:

    public async Task<IActionResult> GrabEmployees()
    {
        var item = new List<EmployeeViewModel>();

        using (var employee = new HttpClient())
        {
            employee.BaseAddress = new Uri("http://localhost:5050/");
            employee.DefaultRequestHeaders.Accept.Clear();
            employee.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            HttpResponseMessage response = await employee.GetAsync("api/employees");
            if (response.IsSuccessStatusCode)
            {
                item = await response.Content.ReadAsAsync<List<EmployeeViewModel>>();
            }
        }
        return ViewBag.Employees = item.Select(employee => new SelectListItem { Value = employee.EmployeeNumber, Text = (employee.FirstName + " " + employee.LastName) });
    }

So with the above code I tried setting the Task to a string, IEnumerable, JsonResult, all kinds of stuff it gives me the same error. It leads me to believe that the issue could be because it's async. I don't know though, I'm new to Json and MVC Core.

Here is how I pass the info into the View:

    public IActionResult Assignments()
    {
        ViewData["Title"] = "Assign Asset";
        ViewData["Message"] = "Use this section to assign assets to Employees.";
        ViewBag.Employees = GrabEmployees();
        ViewBag.Assets = AManger.GetAll();
        //Allows to assign assets to employees
        return View();
    }

Here is the View page code:

@model IEnumerable<Final.HRInventoryApp.Models.AssetViewModel>

<h2>@ViewData["Title"]</h2>
<h3>@ViewData["Message"]</h3>
@using (Html.BeginForm())
{
    @Html.DropDownList("Asset", new SelectList(ViewBag.Assets, "Id", "TagNumber"))
    @Html.DropDownList("EmployeeId", new SelectList(ViewBag.Employees, "Value", "Text"))
    <input type="submit" id="buttonsubmit" value="Submit" />

}

I am getting mixed results. When I first launch the application the page loads and the drop down is populated. If i click on another page and come back to said page it completely fails with that error. How can I fix this?

1 Answer 1

1

Looks like your GrabEmployees method is returning an IActionResult which you are setting to the viewbag in the other action method ! Also you have a statement return ViewBag.Employees; in that method!! That does not look correct. You should consider updating your GrabEmployees method to return the data you want (The collection of SelectListItem items)

public async Task<IEnumerable<SelectListItem>> GrabEmployees()
{
    var item = new List<SelectListItem>();

    using (var employee = new HttpClient())
    {
        employee.BaseAddress = new Uri("yourUrlForApiEndpointHere");
        employee.DefaultRequestHeaders.Accept.Clear();
        employee.DefaultRequestHeaders.Accept

                            .Add(new MediaTypeWithQualityHeaderValue("application/json"));

        HttpResponseMessage response = await employee.GetAsync("api/employees");
        if (response.IsSuccessStatusCode)
        {
            var data = await response.Content.ReadAsAsync<List<EmployeeViewModel>>();
            return data.Select(x => new SelectListItem { Value = x.EmployeeNumber,
                                           Text = (x.FirstName + " " + x.LastName) });
        }
    }
    return item;
}

And in your other action method,call this method and pass it to view.

public  async Task<IActionResult> Assignments()
{
    ViewData["Title"] = "Assign Asset";
    ViewData["Message"] = "Use this section to assign assets to Employees.";
    var d =  await GrabEmployees();
    ViewBag.Employees = d.ToList();
    // to do : Fix Assets the same way
    return View();
}

Now in the View,

@Html.DropDownList("EmployeeId", ViewBag.Employees as List<SelectListItem>)
Sign up to request clarification or add additional context in comments.

10 Comments

Shyju thank's for the reply, but that does not work.If I use await , it states that await can only be used with async, if I call the GrabEmployees() without it GrabEmployees() returns null.
are you sure response.IsSuccessStatusCode return true ?
Yes it returns true and data is passed into the data variable, I'm getting the following when loading the Assignments view however InvalidOperationException: There is no ViewData item of type 'IEnumerable<SelectListItem>' that has the key 'EmployeeNumber'.
Are you sure you are using the DropDownList helper method as i posted in the answer ? It should work. As long as you set a list of SelectListItem to ViewBag.Employees in your GET action method. I just copied and pasted it and verified it.
I just double checked aside from not being able to use the await statement preceding GrabEmployees() my code looks just like yours.
|

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.