HiddenInput attribute causes runtime error in HiddenInput.cshtml - c#

Update
So, I was looking at the wrong file all along. My project had two HiddenInput.cshtml files, one in the displayTemplate folder and one in the EditorTemplates. My brain wasn't making the connection I was looking at two different folders.
So this seems like a strange error to recieve when adding the hiddenInput attribute to a property in my ViewModel...
My guess to the cause is that because I have my ViewModels,Controllers, and Models in 3 separate projects. However, I made sure System.Data.Linq is referenced in all three when I was trying to debug this issue.
c:\proj\Adirondack.search\Views\Shared\EditorTemplates\HiddenInput.cshtml(9):
error CS0234: The type or namespace name 'Linq' does not exist in the
namespace 'System.Data' (are you missing an assembly reference?)
ViewModel
public class BasicSearchViewModel
{
public BasicSearchViewModel()
{
SalesFrom = new DateTime(1974, 1, 1);
SalesTo = DateTime.Today;
}
[Display(Name = "Owner", ShortName = "Owner", Prompt = "Enter Owner"), DataType(DataType.Text)]
public string OwnerName { get; set; }
[Display(Name = "Account Number", ShortName = "Strap", Prompt = "Enter Account Number"), DataType(DataType.Text)]
public string STRAP { get; set; }
[Display(Name = "Address", ShortName = "Addr.", Prompt = "Enter full address"), DataType(DataType.Text)]
public string Address { get; set; }
//public bool HasPool { get; set; }
public string Location { get; set; }
public string ZipCode { get; set; }
public bool Pool { get; set; }
public bool Tennis { get; set; }
public bool Dock { get; set; }
public bool SeaWall { get; set; }
[Display(Name = "Sales From")]
[Range(typeof(DateTime),"1/1/1974","12/31/2050")]
public DateTime SalesFrom { get; set; }
[Display(Name="Sales To")]
[Range(typeof(DateTime), "1/1/1974", "12/31/2050")]
public DateTime SalesTo { get; set; }
public int? SaleAmountFrom { get; set; }
public int? SaleAmountTo { get; set; }
public bool VacantLand { get; set; }
[ScaffoldColumn(false)]
public PagedList<ParcelResultItemViewModel> SearchResults { get; set; }
[HiddenInput]
public int? page { get; set; }
}
Search.cshtml
#using Search.Helpers;
#using Search.Components.Html.ViewModels;
#using PagedList.Mvc;
#model BasicSearchViewModel
#{
ViewBag.Title = "Search";
}
#Html.ActionLink("Advanced", "AdvancedSearch")
#Html.ActionLink("Tangible", "Search", "Tangible")
#using (Html.BeginForm("Search", "Parcel", FormMethod.Get, new { id = "searchForm" }))
{
<div>#Html.ValidationMessageFor(x => x)</div>
#Html.EditorFor(m => m)
<input type="submit" value="Refine" />
<h2>Results</h2>
<strong>Showing the first #Model.SearchResults.TotalItemCount of #ViewData["count"] results found </strong>
<table>
<tr>
<th>STRAP</th>
<th>SITUS</th>
<th>PROPERTY USE</th>
<th></th>
</tr>
#foreach (var item in Model.SearchResults)
{
<tr>
<td>
#Html.DisplayFor(x => item.STRAP)
</td>
<td>
#Html.DisplayFor(modelItem => item.SITUS)
</td>
<td>
#Html.DisplayFor(modelItem => item.SUBDIVISION_PROPERTY_USE)
</td>
<td rowspan="2">
#Html.ActionLink("Show Details", "Details", new { id = item.STRAP })
</td>
</tr>
<tr>
<td colspan="3">
#foreach (var owner in item.OWNERS.Take(2).OrderBy(x => x.LN_NUM))
{
#owner.NAME<br />
}
</td>
</tr>
}
</table>
<pre>
#HttpUtility.ParseQueryString(Model.AsQueryString())
</pre>
#Html.PagedListPager(Model.SearchResults, page => Url.Action("search",
new {Page = page,
owner = Model.OwnerName,
AccountNumber = Model.STRAP,
Address = Model.Address,
Location = Model.Location,
ZipCode = Model.ZipCode,
Pool = Model.Pool,
Tennis = Model.Tennis,
Dock = Model.Dock,
SeaWall = Model.SeaWall,
SalesFrom = Model.SalesFrom,
SalesTo = Model.SalesTo,
SaleAmountFrom = Model.SaleAmountFrom,
SaleAmountTo = Model.SaleAmountTo,
VacantLand = Model.VacantLand
}
))
}

You are using a LINQ expression in your razoe view. You need to have proper namespaces imported to your view to use the LINQ function.
Add using System.Linq; statement to your view.

Related

Failing to pass data from view to controller after submitting a form in MVC

