I couldn't find a solution for my issue, I have tried many alternatives but I could not resolve it.
I generate my database with the model first, afterwards I have used Scaffolding to generate the Views (Index, Create, Edit, Delete..). The only view (Index) with the model use IEnumerable.
The Index View was :
#model IEnumerable<CAD_CMDBv2.Models.Location>
#{
ViewBag.Title = "Location's Management";
}
<h2>All Locations</h2>
<p>
#Html.ActionLink("Create Location", "Create")
</p>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.Location.site_name)
</th>
<th>
#Html.DisplayNameFor(model => model.Location.country_name)
</th>
<th>
#Html.DisplayNameFor(model => model.Location.region_name)
</th>
<th></th>
</tr>
#foreach(var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Location.site_name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Location.country_name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Location.region_name)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.Location.location_id }) |
#Html.ActionLink("Details", "Details", new { id = item.Location.location_id }) |
#Html.ActionLink("Delete", "Delete", new { id = item.Location.location_id })
</td>
</tr>
}
</table>
I want to insert an asynchronous form for the datasearch, so that becomes:
#model IEnumerable<CAD_CMDBv2.Models.RechercheLocationViewModel>
#{
ViewBag.Title = "Location's Management";
}
<h2>All Locations</h2>
<p>
#Html.ActionLink("Create Location", "Create")
</p>
#using (Html.BeginForm("Search", "Restaurant", FormMethod.Get))
{
#Html.TextBoxFor(r => r.Recherche)
<input type="submit" value="Rechercher" />
<p>Search Results </p>
if (Model.ListeLocations.Count == 0)
{
<p> No Results but you can create it !</p>
}
else
{
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.Location.site_name)
</th>
<th>
#Html.DisplayNameFor(model => model.Location.country_name)
</th>
<th>
#Html.DisplayNameFor(model => model.Location.region_name)
</th>
<th></th>
</tr>
#foreach(var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Location.site_name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Location.country_name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Location.region_name)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.Location.location_id }) |
#Html.ActionLink("Details", "Details", new { id = item.Location.location_id }) |
#Html.ActionLink("Delete", "Delete", new { id = item.Location.location_id })
</td>
</tr>
}
</table>
}
}
I have modified the model in adding a View Model class to allow in IndexView to take as model the View Model by taking over the parameters Locations and use the Search parameter:
//------------------------------------------------------------------------------
// <auto-generated>
// Ce code a été généré à partir d'un modèle.
//
// Des modifications manuelles apportées à ce fichier peuvent conduire à un comportement inattendu de votre application.
// Les modifications manuelles apportées à ce fichier sont remplacées si le code est régénéré.
// </auto-generated>
//------------------------------------------------------------------------------
namespace CAD_CMDBv2.Models
{
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
public partial class Location
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Location()
{
this.User = new HashSet<User>();
this.host = new HashSet<Host>();
this.client_catia = new HashSet<Client_catia>();
this.client_smartam = new HashSet<Client_smarteam>();
}
public int location_id { get; set; }
[Display(Name = "Site's Name")]
public string site_name { get; set; }
[Display(Name = "Country's Name")]
public string country_name { get; set; }
[Display(Name = "Region's Name")]
public string region_name { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<User> User { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Host> host { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Client_catia> client_catia { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Client_smarteam> client_smartam { get; set; }
}
public class RechercheLocationViewModel : IEnumerable<Location> {
public string Recherche {get; set;}
public Location Location { get; set; }
public List<Location> ListeLocations;
public IEnumerator<Location> GetEnumerator()
{
return ListeLocations.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return ListeLocations.GetEnumerator();
}
}
}
The current Controller
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using CAD_CMDBv2.Models;
namespace CAD_CMDBv2.Areas.Locations.Controllers
{
public class LocationsController : Controller
{
private ModeleDonneesCMDBContext db = new ModeleDonneesCMDBContext();
// GET: Locations/Locations
public ActionResult Index()
{
var liste = db.Locations.ToList();
var listeTriee = liste.OrderBy(t => t.site_name);
return View(listeTriee);
}
...
But that generates two errors of the same type about IEnumerable in the Index View on the lines:
#Html.TextBoxFor(r => r.Recherche)
And
if (Model.ListeLocations.Count == 0)
I got this error:
CS1061 Error 'IEnumerable' does not contain
a definition for 'ListeLocations' and no extension method
'ListeLocations' accepting a first argument of type
'IEnumerable' could be found (are
you missing a using directive or an assembly reference ?)
What does that mean? How can I resolve this? I still have some difficulty with understanding the IEnumerable interface.
Your Location class contains the properties Recherche and ListeLocation, but an IEnumerable of that class does not have those properties.
You are using the IEnumerable of the class as an instance of that class, that can't work.
You should think about what you need your model to be, because in one part of the view you use Model as if it were a Location, and in another part (#foreach(var item in Model) {) you use it as an IEnumerable
When you use the IEnumerable interface as a model, you are telling the View you have some kind of list, collection, or something you can 'Enumerate' as a model. A list of your Location objects, so to speak, not a single one.
Edit in response to your comments:
Change the #model IEnumerable<CAD_CMDBv2.Models.RechercheLocationViewModel> to CAD_CMDBv2.Models.RechercheLocationViewModel
Then you need yo change the controller Action:
Instead of :
var liste = db.Locations.ToList();
var listeTriee = liste.OrderBy(t => t.site_name);
return View(listeTriee);
use:
var model = new RechercheLocationViewModel();
model.AddRange(db.Locations.OrderBy(t => t.site_name));
return View(model);
But that won't make it 'work':
Your search query cannot take place in the view, you will have to go back to the server for that, so the architecture of your model is not quite right; you don't need all your locations in there, an what the single Location is there for I don't understand as well. If you want to do an async search in the view, you need an AJAX call back to the server that's going to return the search result. Your form is now just going to post something back to a Search action on your controller, and I don't know what that action does.
I can only advice you to study a bit more on creating search forms with AJAX in ASP.NET MVC
This is where your error is:
var listeTriee = liste.OrderBy(t => t.site_name);
return View(listeTriee);
Instead of passing a single model to your View, you are passing a collection (IEnumerable) which indeed doesn't have the property ListeLocations.
You should create a viewmodel and put the collection in there:
public class ListeTrieeViewModel
{
...
public IEnumerable<Locations> ListeLocations {get; set;}
}
Then you can pass that model in your controller:
public ActionResult Index()
{
var liste = db.Locations.ToList();
var listeTriee = liste.OrderBy(t => t.site_name);
var viewModel = new ListeTrieeViewModel { ListeLocations = listeTriee; }
return View(viewModel);
}
Now your check in the view will work:
if (Model.ListeLocations.Count() == 0)
Related
I am getting the following error on the below line:
"Model reference not set to instance of an object"
<select asp-for="FilmGenre" asp-items="Model.Genres">
I am including the file below for reference.
Any advice would be greatly appreciated!
Thanks.
#model MvcFilm.Models.FilmGenreViewModel
<!-- allows you to access the list of movies that the controller passed to the view by using a Model object that's strongly typed.-->
<!-- Because the Model object is strongly typed (as an IEnumerable object), each item in the loop is typed as Film. -->
#{
ViewData["Title"] = "Index";
}
<h1>Index</h1>
<p>
<a asp-action="Create">Create New</a>
</p>
<form asp-controller="Films" asp-action="Index" method="get">
<p>
<select asp-for="FilmGenre" asp-items="Model.Genres">
<option value="">All</option>
</select>
Title:
<input type="text" asp-for="SearchString" />
<input type="submit" value="Filter" />
</p>
</form>
<table class="table">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.Films[0].Title)
</th>
<th>
#Html.DisplayNameFor(model => model.Films[0].ReleaseDate)
</th>
<th>
#Html.DisplayNameFor(model => model.Films[0].Genre)
</th>
<th>
#Html.DisplayNameFor(model => model.Films[0].Price)
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.Films)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Title)
</td>
<td>
#Html.DisplayFor(modelItem => item.ReleaseDate)
</td>
<td>
#Html.DisplayFor(modelItem => item.Genre)
</td>
<td>
#Html.DisplayFor(modelItem => item.Price)
</td>
<td>
<a asp-action="Edit" asp-route-id="#item.Id">Edit</a> |
<a asp-action="Details" asp-route-id="#item.Id">Details</a> |
<a asp-action="Delete" asp-route-id="#item.Id">Delete</a>
</td>
</tr>
}
</tbody>
</table>
My model file: // FilmGenreViewModel.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Rendering;
using System.Collections.Generic;
namespace MvcFilm.Models
{
public class FilmGenreViewModel
// Films Genre view: Contains:
// - A list of films
// - A select list covering a list of genres.
// - A searchstring, which contains text that the users enter into the the search text box.
{
public List<Film> Films { get; set; }
public SelectList Genres { get; set; }
public string FilmGenre { get; set; }
public string SearchString { get; set; }
}
}
My controller file: FilmsController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;
using MvcFilm.Data;
using MvcFilm.Models;
namespace MvcFilm.Controllers
{
public class FilmsController : Controller
{
private readonly MvcFilmContext _context;
public object FilmGenreVM { get; private set; }
public FilmsController(MvcFilmContext context)
{
_context = context; // constructor uses dependency injection to inject the database context into the controller.
}
// GET: Films
public async Task<IActionResult> Index(string filmGenre, string searchString)
{
// Use LINQ to get a list of genres.
IQueryable<string> genreQuery = from m in _context.Film select m.Genre;
var films = from m in _context.Film
select m;
if (!String.IsNullOrEmpty(searchString))
{
films = films.Where(s => s.Title.Contains(searchString));
}
if (!string.IsNullOrEmpty(filmGenre))
{
films = films.Where(x => x.Genre == filmGenre);
}
var filmGenreVM = new FilmGenreViewModel
{
Genres = new SelectList(await genreQuery.Distinct().ToListAsync()),
Films = await films.ToListAsync()
};
return View(FilmGenreVM);
}
Object that passed to View from Controller method is null.
In the end of controller method should exists code like that:
var filmGenreViewModel = new FilmGenreViewModel();
//some code for initialize filmGenreViewModel may be here
return View(filmGenreViewModel);
As far as I know, if you want to use Select Tag helpers to render a SELECT element. You should set the view model's Genres type as List<SelectListItem>.
Like below:
public class CreateEmployeeViewModelData
{
//Other properties
public List<SelectListItem> Genres { set; get; }
}
Then you should build it in the controller method as below:
return View(new CreateEmployeeViewModelData {
Genres= new List<SelectListItem>
{
new SelectListItem {Text = "Shyju", Value = "1"},
new SelectListItem {Text = "Sean", Value = "2"}
}
);
}
Usage:
All
Result:
Besides, if the Genres is a list of class like below:
public class CreateEmployeeViewModelData
{
//Other properties
public List<Student> Genres { set; get; }
}
You could set it in controller like this:
return View(new CreateEmployeeViewModelData {
Genres= new List<Student>
{
new Student{Name = "Shyju", Id = "1"},
new Student{Name = "Sean", Id = "2"}
}
);
}
Then you could new SelectListItem in the select tag helper as below:
<select asp-for="FilmGenre" asp-items="#(new SelectList(Model.Genres,"Id","Name"))">
<option value="">All</option>
</select>
Realised the issue - it's a capitalization problem:
var filmGenreVM = new FilmGenreViewModel
{
Genres = new SelectList(await genreQuery.Distinct().ToListAsync()),
Films = await films.ToListAsync()
};
return View(FilmGenreVM);
}
Should be:
var filmGenreVM = new FilmGenreViewModel
{
Genres = new SelectList(await genreQuery.Distinct().ToListAsync()),
Films = await films.ToListAsync()
};
return View(filmGenreVM);
}
Im experiencing an error on trying to fetch data from a db using a list scaffolding. The error and the code is as follow.
My Model:
namespace ShimbaSchool.Models
{
[Table("tblStaff")]
public class Staff
{
[Key]
public int StaffId { get; set; }
[Required]
[DisplayName("Upload Image")]
public string ImagePath { get; set; }
[Required,MinLength(2),DisplayName("Staff Name")]
public string StaffName { get; set; }
[Required,MaxLength(250)]
[DisplayName("Teacher's Subject")]
public string StaffSpecialty { get; set; }
[NotMapped]
public HttpPostedFileBase ImageFile { get; set; }
}
}
My Controller:
namespace ShimbaSchool.Controllers
{
public class StaffController : Controller
{
EventMessageDepartmentContext db = new EventMessageDepartmentContext();
public ActionResult Index()
{
return View(db.StaffTable.ToList());
}
}
}
The View:
#model IEnumerable<ShimbaSchool.Models.Staff>
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_MyLayout.cshtml";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.ImagePath)
</th>
<th>
#Html.DisplayNameFor(model => model.StaffName)
</th>
<th>
#Html.DisplayNameFor(model => model.StaffSpecialty)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.ImagePath)
</td>
<td>
#Html.DisplayFor(modelItem => item.StaffName)
</td>
<td>
#Html.DisplayFor(modelItem => item.StaffSpecialty)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.StaffId }) |
#Html.ActionLink("Details", "Details", new { id=item.StaffId }) |
#Html.ActionLink("Delete", "Delete", new { id=item.StaffId })
</td>
</tr>
}
</table>
On executing i get the error:
The model item passed into the dictionary is of type 'System.Collections.Generic.List 1[ShimbaSchool.Models.Staff]', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable 1[ShimbaSchool.Models.EventMessageDepartment]'.
Please help me fix this situation and understand the logic so that there is no next time. To add on i used the same model with another controller and its working fine though the view were rendered on different layouts of the same project.
Actually the list you are passing from controller method to view is a List of EventMessageDepartment, not List of Staff. Please check it properly and pass List of Staff from controller method to the view.
If you are ensured that the data you are passing to the view is List<ShimbaSchool.Models.Staff> then please check your Layout.cshtml page. May be there is #model IEnumerable<EventMessageDepartment> is referenced.
Did you try the following?
public ActionResult Index()
{
return View(db.StaffTable.AsEnumerable());
}
First you need to return an IEnumerable version of your model to the list view.
#model IEnumerable<IdentityManager.Models.MerchantDetail>
Second, you need to return a list from the database. I am doing it via SQL Server, so this is code I got working.
public IActionResult Merchant_Boarding_List()
List<MerchantDetail> merchList = new List<MerchantDetail>();
var model = new MerchantDetail();
try
{
using (var con = new SqlConnection(Common.DB_CONNECTION_STRING_BOARDING))
{
con.Open();
using (var command = new SqlCommand("select * from MerchantDetail md where md.UserGUID = '" + UserGUID + "'", con))
{
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
model.biz_dbaBusinessName = reader["biz_dbaBusinessName"].ToString();
merchList.Add(model);
}
}
}
}
}
catch (Exception ex)
{
}
return View(merchList);
Why is this not working?
I feel like I am losing my mind.
I am using asp.net core with entity frameworks. This code in my controller is not working. I just want to return the ChildLans where the ParentOrgLevel contains 0001 at the beginning.
Model
public class CORP_MatrixPositionOLDWay
{
public int ID { get; set; }
public string ParentLAN { get; set; }
public string ChildLAN { get; set; }
public string ChildOrgLevel { get; set; }
public string ParentOrgLevel { get; set; }
}
View
model IEnumerable<Certifications.Models.CORP_MatrixPositionOLDWay>
#{
ViewData["Title"] = "Index";
}
<h2>Index</h2>
<p>
<a asp-action="Create">Create New</a>
</p>
<table class="table">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.ParentOrgLevel)
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.ParentOrgLevel)
</td>
<td>
<a asp-action="Edit" asp-route-id="#item.ID">Edit</a> |
<a asp-action="Details" asp-route-id="#item.ID">Details</a> |
<a asp-action="Delete" asp-route-id="#item.ID">Delete</a>
</td>
</tr>
}
</tbody>
</table>
Controller
public async Task<IActionResult> Index()
{
var ParentORG = _context.CORP_MatrixPositionOLDWay
.Where(i => i.ParentLAN == UserInformation.Globals.LANID)
.Select(i => i.ParentOrgLevel);
return View(ParentORG);
}
UserInformation.Globals.LANID is a string variable for the machines LANID
You are missing a lambda in your Where(), you can also just use StartsWith() instead of Contains() if you want to be more specific:
var list = _context.CORP_MatrixPositionOLDWay
.Where(x => x.ParentOrgLevel.StartsWith("0001"))
.Select(x => x.ChildLAN);
Given your latest edit
Your view expects a model of IEnumerable<Certifications.Models.CORP_MatrixPositionOLDWay>
Your action must return a View with that type as a model:
public async Task<IActionResult> Index()
{
var ParentORG = _context.CORP_MatrixPositionOLDWay
.Where(i => i.ParentLAN == UserInformation.Globals.LANID);
return View(ParentORG);
}
If you want your view to have only the ChildLAN properties (as you indicated in your comment below) then you'll have to adjust your view's model to be of type IEnumerable. However keep in mind that by doing this you will lose all the other functionality of your view (since its dependent on other properties of the CORP_MatrixPositionOLDWay class. What you likely want to do is create a new class called IndexViewModel or something like that. and have it contain both things you need:
public class IndexViewModel
{
//Name these properties better than I have
public IEnumerable<string> ChildLans {get;set;}
public IEnumerable<CORP_MatrixPositionOLDWay> DataList {get;set;}
}
This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 6 years ago.
So I am creating a strongly-typed view. My model is called RestaurantReview.cs and looks like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace OdeToFood.Models
{
public class RestaurantReview
{
public int Id { get; set; }
public string Name { get; set; }
public string City { get; set; }
public string Country { get; set; }
public int Rating { get; set; }
}
}
I had Visual Studio create a strongly-typed List model based on this, which looks like this:
#model IEnumerable<OdeToFood.Models.RestaurantReview>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
<th>
#Html.DisplayNameFor(model => model.Name)
</th>
<th>
#Html.DisplayNameFor(model => model.City)
</th>
<th>
#Html.DisplayNameFor(model => model.Country)
</th>
<th>
#Html.DisplayNameFor(model => model.Rating)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.City)
</td>
<td>
#Html.DisplayFor(modelItem => item.Country)
</td>
<td>
#Html.DisplayFor(modelItem => item.Rating)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.Id }) |
#Html.ActionLink("Details", "Details", new { id=item.Id }) |
#Html.ActionLink("Delete", "Delete", new { id=item.Id })
</td>
</tr>
}
</table>
When I run the site, I get a null pointer exception in the line "#foreach (var item in Model)", highlighting Model object, and stating "Object reference not set to an instance of an object."
Not really understanding how this code can be wrong since I didn't even write it, Visual Studio did. What is happening here?
Your Controller show have the RestaurantReview IEnumerable passed. Example:
public class HomeController : Controller { //suppose this is your Home
public ActionResult Index() {
IEnumerable<OdeToFood.Models.RestaurantReview> model;
model = from m in db.RestaurantReviews
... //your query here
select m;
return View(model); //pass the model here
}
Then you will not get null exception
Sounds like you haven't instantiated your model correctly within the Controller.
As a test you could try this:
public ActionResult Reviews()
{
var model = new List<OdeToFood.Models.RestaurantReview>();
model.Add(new OdeToFood.Models.RestaurantReview { Name = "Test" });
model.Add(new OdeToFood.Models.RestaurantReview { Name = "Test2" });
return View(model);
}
However the model should be correctly populated from the DB. If you can paste your Controller code that would help.
I have a BookingView class in Model:
public class BookingView
{
[Required]
[Display(Name = "Attraction")]
public int Attraction { get; set; }
[Required]
[Display(Name = "Date")]
public string Date { get; set; }
[Required]
[Display(Name = "Username")]
public string Username { get; set; }
}
Table against this model in DB is Tickets.
I need to write a function in another class in model named BookingManager to get all Ticket Records.
public IEnumerable<BookingView> GetAllBookings()
{
var a = from o in dre.Tickets select o;
return a.ToList();
}
I want to display these records in view named ViewAllBookings:
#model IEnumerable<VirtualTickets.Models.ViewModel.BookingView>
#{
ViewBag.Title = "ViewAllBookings";
}
<h2>ViewAllBookings</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
<th>
Attraction
</th>
<th>
Date
</th>
<th>
Username
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Attraction)
</td>
<td>
#Html.DisplayFor(modelItem => item.Date)
</td>
<td>
#Html.DisplayFor(modelItem => item.Username)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) |
#Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) |
#Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ })
</td>
</tr>
}
</table>
The function gives complie time error in function GetAllBookings on return statement. If I change return type to Ticket then I get runtime error as expected because in view ViewAllBookings it is expecting IEnumerable List of records having type BookingView.
Please provide a solution to this situation. I am really confused how to deal with this.
Thanks
It looks like your setup requires converting the entity class Ticket into the view model BookingView. I guess you need something like this:
return a.AsEnumerable().Select(ticket => new BookingView
{
Attraction = ticket.SomeProperty,
// etc
})
.ToList();
You have to write method that maps Ticket to BookingView and use it like this:
public IEnumerable<BookingView> GetAllBookings()
{
var a = from o in dre.Tickets select o;
return a.AsEnumerable().Select(Map).ToList();
}
private BookingView Map(Ticket ticket)
{
var bookingView = new BookingView();
//mapping code goes here
return bookingView;
}
I am not sure if your Tickets table actually has the same columns as the BookingView class in your code, but if theere's a mapping between the table and your class, your solution would be:
var a = from o in dre.Tickets
select new BookingView { Attraction= o.Attraction,
Date=o.Date,
Username = o.UserName } ;
return a.ToList();
Yes it is obvious that you are getting this error because you are returning a Ticket object and your view needs a list of BookingView objects. The 2 don't match, i.e. they are not the same.
Your BookingManager should return your tickets to the controller. Here is an alternative way of how I would have done it.
You could change your view model to look like this:
public class BookingViewModel
{
public List<Ticket> Tickets { get; set; }
}
Your BookingManager can contain the following method to return your tickets:
public class BookingManager : IBookingManager
{
// References to your database context
public IEnumerable<Ticket> GetAllTickets()
{
return databaseContext.Tickets;
}
}
In your booking controller you can inject an instance of IBookingManager with a dependency injection framework like AutoFac:
public class BookingController : Controller
{
private readonly IBookingManager bookingManager;
public BookingController(IBookingManager bookingManager)
{
this.bookingManager = bookingManager;
}
public ActionResult Index()
{
BookingViewModel viewModel = new BookingViewModel
{
Tickets = bookingManager.GetAllTickets().ToList()
};
return View(viewModel);
}
}
And then on your view:
#model YourProject.ViewModels.Tickets.BookingViewModel
#foreach (var ticket in Model.Tickets)
{
// Display ticket details here
}
I hope this helps.