0

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()

kez
  • 2,273
  • 9
  • 64
  • 123
  • You don't really pass your data into your model, you pass it into your ViewBag. And then you try to read your model in your view, while you should read your ViewBag – Marco Sep 18 '16 at 12:09
  • Isn't it I'm calling `ViewBag.listAuthers = lc.GetAuthersIdName();` here – kez Sep 18 '16 at 12:10
  • `ViewBag.listAuthers` is `IEnumerable` not `IEnumerable` - you can use `ViewBag.listAuthers = new SelectList(lc.GetAuthersIdName(), "ID", "Name")` to create `IEnumerable` (or `ViewBag.listAuthers = lc.GetAuthersIdName().Select(x => new SelectListItem{ Value = x.ID.ToString(), Text = x.Name });`) –  Sep 18 '16 at 12:11
  • @StephenMuecke now that populating it , to get ID value from that dropdown do I need to use like this `@Html.DropDownList("ID", (IEnumerable)ViewBag.listAuthers, "---Select---");` – kez Sep 18 '16 at 12:19
  • It does not matter whether its `ID` or `NAME` (it could be `XYZ`) - the value of your –  Sep 18 '16 at 12:24
  • @StephenMuecke but when I debug `POST` method of that I can see ID of that selected value not getting to model http://imgur.com/a/6xri1 here I should bind `ID` of this DropDown to `Auther_Id` , which is currently getting `0` – kez Sep 18 '16 at 12:34
  • If you want to bind to a property named `Author_Id`, then the dropdownlist needs to have the same name - `@Html.DropDownList("Author_Id", ....)`. But read the link I gave you. Use a view model and bind to your view model and always use the strongly typed `***For()` methods –  Sep 18 '16 at 12:39
  • @StephenMuecke Yp youre correct now thats working , thanks lot , I wish you can mark as an answer :) – kez Sep 18 '16 at 12:41
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/123634/discussion-between-stephen-muecke-and-kez). –  Sep 18 '16 at 12:42

1 Answers1

1

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.

Community
  • 1
  • 1