In my project, I have Cinema, Movie, and Screening Models. Now I want that a user would be able to order tickets for a screening of his choice, according to his chosen cinema. First, the user will select a cinema, then he will see the screenings that are available for the cinema he chose.
Using a foreach method I'm iterating over the screenings available in the chosen cinema and display them inside forms, so the user can click the "Order Now" button to submit the form for the specific screening he chose.
Here you can see my view:
#model IEnumerable<CinemaProjectMVC.Models.Screening>
#{
ViewBag.Title = "OrderForm";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Buy Tickets</h2>
<table id="screenings" class="table table-bordered table-hover">
<thead>
<tr>
<th>Movie</th>
<th>Date</th>
<th>Tickets</th>
<th>Price</th>
<th>Order Now!</th>
</tr>
</thead>
<tbody>
#{
if (!Model.Any())
{
<tr>
<td class="empty-table" colspan="5">There are no screenings.</td>
</tr>
}
}
#foreach (var screening in Model)
{
using (Html.BeginForm("Save", "Orders"))
{
#Html.ValidationSummary(true, "Please fix the following errors.")
<tr>
<td>#screening.Movie.Name</td>
<td>#screening.Date.ToString("d MMM yyyy, HH:mm")</td>
<td>
#Html.TextBoxFor(s => screening, new { #type = "number", Value = "1" })
#Html.ValidationMessageFor(s => screening)
</td>
<td id="#screening.Price">#screening.Price</td>
<td><button type="submit" class="order-now-button">Order Now</button></td>
</tr>
#Html.HiddenFor(s => s.Id)
#Html.AntiForgeryToken()
}
}
</tbody>
</table>
Now, there is an issue with the line #Html.HiddenFor(s => s.Id), probably because I'm using an IEnumerable as a Model. Without passing the Id in the form I can't pass it to another action.
I tried changing this line to #Html.HiddenFor(s => screening.Id) which compiles, but still i'm not getting the data I need in the "Save" action.
My Action:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Save(Screening screening)
{
return RedirectToAction("", "");
}
Right now my action is empty, but through debugging I can see the "screening" variable is null after I submit the form.
This is the action that passes the data about screenings to the form in the OrderForm view:
public ActionResult AvailableScreenings(int id)
{
var screenings = _context.Screenings.Where(s => s.CinemaId == id).ToList();
var cinemas = _context.Cinemas.ToList();
var movies = _context.Movies.ToList();
var viewModel = new ScreeningFormViewModel
{
Cinemas = cinemas,
Movies = movies,
Date = DateTime.Now
};
return View("OrderForm", screenings);
}
And finally, I will add my Screening and ScreeningFormViewModel Models just in case -
Screening Model:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
namespace CinemaProjectMVC.Models
{
public class Screening
{
public int Id { get; set; }
public Cinema Cinema { get; set; }
[Required]
public byte CinemaId { get; set; }
public Movie Movie { get; set; }
[Required]
public byte MovieId { get; set; }
[Required]
public DateTime Date { get; set; }
[Required]
[Display(Name = "Available Seats")]
[ValidNumberOfSeats]
public int AvailableSeats { get; set; }
[Required]
[Range(0, int.MaxValue, ErrorMessage = "Please enter valid number")]
public int Price { get; set; }
public Screening() { }
public Screening(int id, Cinema cinema, Movie movie, byte cinemaId, byte movieId, DateTime date, int availableSeats, int price)
{
Id = id;
Cinema = cinema;
Movie = movie;
CinemaId = cinemaId;
MovieId = movieId;
Date = date;
AvailableSeats = availableSeats;
Price = price;
}
}
}
ScreeningFormViewModel:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using CinemaProjectMVC.Models;
using System.Linq;
using System.Web;
namespace CinemaProjectMVC.ViewModels
{
public class ScreeningFormViewModel
{
public int? Id { get; set; }
public IEnumerable<Cinema> Cinemas { get; set; }
[Required]
[Display(Name = "Cinemas")]
public byte? CinemaId { get; set; }
public IEnumerable<Movie> Movies { get; set; }
[Required]
[Display(Name = "Movies")]
public byte? MovieId { get; set; }
[Required]
public DateTime Date { get; set; }
[Required]
[Display(Name = "Available Seats")]
public int AvailableSeats { get; set; }
[Required]
[Range(0, int.MaxValue, ErrorMessage = "Please enter valid number")]
public int Price { get; set; }
public string Title
{
get
{
return Id != 0 ? "Edit Screening" : "New Screening";
}
}
public ScreeningFormViewModel()
{
Id = 0;
}
public ScreeningFormViewModel(Screening screening)
{
Id = screening.Id;
CinemaId = screening.CinemaId;
MovieId = screening.MovieId;
Date = screening.Date;
AvailableSeats = screening.AvailableSeats;
Price = screening.Price;
}
}
}
I'm not sure where my problem is, maybe I'm not passing the right Model to the view, or maybe there are other issues in my form.
You can do so by modifying your view code as:
#for(int i=0;i<Model.Count;i++)
{
using (Html.BeginForm("Save", "Orders"))
{
#Html.ValidationSummary(true, "Please fix the following errors.")
<tr>
<td>#Html.DisplayFor(m=>m[i].Movie.Name</td>
<td>#Html.DisplayFor(m=>m[i].Date.ToString("d MMM yyyy, HH:mm"))</td>
<td>
#Html.TextBoxFor(m =>m[i].screening, new { #type = "number", Value = "1" })
#Html.ValidationMessageFor(m =>m[i].screening)
</td>
<td>m=>m[i].Price</td>
<td><button type="submit" class="order-now-button">Order Now</button></td>
</tr>
#Html.HiddenFor(m => m[i].Id)
#Html.AntiForgeryToken()
}
}
Using this you can easily achieve what you actually wanted with the iterative form or we can say order based form.
Let me know if this answer is useful to you.

