ASP.Net MVC Razor - Display Countries Gives Error in View - asp.net-mvc

I am trying to list the contries in view. I have created a model called tbl_Countries and the code is below
public class tbl_Countries
{
public int ID { get; set; }
public string Country_Name { get; set; }
}
I have a Controller called Home with the following code. I have created an edmx file for TestDB database
public ActionResult Index()
{
TestDBEntities TestdbContext = new TestDBEntities();
var countries = TestdbContext.tbl_Countries.ToList();
return View(countries);
}
Below is my View code
#model IList
displaying the countries using ul li with foreach
If i run the application am getting this error:
The model item passed into the dictionary is of type 'System.Collections.Generic.List1[TestMVC.tbl_Countries]',
but this dictionary requires a model item of type 'System.Collections.Generic.IList1[TestMVC.Models.tbl_Countries]
I just want to show the list of countries in view and I would like to know
Without creating a model class is it possible to bind grid?
Is it mandatory to specify the model name using #model directive in view?

You got this error 'cause you specified in your view #model List, but pass to it List, try to change it in your view to List
Yes, you can delete #model at all, but in this case your view won't be strongly typed, so you won't be able to use intelli sense

create a list of country type in model
public List< tbl_Countries> country{get;set;}
In index page set the value of this List
public ActionResult Index()
{
TestDBEntities TestdbContext = new TestDBEntities();
tbl_Countries objModel=new tbl_Countries();
objModel.country = TestdbContext.tbl_Countries.ToList();
return View(objModel);
}

According to the error message you are expecting a model of the type List<TestMVC.Models.tbl_Countries> in the view which is different from the List<TestMVC.tbl_Countries> type your action method returns.
To resolve this issue, you could create a list your view expects and map the data you got from Entity Framework to it.
For example:
public ActionResult Index()
{
TestDBEntities TestdbContext = new TestDBEntities();
var countries = new List<TestMVC.Models.tbl_Countries>();
countries = (from country in TestdbContext.tbl_Countries
select new TestMVC.Models.tbl_Countries
{
Country_Name = country.Country_Name
}).toList();
return View(countries);
}
To seperate the logic of the view and data access it is a good practice to have models which are independent from your data models, from the EF models in your example.

Related

Show dropdownlist in the View

I am working on a project in which, i am getting the client names from database table using the HomeController>Index Action method.
I want to send this list to Index view and display this list in the dropdownlist.
Request you to please help me with the View accordingly as i am new to MVC.
Home Controller
public ActionResult Index()
{
var model = from c in
_mdlCntxtcls.clients
where (DateTime.Now<=c.End_Date)
select c;
return View(model);
}
Model
public class Client
{
public int ClientID { get; set; }
public string Client_Names { get; set; }
public DateTime Start_Date { get; set; }
public DateTime End_Date { get; set; }
}
Please help as early as possible
Thank you
You are passing a collection of Client objects to the view. So your view should be strongly typed to a collection of Client object to accept that as the (view) model data.
You can use the DropDownList html helper method to render a SELECT element from this view model data. You can create a SelectList object from this collection (your page model)
#model IEnumerable<YourNamespaceHere.Client>
#Html.DropDownList("StudentSelect",new SelectList(Model,"ClientID","Client_Names"))
This will render a SELECT element with name attribute value set to StudentSelect. Each options in the SELECT elemtn will have the ClientID as the value attribute value and Client_Names property value as the option text.
You can also use viewbag or viewdata for send list of Client from controller to view and then you can put it in dropdown list.
In Controller you can use like :
List<SelectListItem> ClientList = new List<SelectListItem>();
using (dbContext db = new dbContext())
{
var Clients = db.Client.ToList();
foreach (var i in Clients)
{
ClientList.Add(new SelectListItem { Text = i.Client_Name, Value = i.ClientID.ToString() });
}
}
ViewBag.ClientList = ClientList;
and in view side you can use that viewbag like :
#Html.DropDownListFor(x => x.Client, (IEnumerable<SelectListItem>)ViewBag.ClistList)

.net MVC: resolve a view related to a type

