Using part of a view in a different controller - asp.net-mvc

I want to do the following and I can't figure it out. I have a controller with a view that shows a list of data. I would like to show that list of data on the home page. Is there any way to use the view of that list of data in the controller of the home page?

You want to achieve two (or more) models to render in one view? If yes, then here is your answer.
Let's suppose that you have two models, Book and Movie
public class Book
{
public int BookId { get; set; }
public string BookTitle { get; set; }
}
public class Movie
{
public int MovieId { get; set; }
public string MovieTitle { get; set; }
}
And then you want to get all Books and all Movies in one view. So create new class (for example in new folder named ViewModels and your class name can be anything, but let's name it for example ViewModel. In your class ViewModel write your Book and Movie model.
public class ViewModel
{
public Book Book { get; set; }
public IEnumerable<Book> Books { get; set; }
public Movie Movie { get; set; }
public IEnumerable<Movie> Movies { get; set; }
}
If you want also to display list you need to specify IEnumerable list, here is for Books and Movies.
And finally in your controller you can simply write:
public ActionResult Index()
{
var viewModel = new ViewModel
{
Movies = db.Movies.ToList(),
//you can also do this:
Movies = db.Movies.Where() //and so on
Books = db.Books.ToList()
};
return View(viewModel);
}
And #model for your view will be
#model MovieSubtitles.ViewModels.ViewModel
Hope it helps.

So you're saying you currently have something like:
public DataController() {
public ActionResult Index()
{
.. load data
return View(data);
}
}
If you convert data list to a PartialView you can then use that in any other view, eg:
public DataController() {
public ActionResult Index()
{
return View();
}
public ActionResult DataPartial()
{
.. load data
return Partial(data);
}
}
then in your original view, move out just the parts related to data into DataPartial.cshtml and in index.cshtml add call to the action:
#Html.Action("DataPartial");
You can then re-use this partial/action anywhere you want by calling it as above, but also specifying the controller
public HomeController() {
public ActionResult Index()
{
return View();
}
}
and home\index.cshtml:
#Html.Action("DataPartial", "Data")

Thanks, I figured it out. I made a partial view and I implemented that partial view in both index views (from home and the actual page of the list of data)

Related

Querying database but getting null back

I'm trying to list the items from my database into my view but I'm getting null back.
I know the connection must be working to a certain extent because in my database the tables didn't exist but once I ran my program it did create the tables. However when I add content into my table my view still returns NULL.
Also, haven't touched the Review table yet, just worried about getting Restaurants working.
Restaurant.cs
namespace OdeToFood.Models
{
public class Restaurant
{
public int Id { get; set; }
public string Name { get; set; }
public string City { get; set; }
public string Country { get; set; }
public ICollection<RestaurantReview> Reviews { get; set; }
}
}
OdeToFood.cs
namespace OdeToFood.Models
{
public class OdeToFoodDb : DbContext
{
public DbSet<Restaurant> Restaurants { get; set; }
public DbSet<RestaurantReview> Reviews { get; set; }
}
}
Controller
OdeToFoodDb _db = new OdeToFoodDb();
public ActionResult Index()
{
var model = _db.Restaurants.ToList();
return View();
}
Index.cshtml
#model IEnumerable<OdeToFood.Models.Restaurant>
#{
ViewBag.Title = "Home Page";
}
#{
if (Model != null)
{
foreach (var item in Model)
{
<div>
<h4>#item.Name</h4>
<div>#item.City, #item.Country</div>
<hr />
</div>
}
}
else
{
<h1>Null</h1>
}
}
You need to pass to model back to the view.
OdeToFoodDb _db = new OdeToFoodDb();
public ActionResult Index()
{
var model = _db.Restaurants.ToList();
return View(model);
}
You never actually send the model to the view. Pass it as an argument:
OdeToFoodDb _db = new OdeToFoodDb();
public ActionResult Index()
{
var model = _db.Restaurants.ToList();
return View(model);
}
Additionally, it's generally a good idea not to create database contexts in a shared scope. Keep the context as close to where it's used as possible and only expand its scope when you really need to. Something like this:
public ActionResult Index()
{
using (var _db = new OdeToFoodDb())
{
var model = _db.Restaurants.ToList();
return View(model);
}
}
Database contexts/connections in a shared scope is just asking for problems unless you pay close attention to what you're doing. As the code gets more complex, it becomes more likely that other methods will try to use it and it may be in an unknown state at that time.

How to implement ViewModels for asp.net MVC 5?