C# MVC Return ViewModel to List

I decided to post a new question rather then add to the existing because it is not the same issue. I followed the comment to the other question to create a ViewModel.
I have not had, up to this point, had to list from a ViewModel. I did search online to see if I could find an example but all I found was; How to create a list in a ViewModel, which I already know how to do.
I have a ViewModel below. I am not sure that it is structured properly or not but the controller is returning count = 0
Controller:
public ActionResult Index()
{
List<AccountingViewModels> list = new List<AccountingViewModels>();
return View(list);
}
The View Has This: #model IEnumerable<BestenEquipment.Models.AccountingViewModels>
I did try to do this #model List<BestenEquipment.Models.AccountingViewModels>
But got an Error 'List<AccountingViewModels>' does not contain a definition for 'Description' and no extension method 'Description' accepting a first argument of type 'List<AccountingViewModels>' could be found (are you missing a using directive or an assembly reference?)
Controller is still count = 0
The IEnumerable does not error out it just gives me an empty table. So I am thinking the IEnumerable is the way to go. I just need to fix the controller.
If someone could point me in the right direction or tell me what I have wrong in my Controller it would help a great deal.
Here is the ViewModel:
public class AccountingViewModels
{
[Key]
public Guid TransactionId { get; set; }
public string Description { get; set; }
[Display(Name = "Company")]
public int? CompanyId { get; set; }
[Display(Name = "Vendor")]
public Guid? VendorId { get; set; }
[Display(Name = "Rec Chk #")]
public string InCheckNumber { get; set; }
[Display(Name = "Sent Chk #")]
public string OutCheckNumber { get; set; }
[Display(Name = "Invoice #")]
public string InvoiceNumber { get; set; }
[Display(Name = "PO #")]
public string PurchaseOrderNumber { get; set; }
[Display(Name = "Ledger Acct")]
public Guid LedgerAccountId { get; set; }
[Display(Name = "Credit")]
public decimal? DebitAmount { get; set; }
[Display(Name = "Debit")]
public decimal? CreditAmount { get; set; }
[Display(Name = "Transaction")]
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = false)]
public DateTime TransactionDate { get; set; }
[Display(Name = "Modified By")]
public string ModifiedBy { get; set; }
[Display(Name = "Modified")]
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = false)]
public DateTime? ModifiedDate { get; set; }
public string SavedDocument { get; set; }
[Display(Name = "Created")]
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = false)]
public DateTime CreatedDate { get; set; }
[Display(Name = "Created By")]
public string CreatedBy { get; set; }
public bool IsCredit { get; set; }
public bool IsDebit { get; set; }
public Guid Type { get; set; }
[ForeignKey("LedgerAccountId")]
public LedgerAccount LedgerAccount { get; set; }
[ForeignKey("CompanyId")]
public CompanyNames Company { get; set; }
[ForeignKey("VendorId")]
public Vendors Vendor { get; set; }
}
This is most likely a simple fix, I just need a nudge..
Using the db model is like this: return View(db.Transaction.ToList());
I need to do the same but with a ViewModel..
Thanks for your help!
Thanks
UPDATE:
Here is the link to my Original problem and was told to create a viewModel..
Original Issue
UPDATE:
Adding View:
#model List<BestenEquipment.Models.AccountingViewModels>
#{
Layout = "~/Views/Shared/_DashboardLayout.cshtml";
}
#section ScriptsOrCss
{
#Html.Action("DataTableCssJs", "Layout")
}
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<section class="content-header">
<h1>
Overview List
<small> Transactions </small>
</h1>
</section>
<section class="content">
<!-- Small boxes (Stat box) -->
<div class="row">
<div class="col-md-12">
#if (ViewBag.Create == true)
{
<div class="box box-solid box-primary">
<div class="box-body">
<!-- Split button -->
<div class="margin">
<div class="btn-group">
#Ajax.ModalDialogActionLink("Create Quick", "Create", "Create ", "btn btn-info btn-sm")
</div>
<div class="btn-group">
Create Full
</div>
</div>
<!-- flat split buttons -->
</div><!-- /.box-body -->
</div>
}
<div class="box box-primary">
<div class="box-header">
<h3 class="box-title">Orders</h3>
</div><!-- /.box-header -->
<div class="box-body table-responsive">
<table class="table table-striped table-hover table-bordered" id="TransactionListTable">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.Description)
</th>
<th>
#Html.DisplayNameFor(model => model.Company.CompanyName)
</th>
<th>
#Html.DisplayNameFor(model => model.Vendor.Name)
</th>
<th>
#Html.DisplayNameFor(model => model.InCheckNumber)
</th>
<th>
#Html.DisplayNameFor(model => model.OutCheckNumber)
</th>
<th>
#Html.DisplayNameFor(model => model.InvoiceNumber)
</th>
<th>
#Html.DisplayNameFor(model => model.PurchaseOrderNumber)
</th>
<th>
#Html.DisplayNameFor(model => model.LedgerAccountId)
</th>
<th>
#Html.DisplayNameFor(model => model.DebitAmount)
</th>
<th>
#Html.DisplayNameFor(model => model.CreditAmount)
</th>
<th>
#Html.DisplayNameFor(model => model.TransactionDate)
</th>
<th>
CRUD
</th>
<th>
Actions
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.Items)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Description)
</td>
<td>
#if (item.CompanyId != null)
{
#Html.DisplayFor(modelItem => item.Company.CompanyName)
}
else
{
<b>N/A</b>
}
</td>
<td>
#if (item.VendorId != null)
{
#Html.DisplayFor(modelItem => item.Vendor.Name)
}
else
{
<b>N/A</b>
}
</td>
<td>
#if (item.InCheckNumber != null)
{
#Html.DisplayFor(modelItem => item.InCheckNumber)
}
else
{
<b>N/A</b>
}
</td>
<td>
#if (item.OutCheckNumber != null)
{
#Html.DisplayFor(modelItem => item.OutCheckNumber)
}
else
{
<b>N/A</b>
}
</td>
<td>
#if (item.InvoiceNumber != null)
{
#Html.DisplayFor(modelItem => item.InvoiceNumber)
}
else
{
<b>N/A</b>
}
</td>
<td>
#if (item.PurchaseOrderNumber != null)
{
#Html.DisplayFor(modelItem => item.PurchaseOrderNumber)
}
else
{
<b>N/A</b>
}
</td>
<td>
#Html.DisplayFor(modelItem => item.LedgerAccount.Title)
</td>
<td>
#if (item.IsDebit == true)
{
#Html.DisplayFor(modelItem => item.DebitAmount)
}
else
{
<b>N/A</b>
}
</td>
<td>
#if (item.IsCredit == true)
{
#Html.DisplayFor(modelItem => item.CreditAmount)
}
else
{
<b>N/A</b>
}
</td>
<td>
#Html.DisplayFor(modelItem => item.TransactionDate)
</td>
<td>
#if (ViewBag.Edit == true)
{
#Ajax.ModalDialogActionLink("Edit", "Edit", "Edit", "btn btn-warning btn-sm", new { id = item.TransactionId })
}
#if (ViewBag.Read == true)
{
#Ajax.ModalDialogActionLink("Details", "Details", "Transaction Details", "btn btn-info btn-sm", new { id = item.TransactionId })
}
#if (ViewBag.Delete == true)
{
#Ajax.ActionLink("Delete", "Delete", "Tranaction", new { id = item.TransactionId },
new AjaxOptions()
{
HttpMethod = "Delete",
Confirm = "Are you sure you want to delete " + item.Description + "Transaction",
}, new { #class = "btn btn-danger btn-sm Delete" })
}
</td>
<td>
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
</div>
</div>
I replicated your error. Try this.
Instead of this one:
#model List<BestenEquipment.Models.AccountingViewModels>
Use this:
#model IEnumerable<BestenEquipment.Models.AccountingViewModels>
Then lastly, remove the Items word on your foreach loop, it should be:
#foreach (var item in Model)
Public class AcctModel
{
public IEnumerable<AccountingViewModels> Items {get; set;}
}
In view.cshtml
foreach(var item in Model.Items)
{
// Your code here
}
I have found that when you are just listing records it is easier to use SQL Views. There isn't any creating or editing with this so just to populate what you need is easier that way. The Databases job is to do the work so why not let it!
Here is what I did incase someone needs something like this or is looking for a cleaner way to do it.
Remember I needed Joins from tables in 2 separate databases. Creating a View in the same database is easier, you just select the tables and then the fields you want.
First Create the View, in my case I needed to do the query with aliases and did not use the GUI.
SQL:
SELECT t.TransactionId, t.Description, t.InCheckNumber, t.OutCheckNumber, t.InvoiceNumber, t.PurchaseOrderNumber, la.Title, t.DebitAmount, t.CreditAmount, t.TransactionDate, t.SavedDocument, t.CreatedDate, t.CreatedBy, tt.Type,
cn.CompanyName, v.Name
FROM dbo.LedgerAccount AS la INNER JOIN
dbo.[Transaction] AS t ON la.LedgerAccountId = t.LedgerAccountId
INNER JOIN
dbo.TransactionType AS tt ON t.Type = tt.TypeId INNER JOIN
OtherDBName.dbo.CompanyNames AS cn ON t.CompanyId =
cn.CompanyId LEFT OUTER JOIN
OtherDbName.dbo.Vendors AS v ON t.VendorId = v.VendorId
I called the Transaction table t the Type table as tt and when you are referencing another database you have to use dbname.schema.table.column These I gave the names cn for CompanyNames table and v for Vendors table. In my particular case I will not always have a Vendor name in every record so you do a LEFT OUTER JOIN
Once this is created you can now go back to your project and create the Entity.
In Your Context you will create this as if it is just another table. With the exception of not mapping it. There is no need to. We are not using this for CRUD actions.
I called the view TransactionsView:
public class AccountingEntities : DbContext
{
public AccountingEntities() : base("AccountingConnection")
{
}
[NotMapped]
public IDbSet<TransactionsView> TransactionsView { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
Usings:
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;
using System.ComponentModel.DataAnnotations.Schema;
Then create the Model TranactionsView:
using System;
using System.ComponentModel.DataAnnotations;
namespace YourProject.AccountingDTO.Entities
{
public class TransactionsView
{
[Key]
public Guid TransactionId { get; set; }
[Display(Name = "Desc")]
public string Description { get; set; }
[Display(Name = "Company")]
public string CompanyName { get; set; }
[Display(Name = "Vendor")]
public String Name { get; set; }
[Display(Name = "Rec Chk #")]
public string InCheckNumber { get; set; }
[Display(Name = "Sent Chk #")]
public string OutCheckNumber { get; set; }
[Display(Name = "Invoice #")]
public string InvoiceNumber { get; set; }
[Display(Name = "PO #")]
public string PurchaseOrderNumber { get; set; }
[Display(Name = "Ledger Acct")]
public string Title { get; set; }
[Display(Name = "Credit")]
public decimal? DebitAmount { get; set; }
[Display(Name = "Debit")]
public decimal? CreditAmount { get; set; }
[Display(Name = "Transaction")]
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = false)]
public DateTime TransactionDate { get; set; }
[Display(Name = "Doc Link")]
public string SavedDocument { get; set; }
[Display(Name = "Created")]
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = false)]
public DateTime CreatedDate { get; set; }
[Display(Name = "Created By")]
public string CreatedBy { get; set; }
[Display(Name = "Type")]
public string Type { get; set; }
}
}
The in the Controller:
private readonly AccountingEntities account = new AccountingEntities();
// GET: Transaction
public ActionResult Index()
{
return View(account.TransactionsView.ToList());
}
In the View you just create a List View and put your #model at the top:
#model IEnumerable<YourProject.AccountingDTO.Entities.TransactionsView>
I tried to be as thorough as possible if I missed something I can answer any questions you may have. I use these all the time for List Views and tables