I'm trying to render a Model in MVC that takes a list of Content objects List<Content>()
A Content is a base class and can be one of many different derived types eg: (TextBox, Schedule etc...)
In my View, while iterating through the list of contents I want to address a view that matches the type of the Content's derived class. (so that TextBox uses it's own view, Schedule it's own view and so on...)
How can I achieve this? Maybe I need to do some binding in the ViewModel?
Any help will be greatly appreciated,
thanks in advance for your answer(s).
You can iterate your list, and on each iteration call a partial view which matches the iterated object type (what you called "Content").
You can encapsulate a public property in you content class, to hold the view name. Or you can also use the object's method GetType instead.
Something like this (where your list of objects resides in Model.ContentList):
foreach (var _content in Model.ContentList) {
#Html.Partial(_content.ViewName, _content); // the "ViewName" would hold different names, such as: "TextBox", "Schedule" from your question.
}
Lets say your model -
public class Content
{
public int Weight { get; set; }
}
public class TextContent : Content
{
public string Text { get; set; }
}
Then create a controller action -
public ActionResult GetContents()
{
var contents = new List<TextContent>()
{
new TextContent() {Text = "Sample Text"},
new TextContent() {Text = "Second Sample Content"}
};
return View(contents);
}
now create a folder called EditorTemplates in Shared folder of Views folder and place following cshtml with name TextContent.cshtml (Note: name of the cshtml file should be matching with the model name, otherwise custom editor template will not be rendered).
#model myc.Models.TextContent
#Html.TextBoxFor(m => m.Text)
Now create your view with IEnumerable<myc.Models.TextContent> -
model IEnumerable<MvcApplication1.Controllers.TextContent>
#{
ViewBag.Title = "GetContents";
}
<h2>GetContents</h2>
#foreach (var item in Model) {
#Html.EditorFor(m => item)
}
When you run the application and go to the view, you will get -

How to provide a model to a nested view in MVC (Razor)

Suppose I'm rendering another page(view) to a page (view).
Now the nested view has its separate model. How to provide the model to the nested view.
Here is the example.
my Index Controller:
public ActionResult Index()
{
ViewBag.CreateModel = new Todo();
return View(db.Todos.ToList());
}
my Index View:
IEnumerable<ToDoMVC.Models.Todo>
#RenderPage("~/Views/Todo/Create.cshtml",ViewBag.CreateModel)
my Create View:
#model ToDoMVC.Models.Todo
// does operations with this model
Now, if I run the program it gives me some model type mismatch error for create view.
So, how to solve this? How to provide another model to a nested view from a view?
In your model you would have a seperate model as a variable.
For example
class Todo {
public CreateModel create {get;set}
}
Then when you pass through to the second view you would do something like this:
#RenderPage("~/Views/Todo/Create.cshtml",Model.create)
That will pass that second model to your create page
Edit
Re-reading your question.
The mismatch will be because you are passing the whole model through and you want to pass an individual list item in.
So you need too loop through the model like this:
foreach(var item in Model)
{
#RenderPage("~/Views/Todo/Create.cshtml", item)
}
Simply create a view model class like this:
public class ToDoViewModel
{
public IEnumerable<ToDo> Todos{ get; set; }
public ToDo NewToDoItem { get; set; }
}
Then change your contoller's action:
public ActionResult Index()
{
var todoViewModel = new ToDoViewModel();
todoViewModel.NewToDoItem = new Todo();
todoViewModel.Todos= db.Todos.ToList();
return View(todoViewModel);
}
And then adjust your Index view:
#model ToDoMVC.Models.ToDoViewModel
#RenderPage("~/Views/Todo/Create.cshtml",Model.NewToDoItem)
A view inside a view or inother words, a nested view is not viable as far as my affair with MVC goes. You create a view and bind it to a model to show data relevant to that model on the browser. Now if you want data from other multiple models / business entities to be rendered on the view then you use ViewModels (Reference 1,Reference 2) and for that matter, the answers above remain valid. You can also customize / define sections on your layout to render specific information aswell. Partial views also make an option depending on the kind of info you want delivered to the view.
You can create a MasterModel and refer it to index view
public Class MasterModel
{
Public IEnumerable<ToDo> TodoList { get; set; }
Public ToDo CreateModel { get; set; }
}
Controller
public ActionResult Index()
{
MasterModel model = new MasterModel();
model.CreateModel = new Todo();
model.TodoList = db.Todos.ToList();
return View(model );
}
Refer this to Index model
#model MasterModel
#RenderPage("~/Views/Todo/Create.cshtml",Model.CreateModel)

Queries realted to Dropdown list in MVC