I am new to asp.net, there are some questions on stack overflow but they don't fulfill my purpose. My question is..
How would I implement view model for the following two models?
public class model1
{
int student-id{ get;set}
string student-name{get; set;}
}
public class model2
{
int course-code{get; set;}
string course-name{get; set;}
}
Now I want to write a view model that could pass to a view and this view displays student-name and corresponding course-names.
Note: a student can enrolled in more than one course.
First of all you should modify your model. Student and courses have to be related. You can implement these relations like:
public class Student
{
public int Id { get; set }
public string Name { get; set; }
public ICollection<Course> Courses { get; set; }
}
public class Course
{
public int Code { get; set; }
public string Name{ get; set; }
public ICollection<Student> Students { get; set; }
}
After - you create view model. View model class must contain only what you actually need in you view. In you case - student and courses names. You can consider several options here. If you want just to display all course names in one line you can build you StudentViewModel like this:
public class StudentViewModel
{
public string Name { get; set; }
// In this case you can just join all courses' names to one string using string.Join(", ")
public string Courses { get; set; }
}
... or like this - if you want courses' names separated (to use them in some select or list html element). But you can create JoinedCources property which will return courses' names joined into one string.
public class StudentViewModel
{
public string Name { get; set; }
public ICollection<string> Courses { get; set; }
public string JoinedCources {
get {
return string.Join(", ", Courses);
}
}
}
Note: this is view model for only one student! If you want to display view which shows you the list of students and their courses you should either create new view model with property which is collection of StudentViewModel or in your view define model like #model ICollection<StudentViewModel> instead of #model StudentViewModel.
Now you have to map your model to view model. For example in your controller action when you get your student from database (or any other data source - file or web service):
public ActionResult StudentDetails(int studentId)
{
var student = _dataSource.GetStudent(studentId);
var model = AutoMapper.Mapper.Map<StudentViewModel>(student);
return View(model);
}
Now few words about mapping. AutoMapper is external class library you should definitely get to learn about if you want to work with view models and mapping in the future. It will help you simplify action method code and make it more readable. But since you're new to ASP. Net you can implement mapping by your self for the first time. For example like below:
public ActionResult StudentDetails(int studentId)
{
var student = _dataSource.GetStudent(studentId);
var model = new StudentViewModel()
{
Name = student.Name,
Courses = student.Courses.Select(c => c.Name)
}
return View(model);
}
public class StudentViewModel
{
public string Name{get;set;}
public int StudentId{ get;set}
public List<model2> Courses
}
You can consider combining the two models into the above view model if the goal is to display a student with course info.

Entity framework how to pass data to view?