.NET Use A Related Table To Decide What Information to Show

I have a client model a identifier model and a link model. The identifier model contains websites available for posting, client model contains clients that need a specific amount of links per month. A link object in the link model contains the Identifier ID and the Client ID. I want another view displaying a table of all the Identifier ID's that haven't been used with a Client ID's in the Link model table if this makes sense?
Client Model:
namespace Linkofy.Models
{
public class Client
{
public int ID { get; set; }
[Required]
[Display(Name = "Client")]
public string clientN { get; set; }
[Url]
[Display(Name = "Website")]
public string homePage{ get; set; }
[EmailAddress]
[Display(Name = "Contact Email")]
public string clientEmail { get; set; }
[Display(Name = "Contact Name")]
public string contName { get; set; }
[Display(Name = "Monthly")]
public int monthlyQuota { get; set; }
[Display(Name = "TF")]
public int TrustFlow { get; set; }
[Display(Name = "CF")]
public int CitationFlow { get; set; }
public int RI { get; set; }
public int? MJTopicsID { get; set; }
public virtual MJTopics MJTopics { get; set; }
public int UserTableID { get; set; }
public virtual UserTable UserTable { get; set; }
public virtual ICollection<Link> Links { get; set; }
public virtual ICollection<Status> Statuss { get; set; }
}
}
Link Model:
namespace Linkofy.Models
{
public class Link
{
public int LinkID { get; set; }
[Required]
[Display(Name = "Linking Page")]
public string Obdomain { get; set; }
public int? ClientID { get; set; }
public virtual Client Client { get; set; }
[Required]
[Display(Name = "Outbound Link")]
public string Obpage { get; set; }
[Required]
[Display(Name = "Anchor Text")]
public string Anchor { get; set; }
[Required]
[Display(Name = "Date Built")]
public DateTime BuildDate { get; set; }
public int IdentifierID { get; set; }
public virtual Identifier Identifier { get; set; }
public int? UserTableID { get; set; }
public virtual UserTable UserTable { get; set; }
}
}
Domain Model:
public class Identifier
{
public enum Ltype
{
GuestPost, ExistingLink
}
public int ID { get; set; }
[Url]
[Required]
[Display(Name = "Domain")]
public string domain { get; set; }
[Required]
[Display(Name = "Contact Email")]
[EmailAddress]
public string contact { get; set; }
[Display(Name = "Contact Name")]
public string contactname { get; set; }
[Required]
[Display(Name = "Price")]
public int price { get; set; }
[Display(Name = "Type of Link")]
public Ltype? type { get; set; }
[Display(Name = "TF")]
public int TrustFlow { get; set; }
[Display(Name = "CF")]
public int CitationFlow { get; set; }
public int RI { get; set; }
public int? MJTopicsID { get; set; }
public virtual MJTopics MJTopics { get; set; }
public virtual UserTable UserTable { get; set; }
public int UserTableID { get; set; }
public virtual ICollection<Link> Links { get; set; }
}
}
Model View:
#model IEnumerable<Linkofy.Models.Identifier>
#{
ViewBag.Title = "Index";
}
#section Styles {
<link href="#Url.Content("~/Styles/Index.css")" rel="stylesheet" type="text/css" />
}
<h1>Domain List</h1>
<p class="options"> #Html.ActionLink("Add New", "Create") | #Html.ActionLink("Add Bulk", "CreateBulk") </p>
<div class="row">
<div class="col-md-12">
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.domain)
</th>
<th>
#Html.DisplayNameFor(model => model.contact)
</th>
<th>
#Html.DisplayNameFor(model => model.contactname)
</th>
<th>
#Html.DisplayNameFor(model => model.price)
</th>
<th>
#Html.DisplayNameFor(model => model.type)
</th>
<th>
#Html.DisplayNameFor(model => model.TrustFlow)
</th>
<th>
#Html.DisplayNameFor(model => model.CitationFlow)
</th>
<th>
#Html.DisplayNameFor(model => model.RI)
</th>
<th>
#Html.DisplayNameFor(model => model.MJTopics.topicalTF)
</th>
<th></th>
</tr>
#foreach (var item in Model.Where(Model.Links.Item => item.ClientID != ViewBag.ClientID)) {
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.domain)
</td>
<td>
#Html.DisplayFor(modelItem => item.contact)
</td>
<td>
#Html.DisplayFor(modelItem => item.contactname)
</td>
<td>
#Html.DisplayFor(modelItem => item.price)
</td>
<td>
#Html.DisplayFor(modelItem => item.type)
</td>
<td>
#Html.DisplayFor(modelItem => item.TrustFlow)
</td>
<td>
#Html.DisplayFor(modelItem => item.CitationFlow)
</td>
<td>
#Html.DisplayFor(modelItem => item.RI)
</td>
<td>
#Html.DisplayFor(modelItem => item.MJTopics.topicalTF)
</td>
<td>
#Html.ActionLink(" ", "Details", new { id=item.ID }, new {#class= "glyphicon glyphicon-home" })
#Html.ActionLink(" ", "Edit", new { id=item.ID }, new {#class= "glyphicon glyphicon-edit" })
#Html.ActionLink(" ", "Delete", new { id=item.ID }, new {#class= "glyphicon glyphicon-trash" })
</td>
</tr>
}
</table>
</div>
</div>
I achieved this using LINQ statements as mentioned by Zorkind in comments.

