kez kez - 2 months ago 24
C# Question

Web API method Populate as @Html.DropDownList in MVC project's create view

I have following class

Basic Class

public class Basic
{
public int ID { get; set; }
public string NAME { get; set; }

}


I have following method to fill the Value to above class

Get Authers Id and Name Method

public IEnumerable<Basic> GetAuthersIdName()
{
.....
}


So in Web API layer
Controller Class
I'm getting above details like below

// GET: api/Authers/all

[System.Web.Http.Route("api/Authers/all")]
public IEnumerable<Basic> GetAuthersIdName()
{
return db.GetAuthersIdName();
}


Then I can have following URL to fetch above details

http://localhost:13793/api/Authers/all


enter image description here

So In my MVC Layer , model folder I created a class to handle above details like below

public class LibraryClient
{
private string AUTHER_URL = "http://localhost:13793/api/Authers";

//DropDown

public IEnumerable<Basic> GetAuthersIdName()
{
try
{
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(AUTHER_URL);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = client.GetAsync("Authers/all").Result;
if (response.IsSuccessStatusCode)
return response.Content.ReadAsAsync<IEnumerable<Basic>>().Result;
return null;
}
catch
{
return null;
}

}
}


Then I create Controller class to populate above details on front end like below

Controller Class

public class BooksController : Controller
{
// GET: Books/Create
public ActionResult Create()
{
LibraryClient lc = new LibraryClient();
ViewBag.listAuthers = lc.GetAuthersIdName();
return View("Create");
}

// POST: Books/Create
[HttpPost]
public ActionResult Create(Book book)
{
LibraryClient lc = new LibraryClient();
lc.CreateBook(book);
return RedirectToAction("BookswithAuthers", "BookWithAuther");
}
}


View File

<div class="form-group">
@Html.LabelFor(model => model.Auther_Id, "Auther_Id", htmlAttributes: new { @class = "." })
<div class="col-md-10">
@Html.DropDownList("NAME", (IEnumerable<SelectListItem>)ViewBag.listAuthers, "---Select---");
@Html.ValidationMessageFor(model => model.Auther_Id, "", new { @class = "." })
</div>
</div>


But since I'm using
IEnumerable<Basic>
to populate in business layer I cannot use that type in frontend.

I saw many answers do this task using jQuery and Web API , without that path how can I populate my drop down with
@Html.DropDownList()

Answer

You assigning IEnumerable<Basic> to ViewBag.listAuthers and in the view attempting to cast it to IEnumerable<SelectListItem> which cannot be done and will fail (and result in an exception). You need to create the SelectList in the GET method using either

ViewBag.listAuthers = new SelectList(lc.GetAuthersIdName(), "ID", "Name")

or

ViewBag.listAuthers = lc.GetAuthersIdName().Select(x => new SelectListItem
{
    Value = x.ID.ToString(),
    Text = x.Name
});

and since you want to bind to the selected value to the Auther_Id property of Book, then your view needs to be

@Html.DropDownList("Auther_Id", (IEnumerable<SelectListItem>)ViewBag.listAuthers, "---Select---")

or better, use the strongly typed method

@Html.DropDownListFor(m => m.Auther_Id, (IEnumerable<SelectListItem>)ViewBag.listAuthers, "---Select---")

However, your editing data so you should be using a view model and that view model will contain a property for the SelectList (say public IEnumerable<SelectListItem> AuthorList { get; set; } and then the view will be

@Html.DropDownListFor(m => m.Auther_Id, Model.AuthorList, "---Select---")

Refer this question/answer for more detail on implementing the view model and the associated controller methods.

Comments