I am learning Entity Framework and MVC.
This is my model:
public class ChatLogContext : DbContext
{
public ChatLogContext()
: base("connString")
{
}
public DbSet<ChatLogs> ChatLogs { get; set; }
}
[Table("ChatLogs")]
public class ChatLogs
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int ChatLogId { get; set; }
[Column("Message")]
public string Message { get; set; }
[Column("UserId")]
public int UserId { get; set; }
}
And this is my controller code here:
public ActionResult Index()
{
using(var db = new ChatLogContext())
{
var list = db.ChatLogs.Select(p => p.Message).SingleOrDefault();
ViewBag.data = list;
return View();
}
}
I then access that data in view like this:
#model Chat.Models.ChatLogs
#Html.Raw(ViewBag.data)
I can access 1 record as seen here with this.
But I would like to learn, how to access all records from the table ChatLogs with Entity Framework and pass it to view with Razor method(foreach), so I can format that data (I don't like default tables that VS generates). I am now using ViewBag for one row and 1 column, this is the most far I came.
I just can't find an examples on Google that would help my brains.
Help appreciated.
PS: Is it better to work with pure entity or mix linq(linq to entities)?
Typically the Index action is for showing a grid of all the entities (in this case ChatLogs).
One of the points of the Razor View Engine is that you get typed Views. So typically I would pass the data to the view directly as opposed to using the ViewBag.
public ActionResult Index()
{
using(var db = new ChatLogContext())
{
var list = db.ChatLogs.ToList();
return View(list);
}
}
The next step is to have the View typed to IEnumerable<ChatLog>. Visual Studio should help you with that. Then you can just foreach over the ChatLogs.

MVC create using derived class

I'm new to MVC, so I apologize in advance if something doesn't make sense.
I have a base class (let's say "Person"), and 2 derived classes ("Student", "Professor").
I want to use 1 view for the Create functionality, with Partial views that contain the creation forms for either a student or professor. If I add a parameter, I can check against that to determine which partial view to show.
But my question is this: When the "Create" button is clicked, how can I determine which object is being created?
Edit (please bear w/ me, as I just created these to illustrate the problem)
Person class:
public class Person
{
public string Gender { get; set; }
public int ID { get; set; }
}
Student class:
public class Student : Person
{
public string LastName { get; set; }
public string FirstName { get; set; }
public List<Course> Courses { get; set; }
}
Professor class:
public class Professor : Person
{
public string LastName { get; set; }
public string FirstName { get; set; }
public double AnnualSalary { get; set; }
}
So then my Create controller looks like this:
public ActionResult Create(int personType) //1=student, 2=professor
{
var x = new {
Student = new Student(),
Professor = new Professor()
};
ViewBag.PersonType = personType;
return View(x);
}
Then my view looks like this:
<div>
#if (ViewBag.PersonType == 1)
{
#Html.Partial("CreateStudentPartialView", Model.Student)
}
else
{
#Html.Partial("CreateProfessorPartialView", Model.Professor)
}
So, the question is what would the associated create action look like, when the "Create" button is clicked in either partial view?
[HttpPost()]
public ActionResult Create(....) //What would I put as parameter(s)?
{
//no idea what to do here, since I don't know what object is being passed in
return RedirectToAction("Index");
}
Your best bet here is to have multiple POST actions in your controller.
So in the forms in your partial views, specify the action to hit
#using (Html.BeginForm("CreateStudent", "Create")) {
and
#using (Html.BeginForm("CreateProfessor", "Create")) {
Then your controller will look something like this:
[HttpPost]
public ActionResult CreateStudent(Student student)
{
//access the properties with the dot operator on the student object
//process the data
return RedirectToAction("Index");
}
and
[HttpPost]
public ActionResult CreateProfessor(Professor professor)
{
//access the properties with the dot operator on the professor object
//process the data
return RedirectToAction("Index");
}

Updating database when using View Models

I have a question abou view models and adding information to a database.
Let's say i have these two classes:
public class Ad {
public int Id { get; set; }
public int CategoryId { get; set; }
public string Headline { get; set; }
public string Text { get; set; }
public int Type { get; set; }
public Category Category { get; set; }
}
public class Category {
public int CategoryId { get; set; }
public int CategoryName { get; set; }
public IColletion<Ad> Ads { get; set; }
}
Context class:
public DbSet<Ad> Ads { get; set; }
public DbSet<Category> Categories { get; set; }
The models are really over simpified but i just want to get a grasp of the context. Lets say i want to create a view model for the view that are suppose to add entries to the db. How do i go about adding info to the "Ads" database table from a view model. Lets say the view model looks something like:
namespace Website.Models
{
public class CreateViewModel
{
public Ad Ad { get; set; }
public ICollection<Categories> Categories { get; set; }
public Dictionary<int, string> AdTypes { get; set; }
public CreateViewModel()
{
// to populate a dropdown on the "Create" page
this.Adtypes= new Dictionary<int, string>
{
{1, "For sale"},
{2, "Want to buy"},
{3, "Want to trade"},
{4, "Have to offer"}
};
}
}
}
The only thing i really need when adding to the db is the parameters in the Ad class (although i need the view model to render the dropdowns). But how do I extract this from the CreateViewModel to add to the db.
This is my code at the moment:
[HttpPost]
public ActionResult Create(Ad ad)
{
if (ModelState.IsValid)
{
db.Ads.Add(ad);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(ad);
Since this is expecting a Ad class, how do i extract only the Ad paramaters from the view model and insert it to the db.
Sorry, very long post and probably some serious newbie stuff. I just didn't know how to explain it better.
I would appreciate if someone could explain about view models, or direct me to some site that does.
/m
You can use Viewmodels when you need more data on the website like values for dropdowns. So lets say you want to create a car.
Car object (Car.cs)
public class Car
{
public int Id {get;set;}
public string Color {get;set;}
public string Name {get;set;}
}
But you don't want to type color by yourself in a textbox. Let's say you want to pick color from dropdown. If so you need to add somehow list (SelectList) of colors to a dropdown.
Viewmodel is helpful in this situation (CreateCarViewModel.cs)
public CreateCarViewModel
{
public Car Car {get;set;}
public SelectList Colors{ get; set; } //List of colors for dropdown
}
Controller
ActionResult CreateCar()
{
CreateCarViewModel CCVM = new CreateCarViewModel();
List<string> colors = new List<string>{"Black","White"};
CCVM.Colors = new SelectList(colors);
//Your view is expecting CreateCarViewModel object so you have to pass it
return View(CCVM);
}
CreateCar (CreateCar.cshtml)
#model YourSolutionName.ModelsFolder.CreateCarViewModel
//form etc.
{
#Html.DropDownListFor(x => x.Car.Color, Model.Colors)
#Html.TextBoxFor(x => x.Car.Name)
}
Controller Again
[HttpPost]
//Again: but now controller expects CreateCarViewModel
ActionResult CreateCar(CreateCarViewModel CCVM)
{
if (ModelState.IsValid)
//update database with CCVM.Car object and redirect to some action or whatever you want to do
else
{
//populate your colors list again
List<string> colors = new List<string>{"Black","White"};
CCVM.Colors = new SelectList(colors);
return View (CCVM);
}
}

Resources