#Html.DropDownList does not set selected value

I have an MVC 4 application and what I am trying to do is to list the events of a specific booking (together with some information about the booking - this by using viewbags) in the same page (using the Events model only). So that goes fine until I add a dropdown-list to change the statusCode of that booking (that all the listing events are related to).
#Html.DropDownList("StatusCodeList")
Whatever I do, it doesn't change. Please help me to find out why !
Models
public class Booking
{
[Key]
public int BookingId { get; set; }
[DisplayName("Event Title")]
public string EventTitle { get; set; }
[DisplayName("Requester's Name")]
public string UserFullName { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
public System.DateTime RequestDate { get; set; }
[DisplayName("Event Date")]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
public System.DateTime EventDate { get; set; }
[DisplayName("Login")]
public string Login { get; set; }
[DisplayName("NetworkID")]
public string NetworkID { get; set; }
public string BookingTotalCost { get; set; }
[ForeignKey("StatusCode")]
public int StatusCodeId { get; set; }
public virtual StatusCode StatusCode { get; set; }
[Required(ErrorMessage = "Event Type is required.")]
[ForeignKey("CateringType")]
public int CateringTypeId { get; set; }
public virtual CateringType CateringType { get; set; }
public List<Event> Events { get; set; }
}
public class Event
{
[Key]
public int EventId { get; set; }
[Required(ErrorMessage = "Event Leader is required")]
[DisplayName("Event Leader")]
public string EventLeader { get; set; }
[Required(ErrorMessage = "Budget Code is required")]
[DisplayName("Budget Code")]
public string EventBudgetCode { get; set; }
[DisplayName("Special Requirements")]
public string SpecialRequirements { get; set; }
[DisplayName("Event Cost")]
public string EventTotalCost { get; set; }
[Required(ErrorMessage = "Participants are required")]
[Range(1, 300, ErrorMessage = "Participants must be </br> between 1 and 300")]
[StringLength(3, ErrorMessage = "Max 3 digits")]
[DisplayName("Participants")]
public string EventParticipants { get; set; }
[Required(ErrorMessage = "Room is required")]
[DisplayName("Room Number")]
[ForeignKey("Room")]
public int RoomId { get; set; }
public virtual Room Room { get; set; }
[Required(ErrorMessage = "Start Time is required")]
[DisplayName("Start Time")]
[DataType(DataType.Time)]
public DateTime EventStartDateTime { get; set; }
[Required(ErrorMessage = "End Time is required")]
[DisplayName("End Time")]
[DataType(DataType.Time)]
[DateEnd(DateStartProperty = "EventStartDateTime")]
public DateTime EventEndDateTime { get; set; }
[ForeignKey("Booking")]
public int BookingId { get; set; }
public virtual Booking Booking { get; set; }
[Required(ErrorMessage = "Dietary Requirements are required")]
[DisplayName("Dietary Requirement")]
[ForeignKey("DietaryRequirement")]
public int DietaryRequirementId { get; set; }
public virtual DietaryRequirement DietaryRequirement { get; set; }
public ICollection<CateringItem> CateringItems { get; set; }
}
Controller
public ActionResult RequestDetails(int id)
{
var eventList = from s in SystemDB.Events
where s.BookingId == id
select s;
Booking booking = SystemDB.Bookings.Find(id);
ViewBag.Date = booking.EventDate.ToShortDateString();
ViewBag.BookingId = id;
ViewBag.Requester = booking.UserFullName;
ViewBag.RequesterEmail = booking.NetworkID + "#gmail.com";
var sum = (from s in SystemDB.Events.ToList()
where s.BookingId == id
select Convert.ToDecimal(s.EventTotalCost)).Sum();
if (booking.BookingTotalCost == null && sum == 0)
{
ViewBag.BookingTotalCost = "0";
}
else
{
ViewBag.BookingTotalCost = sum;
}
TempData["BookingId"] = id;
var statuscodes = SystemDB.StatusCodes.Where(s => s.StatusCodeId != 1);
ViewBag.StatusCodeList = new SelectList(statuscodes, "StatusCodeId", "StatusCodeName", booking.StatusCodeId);
return View(eventList);
}
[HttpPost]
[ActionName("RequestDetails")]
public ActionResult PostRequestDetails(int id)
{
TempData["BookingId"] = id;
var eventList = from s in SystemDB.Events
where s.BookingId == id
select s;
ViewBag.BookingId = id;
Booking booking = SystemDB.Bookings.Find(id);
ViewBag.Date = booking.EventDate.ToShortDateString();
ViewBag.BookingId = id;
ViewBag.Requester = booking.UserFullName;
ViewBag.RequesterEmail = booking.NetworkID + "#gmail.com";
var sum = (from s in SystemDB.Events.ToList()
where s.BookingId == id
select Convert.ToDecimal(s.EventTotalCost)).Sum();
booking.BookingTotalCost = sum.ToString();
var statuscodes = SystemDB.StatusCodes.Where(s => s.StatusCodeId != 1);
ViewBag.StatusCodeList = new SelectList(statuscodes, "StatusCodeId", "StatusCodeName", booking.StatusCodeId);
if (ModelState.IsValid)
{
SystemDB.Entry(booking).State = EntityState.Modified;
SystemDB.SaveChanges();
return RedirectToAction("RequestList", "Admin", new { id = id });
}
return View(eventList);
}
View
#model IEnumerable<CateringBookingSystem.Models.Event>
#using (Html.BeginForm())
{
<span><b>Booking for: </b>#ViewBag.Date</span> <span style="padding-left:20px;"><b>Total Cost: </b>£#ViewBag.BookingTotalCost</span> <span style="padding-left:20px;"><b>Requester: </b>#ViewBag.Requester</span> <span style="padding-left:20px;"><b>Status: </b> #Html.DropDownList("StatusCodeList") </span>
<table id="listTable" style="width:100%" >
<tr style="color:white;">
<th>
#Html.DisplayNameFor(model => model.EventLeader)
</th>
<th>
#Html.DisplayNameFor(model => model.EventStartDateTime)
</th>
<th>
#Html.DisplayNameFor(model => model.EventEndDateTime)
</th>
<th>
#Html.DisplayNameFor(model => model.Room.RoomNumber)
</th>
<th>
#Html.DisplayNameFor(model => model.EventParticipants)
</th>
<th>
#Html.DisplayNameFor(model => model.EventTotalCost)
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.EventLeader)
</td>
<td>
#Html.DisplayFor(modelItem => item.EventStartDateTime)
</td>
<td>
#Html.DisplayFor(modelItem => item.EventEndDateTime)
</td>
<td>
#Html.DisplayFor(modelItem => item.Room.RoomNumber)
</td>
<td>
#Html.DisplayFor(modelItem => item.EventParticipants)
</td>
<td>
£#Html.DisplayFor(modelItem => item.EventTotalCost)
</td>
<td>
#Html.ActionLink("Amend", "EditEventForEventList", new { EventId = item.EventId, Amend = "True" }) |
<a class="clicker" dialogid="#item.EventId" href="#"> View Catering</a> |
<div class="dialog #item.EventId " title="">
<p>#{Html.RenderAction("ViewEvent", "Home", new { EventId = item.EventId });}</p>
</div>
#Html.ActionLink("Delete", "DeleteEventFromEventList", new { id = item.EventId })
</td>
</tr>
}
</table>
<div style="padding-top:50px;">
<input type="submit" value="submit" />
</div>
}