I am a new to ASP.NET MVC, I am developing an application. I want to bind the data in the drop down list in create view.
How to bind the data in the drop down? I have go through many question and answers here...
I have seen usually everyone suggested to use List<SelectListItem> what is its purpose?
Do I need to use ViewModel while binding the data to drop down list?
Can I get simple example where data get bind in the dropdown using viewbag?
I have created a list in controller
List<string> items = new List<string>();
and I want to pass this list to view using viewbag and simply want to bind to drop down list.
How to do this ?
I'd suggest using a ViewModel as it makes interaction with user input so much easier. Here's an example of how you might bind data from your ViewModel to a drop down in your View. First, the ViewModel:
public class CrowdViewModel
{
public string SelectedPerson { get; set;}
public IEnumerable<SelectListItem> People { get; set; }
}
So yes, you're right - use a collection of SelectListItems. I'm guessing in your case, the SelectListItem's Value and Text property will be the same. You could turn your List into IEnumerable like this:
[HttpGet]
public ActionResult Home()
{
// get your list of strings somehow
// ...
var viewModel = new CrowdViewModel
{
People = items.Select(x => new SelectListItem { Text = x, Value = x })
}
return View(viewModel);
}
Now you need to bind that ViewModel's property to the DropDown on your view. If you're using the Razor ViewEngine, the code will look something like this:
#model MyApp.ViewModels.CrowdViewModel
#using (Html.BeginForm())
{
#Html.DropDownListFor(model => model.SelectedPerson, Model.People)
}
Now when you post that form, MVC will bind the selected value to the ViewModel's SelectedPerson property!
[HttpPost]
public ActionResult Home(CrowdViewModel viewModel)
{
// viewModel.SelectedPerson == whatever the user selected
// ...
}
Easy as that!
Update:
If you really want to use the ViewBag (don't do it), you can pass your list through from your Controller action like so:
[HttpGet]
public ActionResult Home()
{
ViewBag.People = new List<string> { "Bob", "Harry", "John" };
return View();
}
And then create a SelectList on your View:
#Html.DropDownList("SelectedPerson", new SelectList(ViewBag.People, Model))

ASP.NET MVC - drop down list selection - partial views and model binding

I'm fairly new to ASP.NET MVC and am trying to work out the best way to do this. It's probably simple but I just want to do things correctly so I thought I'd ask.
Lets say I have a model that is this:
Task - Id, Description, AssignedStaffMember
StaffMember - Id, FirstName, LastName
and in my view I want to create a new task. I make a strongly typed Razor view, and can use EditorFor to create textboxes for Description but what about AssignedStaffMember?
I want a drop down list of all current staff and have the option of selecting one, then this gets submitted to an action method which is
NewTask(string description, StaffMember assignedStaffMember)
either that or I could have an int for staffId instead of the StaffMember object and look it up in the action method.
What is the best way to do this? I need to go to the database to get the list off staff, so here's what I thought:
Make a partial view for the listing of staff drop down, which will be used a few times and use #Html.Action("ListStaff", "Staff") to call it. The action method then has
public ActionResult ListStaff()
{
IEnumerable<StaffMember> model = _serviceLayer.GetAllStaff();
return PartialView(model);
}
However I'm not sure on how this will work with model binding, my understanding is that it has to have the correct name for the form to submit it, I'd need to pass the name to the partial view to put on the element I guess?
Instead of having it call a controller to get the staff, make a ViewModel that contains my Task and a IEnumerable possibleStaff collection. possibly send this information to a partial view.
a Html Helper ?
EditorFor could somehow be used?
which one (or is there more) would be best? and how would I do the model binding?
Here is one way to do this. Create a TaskDetailsViewModel
public class TaskDetailsViewModel
{
public TaskDetailsViewModel()
{
this.Task = new Task();
this.StaffMembers = new List<StaffMember>();
}
public Task Task { get; set; }
public IEnumerable<StaffMember> StaffMembers { get; set; }
}
In Controller
public ActionResult Edit(int id)
{
var task = taskRepository.GetTaskByID(id);
var taskDetailsViewModel = new TaskDetailsViewModel();
// Populate taskDetailsViewModel from task and staff
return View(taskDetailsViewModel);
}
[HttpPost]
public ActionResult Edit(TaskDetailsViewModel taskDetailsViewModel)
{
if (ModelState.IsValid)
{
taskRepository.Save(taskDetailsViewModel.Task);
}
else
{
// Show Error
}
return View(taskDetailsViewModel);
}
In View (bound strongly to TaskDetailsViewModel)
#Html.DropDownListFor(model => model.Task.AssignedStaffMember, new SelectList(Model.StaffMembers, "ID", "FirstName", Model.Task.AssignedStaffMember))
#Html.ValidationMessageFor(model => model.Task.AssignedStaffMember)

Resources