The model item passed into the dictionary is of type 'yyyy', but this dictionary requires a model item of type 'xx'

I have two model and I want to show in one view. So I'm using
#Html.Partial
This is my first Model.
public partial class graduandModel :BaseNopEntityModel
{
public graduandModel()
{
this.AvailableCeremony = new List<SelectListItem>();
}
public string first_name { get; set; }
public string middle_name { get; set; }
public string last_name { get; set; }
public int student_id { get; set; }
public int ceremony_id { get; set; }
public DateTime ceremony_date { get; set; }
public int graduand_id { get; set; }
public IList<SelectListItem> AvailableCeremony { get; set; }
public graduandDegreeModel graduandDegreeGroup { get; set; }
}
This is my second Model.
public class graduandDegreeModel
{
public graduandDegreeModel()
{
this.AvailableDegree = new List<SelectListItem>();
}
public string degree_id { get; set; }
public int graduand_id { get; set; }
public string degree_name { get; set; }
public IList<SelectListItem> AvailableDegree { get; set; }
}
This is mu controller
public ActionResult CheckData(int ceremony_id, string first_name, string middle_name, string last_name)
{
graduandModel model = new graduandModel();
graduandDegreeModel model_1 = new graduandDegreeModel();
var graduandList = _graduandService.GetGraduandByStudent(ceremony_id, first_name, middle_name, last_name);
if (graduandList.Count != 0)
{
model.ceremony_id = ceremony_id;
model.first_name = first_name;
model.middle_name = middle_name;
model.last_name = last_name;
// var degreeList = "";
foreach (var c in graduandList)
{
var degreeList = _graduandDegreeService.getAllDegreeIdBtGraduandId(c.graduand_id);
foreach (var d in degreeList)
{
model_1.AvailableDegree.Add(new SelectListItem() { Text = d.Degree.degree_name, Value = d.degree_id });
}
}
}
return View(model);
}
This is my views
#{
Layout = "~/Views/Shared/_ColumnsThree.cshtml";
}
#model graduandModel
#using Nop.Web.Models.Hire;
#using Nop.Web.Framework;
#using Telerik.Web.Mvc.UI;
#using System.Linq;
#using (Html.BeginForm())
{
<table >
<tr>
<td >
Ceremony :
</td>
<td>
Ceremony at #Model.ceremony_date
</td>
</tr>
<tr>
<td >
Name :
</td>
<td >
#Model.first_name #Model.middle_name #Model.last_name
</td>
</tr>
</table>
<div>
#Html.Partial("_DegreeDetailsByGraduand", Model.graduandDegreeGroup)
</div>
}
This is my Partial view
#{
Layout = "~/Views/Shared/_ColumnsThree.cshtml";
}
#model graduandDegreeModel
#using Nop.Web.Models.Hire;
#using Nop.Web.Framework;
#using Telerik.Web.Mvc.UI;
#using System.Linq;
<table >
<tr>
<td >
AAAAAA
</td>
<td>
#Html.DropDownListFor(model => model.degree_id, Model.AvailableDegree)
#* #Html.ValidationMessageFor(model => model.ceremony_id)*#
</td>
</tr>
</table>
there is error
The model item passed into the dictionary is of type 'Nop.Web.Models.Hire.graduandModel', but this dictionary requires a model item of type 'Nop.Web.Models.Hire.graduandDegreeModel'.
How can I slove it???
You didn't create an instance for graduandModel's graduandDegreeGroup property. So this line:
#Html.Partial("_DegreeDetailsByGraduand", Model.graduandDegreeGroup)
will throw an exception like you said. Simply because the second parameter is NULL.
You can try to modify graduandModel's constructor as below:
public graduandModel()
{
this.AvailableCeremony = new List<SelectListItem>();
this.graduandDegreeGroup = new graduandDegreeModel();
}
The exception should be gone.
You may also find this link helpful: ASP.NET MVC renderpartial, model item passed into the dictionary is of type
Another option for you may be to create a new view model which combines the two models above into one. That way it has properties for all of the data you require for this view. Then you don't need to specify a model in your call to the partial view, it will automatically use the parent's model. Alternatively, you may not need to separate the view into partials at all with the use of a combined model. It is not uncommon to have a unique view model for each different view. In some applications, it can be rare that two different views require the same data.
The combined view model:
public class CheckDataViewModel
{
public CheckDataViewModel ()
{
this.AvailableCeremony = new List<SelectListItem>();
this.AvailableDegree = new List<SelectListItem>();
}
public string first_name { get; set; }
public string middle_name { get; set; }
public string last_name { get; set; }
public int student_id { get; set; }
public int ceremony_id { get; set; }
public DateTime ceremony_date { get; set; }
public int graduand_id { get; set; }
public IList<SelectListItem> AvailableCeremony { get; set; }
public graduandDegreeModel graduandDegreeGroup { get; set; }
public string degree_id { get; set; }
public string degree_name { get; set; }
public IList<SelectListItem> AvailableDegree { get; set; }
}
The combined view:
#{
Layout = "~/Views/Shared/_ColumnsThree.cshtml";
}
#model CheckDataViewModel
#using Nop.Web.Models.Hire;
#using Nop.Web.Framework;
#using Telerik.Web.Mvc.UI;
#using System.Linq;
#using (Html.BeginForm())
{
<table >
<tr>
<td >
Ceremony :
</td>
<td>
Ceremony at #Model.ceremony_date
</td>
</tr>
<tr>
<td >
Name :
</td>
<td >
#Model.first_name #Model.middle_name #Model.last_name
</td>
</tr>
</table>
<div>
<table >
<tr>
<td >
AAAAAA
</td>
<td>
#Html.DropDownListFor(model => model.degree_id, Model.AvailableDegree)
#* #Html.ValidationMessageFor(model => model.ceremony_id)*#
</td>
</tr>
</table>
</div>
}

Categories

Resources