Error when trying to create PDF with Rotativa - c#

My goal is to allow users to print to pdf, a view. I found a Nuget called Rotativa and followed some very basic tutorials. In test, it worked perfectly and looked like a great answer to meet my needs.
However, I am finding that implementing it into the actual working project, is giving me errors that the simple test did not.
I have an index view that is a list. I want users to print this list to pdf. I have tried many different classes of Rotativa (ViewAsPDF, ActionAsPDF, GeneratePDF. . . ). I have researched and read numerous tutorials . .but I think the problem is more related to my Model. .
Here is what I have so far
Index View
#model IEnumerable<ICS20web.Models.IndexViewModel>
#{
ViewBag.Title = "Index";
}
<style>
#content {
}
.even {
background-color: #dcf1b8;
}
.odd {
background-color: #f4ffe1;
}
</style>
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<p>
<p>
#Html.ActionLink("Print", "PrintAllReport")
</p>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.ItemDescription)
</th>
<th>
#Html.DisplayNameFor(model => model.OriginalDate)
</th>
<th>
#Html.DisplayNameFor(model => model.TransType)
</th>
<th>
#Html.DisplayNameFor(model => model.LastUpdatedBy)
</th>
<th>
#Html.DisplayNameFor(model => model.ContactName)
</th>
<th>
#Html.DisplayNameFor(model => model.OpenClosed)
</th>
<th>
#Html.DisplayNameFor(model => model.CurrentStatus)
</th>
<th>
#Html.DisplayNameFor(model => model.CurrentStatusDate)
</th>
<th>
#Html.DisplayNameFor(model => model.RequsitionNumber)
</th>
<th>
#Html.DisplayNameFor(model => model.PONumber)
</th>
<th>
#Html.DisplayNameFor(model => model.DeliveryMonth)
</th>
<th>
#Html.DisplayNameFor(model => model.DeliveryYear)
</th>
<th>
#Html.DisplayNameFor(model => model.UnitsOrdered)
</th>
<th>
#Html.DisplayNameFor(model => model.Emergency)
</th>
<th>
#Html.DisplayNameFor(model => model.Comments)
</th>
<th>
#Html.DisplayNameFor(model => model.DeliveryUnit)
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.ItemDescription)
</td>
<td>
#Html.DisplayFor(modelItem => item.OriginalDate)
</td>
<td>
#Html.DisplayFor(modelItem => item.TransType)
</td>
<td>
#Html.DisplayFor(modelItem => item.LastUpdatedBy)
</td>
<td>
#Html.DisplayFor(modelItem => item.ContactName)
</td>
<td>
#Html.DisplayFor(modelItem => item.OpenClosed)
</td>
<td>
#Html.DisplayFor(modelItem => item.CurrentStatus)
</td>
<td>
#Html.DisplayFor(modelItem => item.CurrentStatusDate)
</td>
<td>
#Html.DisplayFor(modelItem => item.RequsitionNumber)
</td>
<td>
#Html.DisplayFor(modelItem => item.PONumber)
</td>
<td>
#Html.DisplayFor(modelItem => item.DeliveryMonth)
</td>
<td>
#Html.DisplayFor(modelItem => item.DeliveryYear)
</td>
<td>
#Html.DisplayFor(modelItem => item.UnitsOrdered)
</td>
<td>
#Html.DisplayFor(modelItem => item.Emergency)
</td>
<td>
#Html.DisplayFor(modelItem => item.Comments)
</td>
<td>
#Html.DisplayFor(modelItem => item.DeliveryUnit)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.TransID })
</td>
</tr>
}
</table>
The View loads in the browser, with correct data from the model, properly. But, when the user clicks the ActionLink PrintAllReport . . . I see the following error: System.NullReferenceException: Object reference not set to an instance of an object.
Referencing line #foreach (var item in Model)
I believe that is telling me that the Model is empty? But, how can that be, when it populates in the browser just fine.
Here is My Index Controller Action
public ActionResult Index()
{
var q = from tr in db.ICS_Transactions
join un in db.ICS_Units
on tr.DeliveryUnitID equals un.DeliveryUnitID
join kt in db.ICS_Contacts
on tr.Contact equals kt.LoginID
join sp in db.ICS_Supplies on tr.SuppliesID equals sp.Supplies_ID
orderby tr.Emergency descending, tr.TransID ascending
select new IndexViewModel
{
TransID = tr.TransID,
ItemDescription = sp.ItemDescription,
OriginalDate = tr.OriginalDate,
TransType = tr.TransType,
LastUpdatedBy = tr.LastUpdatedBy,
ContactName = kt.ContactName,
OpenClosed = tr.OpenClosed,
CurrentStatus = tr.CurrentStatus,
CurrentStatusDate = tr.CurrentStatusDate,
RequsitionNumber = tr.RequsitionNumber,
PONumber = tr.PONumber,
DeliveryMonth = tr.DeliveryMonth,
DeliveryYear = tr.DeliveryYear,
UnitsOrdered = tr.UnitsOrdered,
Emergency = tr.Emergency,
Comments = tr.Comments,
DeliveryUnit = un.DeliveryUnit,
PhoneNumber = un.PhoneNumber,
Street = un.Street,
City = un.City,
State = un.State,
ZipCode = un.ZipCode,
Building = un.Building,
Room = un.Room
}
;
return View(q.Where(d => d.OpenClosed == "Open").ToList());
}
And here is my PrintAllReport Action
public ActionResult PrintAllReport()
{
var model = new IndexViewModel();
//Code to get content
return new Rotativa.ViewAsPdf("Index") { FileName = "TestViewAsPdf.pdf" };
}
This generates the Object Reference Error. I am confused. Shouldn't this work exactly as the index loaded in the browser? What am I missing?
I have also tried it this way:
public ActionResult PrintAllReport()
{
var report = new ActionAsPdf("Index");
return report;
}
The latter gives me an authentication error: You are not authorized to view this page due to invalid authentication headers.
I am new to MVC5 and I am confused as to why the index page loads properly, but the action PrintAllReport is failing to open in pdf. And what I need to change to make it work properly.
Update:
After Stuard gave me some good information, I have made some changes, as follows
{
var viewModel = new IndexViewModel();
var report = new ViewAsPdf("Index", viewModel);
return report;
}
Now, I am getting a different error
The model item passed into the dictionary is of type 'ICS20web.Models.IndexViewModel', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable`1[ICS20web.Models.IndexViewModel]'
I feel like I am close . . . but no cigar.

Related

View in ASP.NET Core 5 MVC display as required

I am creating an ASP.NET Core 5 MVC web app and I have a problem.
View only display the same value.
I have debug and the controller seem to be ok.
But I don't have any idea why the view is only display 9 row and all rows are the same.
Here is the code in the controller:
public class MatchesController : Controller
{
private ISender _mediator;
public MatchesController(ISender mediator)
{
_mediator = mediator;
}
public IActionResult Index()
{
return View();
}
public async Task<IActionResult> ViewAllMatch()
{
var matchQuery = await _mediator.Send(new GetMatchesDetail());
// ReUse model from Apllication Layer
// Manual Mapping from matches to MatchViewModel
// GetMatchesDetail : IRequest<IEnumerable<MatchesDetail>>
// Manual Mapping IEnumerable<MatchesDetail> =>IEnumerable<MatchViewModel>
MatchViewModel matchesvm = new MatchViewModel();
List<MatchViewModel> retList = new List<MatchViewModel>();
// IEnumerable<MatchesDetail> retList;
foreach (var item in matchQuery)
{
matchesvm.MatchId = item.MatchId;
matchesvm.MatchNumber = item.MatchNumber;
matchesvm.DateMatch = item.DateMatch;
matchesvm.TimeMatch = item.TimeMatch;
matchesvm.MatchYear = item.MatchYear;
matchesvm.SeasonId = item.SeasonId;
matchesvm.SeasonName = item.SeasonName;
matchesvm.Round = item.Round;
matchesvm.Stage = item.Stage;
matchesvm.SubStage = item.SubStage;
matchesvm.HTeam = item.HTeam;
matchesvm.HGoal = item.HGoal;
matchesvm.HTeamCode = item.HTeamCode;
matchesvm.GGoal = item.GGoal;
matchesvm.GTeam = item.GTeam;
matchesvm.GTeamCode = item.GTeamCode;
matchesvm.WinNote = item.WinNote;
matchesvm.Stadium = item.Stadium;
matchesvm.Referee = item.Referee;
matchesvm.Visistors = item.Visistors;
retList.Add(matchesvm);
}
return View(retList);
}
}
And here is the view:
#model IEnumerable<MatchViewModel>
#{
ViewData["Title"] = "ViewAllMatch";
string flag1, flag2;
}
<h1>ViewAllMatch</h1>
<p>
<a asp-action="Create">Create New</a>
</p>
<table class="table">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.MatchId)
</th>
<th>
#Html.DisplayNameFor(model => model.MatchNumber)
</th>
<th>
#Html.DisplayNameFor(model => model.DateMatch)
</th>
<th>
#Html.DisplayNameFor(model => model.TimeMatch)
</th>
<th>
#Html.DisplayNameFor(model => model.MatchYear)
</th>
<th>
#Html.DisplayNameFor(model => model.SeasonId)
</th>
<th>
#Html.DisplayNameFor(model => model.SeasonName)
</th>
<th>
#Html.DisplayNameFor(model => model.Round)
</th>
<th>
#Html.DisplayNameFor(model => model.Stage)
</th>
<th>
#Html.DisplayNameFor(model => model.SubStage)
</th>
<th>
#Html.DisplayNameFor(model => model.HTeam)
</th>
<th>
#Html.DisplayNameFor(model => model.HTeamCode)
</th>
<th>
#Html.DisplayNameFor(model => model.HGoal)
</th>
<th>
#Html.DisplayNameFor(model => model.GGoal)
</th>
<th>
#Html.DisplayNameFor(model => model.GTeam)
</th>
<th>
#Html.DisplayNameFor(model => model.GTeamCode)
</th>
<th>
#Html.DisplayNameFor(model => model.WinNote)
</th>
<th>
#Html.DisplayNameFor(model => model.Stadium)
</th>
<th>
#Html.DisplayNameFor(model => model.Referee)
</th>
<th>
#Html.DisplayNameFor(model => model.Visistors)
</th>
<th>
#Html.DisplayNameFor(model => model.Status)
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.MatchId)
</td>
<td>
#Html.DisplayFor(modelItem => item.MatchNumber)
</td>
<td>
#Html.DisplayFor(modelItem => item.DateMatch)
</td>
<td>
#Html.DisplayFor(modelItem => item.TimeMatch)
</td>
<td>
#Html.DisplayFor(modelItem => item.MatchYear)
</td>
<td>
#Html.DisplayFor(modelItem => item.SeasonId)
</td>
<td>
#Html.DisplayFor(modelItem => item.SeasonName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Round)
</td>
<td>
#Html.DisplayFor(modelItem => item.Stage)
</td>
<td>
#Html.DisplayFor(modelItem => item.SubStage)
</td>
<td class="text-center">
#Html.DisplayFor(modelItem => item.HTeam)
</td>
<td>
#{
flag1 = "/img/Team/"+#item.HTeamCode+".png";
flag2= "/img/Team/" + #item.GTeamCode + ".png";
}
<img src="#flag1" />
#*#Html.DisplayFor(modelItem => item.HTeamCode)*#
</td>
<td>
#Html.DisplayFor(modelItem => item.HGoal)
</td>
<td>
#Html.DisplayFor(modelItem => item.GGoal)
</td>
<td>
#Html.DisplayFor(modelItem => item.GTeam)
</td>
<td>
#Html.DisplayFor(modelItem => item.GTeamCode)
</td>
<td>
#Html.DisplayFor(modelItem => item.WinNote)
</td>
<td>
#Html.DisplayFor(modelItem => item.Stadium)
</td>
<td>
#Html.DisplayFor(modelItem => item.Referee)
</td>
<td>
#Html.DisplayFor(modelItem => item.Visistors)
</td>
<td>
#Html.DisplayFor(modelItem => item.Status)
</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>
}
</tbody>
</table>
The reason why you always get the same value is your MatchViewModel is new outside the foreach method. This means you always added the same MatchViewModel and its value has been changed during each foreach. This will make the List view model always added the same viewmodel like your view shows always the same row.
I suggest you could try below codes:
public async Task<IActionResult> ViewAllMatch()
{
var matchQuery = await _mediator.Send(new GetMatchesDetail());
//ReUse model from Apllication Layer
//Manual Mapping from matches to MatchViewModel
//GetMatchesDetail : IRequest<IEnumerable<MatchesDetail>>
//Manual Mapping IEnumerable<MatchesDetail> =>IEnumerable<MatchViewModel>
List<MatchViewModel> retList = new List<MatchViewModel>();
//IEnumerable<MatchesDetail> retList;
foreach (var item in matchQuery)
{
MatchViewModel matchesvm = new MatchViewModel();
#region ManualMapping
matchesvm.MatchId = item.MatchId;
matchesvm.MatchNumber = item.MatchNumber;
matchesvm.DateMatch = item.DateMatch;
matchesvm.TimeMatch = item.TimeMatch;
matchesvm.MatchYear = item.MatchYear;
matchesvm.SeasonId = item.SeasonId;
matchesvm.SeasonName = item.SeasonName;
matchesvm.Round = item.Round;
matchesvm.Stage = item.Stage;
matchesvm.SubStage = item.SubStage;
matchesvm.HTeam = item.HTeam;
matchesvm.HGoal = item.HGoal;
matchesvm.HTeamCode = item.HTeamCode;
matchesvm.GGoal = item.GGoal;
matchesvm.GTeam = item.GTeam;
matchesvm.GTeamCode = item.GTeamCode;
matchesvm.WinNote = item.WinNote;
matchesvm.Stadium = item.Stadium;
matchesvm.Referee = item.Referee;
matchesvm.Visistors = item.Visistors;
#endregion
retList.Add(matchesvm);
}
return View(retList);
//return View(matches); //IEnumerable<MatchesDetail>
}
You have bug in your code, you should create a new MatchViewModel instance for each item inside of the loop
foreach (var item in matchQuery)
{
var matchesvm = new MatchViewModel();
matchesvm.MatchId = item.MatchId;
... and so on
}
but you can use Linq instead foreach loop
var retList= matchQuery.Select(item=> new MatchViewModel
{
MatchId = item.MatchId;
MatchNumber = item.MatchNumber;
DateMatch = item.DateMatch
.... and so on
}).ToList();
return View(retList);
IMHO no much sense to convert IEnumerable of MatchesDetail => IEnumerable of MatchViewModel since they have the same property names and you use them only to display data. You can use matchQuery directly
return View(matchQuery);
and view
#model IEnumerable<MatchesDetail>

ASP.NET MVC C# Web App - Filtering / Search from DB getting ERROR

I have a basic asp.net mvc web application. Its connected with my DB which has many records. I need for it to have a Filter option on the top of the page and a search text box whcih searches for Name. The filter box should be a drop down with all the column names and which ever option is selected, all records pertaining to that option display on the main index page. I have tried to do it but its giving me errors. I hvae attached the following: DataFormsController (index method), the index html page, and the .models page AS WELL as the error i get when I run the application.
If anyone can help me out I'd really appreciate it.
Thanks!!!
RiskApplication.models code:
using System.Collections.Generic;
//using Microsoft.AspNetCore.Mvc.Rendering;
using System.Web.Mvc;
namespace RiskApplication.Models
{
public class RiskApplicationModel
{
public List<DataForm> dataForms;
public SelectList owners;
public string department { get; set; }
}
}
index.cshtml:
#model IEnumerable<RiskApplication.Models.DataForm>
#{
ViewBag.Title = "Index";
}
<h2>RiskPrescreen Application 2018</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<form asp-controller="DataForms" asp-action="Index" method="get">
<p>
<select asp-for="department" asp-items="Model.owners">
<option value="">All</option>
</select>
Application Name: <input type="text" name="SearchString">
<input type="submit" value="Search" />
</p>
</form>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.Name)
</th>
#*<th>
#Html.DisplayNameFor(model => model.Application_Exec)
</th>
<th>
#Html.DisplayNameFor(model => model.SME)
</th>
<th>
#Html.DisplayNameFor(model => model.Project_Directory_Location)
</th>
<th>
#Html.DisplayNameFor(model => model.IRDR_name)
</th>
<th>
#Html.DisplayNameFor(model => model.Description)
</th>
<th>
#Html.DisplayNameFor(model => model.Risk_Statement)
</th>*#
<th>
#Html.DisplayNameFor(model => model.InherentRisk)
</th>
#*<th>
#Html.DisplayNameFor(model => model.AppOwner_DD.AppOwnerDes)
</th>
<th>*#
#* #Html.DisplayNameFor(model => model.C1_DD.C1)
</th>
<th>
#Html.DisplayNameFor(model => model.C2_DD.C2)
</th>
<th>
#Html.DisplayNameFor(model => model.C3_DD.C3)
</th>
<th>
#Html.DisplayNameFor(model => model.C4_DD.C4_des)
</th>
<th>
#Html.DisplayNameFor(model => model.C5_DD.C5)
</th>
<th>
#Html.DisplayNameFor(model => model.C6_DD.C6)
</th>
<th>
#Html.DisplayNameFor(model => model.SDLC_Stage_DD.SDLC_Stage)
</th>*#
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
#*<td>
#Html.DisplayFor(modelItem => item.Application_Exec)
</td>
<td>
#Html.DisplayFor(modelItem => item.SME)
</td>
<td>
#Html.DisplayFor(modelItem => item.Project_Directory_Location)
</td>
<td>
#Html.DisplayFor(modelItem => item.IRDR_name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Description)
</td>
<td>
#Html.DisplayFor(modelItem => item.Risk_Statement)
</td>*#
<td>
#Html.DisplayFor(modelItem => item.InherentRisk)
</td>
#*<td>
#Html.DisplayFor(modelItem => item.AppOwner_DD.AppOwnerDes)
</td>
DataFormsController.cs:
public async Task<ActionResult> Index(string department, string searchString)
{
// Use LINQ to get list of genres.
IQueryable<string> genreQuery = from m in db.AppOwner_DD
orderby m.AppOwnerDes
select m.AppOwnerDes;
var dataForms = from m in db.DataForms
select m;
if (!String.IsNullOrEmpty(searchString))
{
dataForms = dataForms.Where(s => s.Name.Contains(searchString));
}
if (!String.IsNullOrEmpty(department))
{
dataForms = dataForms.Where(x => x.AppOwner_DD.AppOwnerDes == department);
}
var movieGenreVM = new RiskApplicationModel();
movieGenreVM.owners = new SelectList(await genreQuery.Distinct().ToListAsync());
movieGenreVM.dataForms = await dataForms.ToListAsync();
return View(movieGenreVM);
}
enter image description here
Aadil,
You are passing a type RiskApplicationModel to the Index view from the Index controller
However the Index view expects a model of type IEnumerable based on the first line in the cshtml #model IEnumerable
So there is the mismatch between what's sent to the view compared to what the view expects
This needs to be fixed either in the controller or in the view.
The controller needs to send a type that the view expects or the view should bind itself to a type that the controller is sending.
Or alternatively, the controller could populate a viewmodel and view could be bound to a viewmodel like in the MVVM design pattern (Model-View-ViewModel)
Hope this helps

Multiple partial views in a strongly typed view (ASP.NET MVC5) ? Unable to get relative Path In View

I am having an issue that after saving relative path I cannot get picture in a list, and having error:
CS1061
'IEnumerable<tbl_Advertisement>' does not contain a definition for 'Imagepath' and no extension method 'Imagepath' accepting a first argument of type 'IEnumerable<tbl_Advertisement>' could be found (are you missing a using directive or an assembly reference?) GawadarHubUI C:\Users\Omer FarooQ\Desktop\GawadarHubistan\GawadarHubUI\GawadarHubUI\Areas\Common\Views\SampleViewAD\Index.cshtml
73
Active
This rrror in just view line: #Html.DisplayNameFor(model => Model.ImagePath) that after type Model. I cannot get the the property Name ImagePath, rather it's showing me Extension methods and methods
Controller CODE
using BLL;
using BOL;
using DAL;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace GawadarHubUI.Areas.Common.Controllers
{
[AllowAnonymous]
public class SampleViewADController : Controller
{
GawadarHubDbEntities db = new GawadarHubDbEntities();
private AdBl objbl;
public SampleViewADController()
{
objbl = new AdBl();
}
// GET: Common/SampleViewAD
[HttpGet]
public ActionResult Index()
{
try
{
var urls = objbl.GetAll().Where(x => x.isapproved == "A").ToList();
return View(urls);
}
catch (Exception e1)
{
TempData["Msg"] = "Approve Failed : " + e1.Message;
return RedirectToAction("Index");
}
}
}
}
View code:
#model IEnumerable<BOL.tbl_Advertisement>
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Index</h2>
#if (TempData["Msg"] != null)
{
<div class="alert alert-dismissable alert-info">
<button type="button" class="close" data-dismiss="alert">×</button>
#TempData["Msg"].ToString()
</div>}
<p>
#Html.ActionLink("SampleViewADController", "urls")
</p>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.adtitle)
</th>
<th>
#Html.DisplayNameFor(model => model.adsociety)
</th>
<th>
#Html.DisplayNameFor(model => model.addesc)
</th>
<th>
#Html.DisplayNameFor(model => model.isapproved)
</th>
<th>
#Html.DisplayNameFor(model => model.contactNumber)
</th>
<th>
#Html.DisplayNameFor(model => model.ImagePath)
</th>
<th>
#Html.DisplayNameFor(model => model.price)
</th>
<th>
#Html.DisplayNameFor(model => model.Size)
</th>
<th>
#Html.DisplayNameFor(model => model.tbl_Category.cname)
</th>
<th>
#Html.DisplayNameFor(model => model.tbl_User.useremail)
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.adtitle)
</td>
<td>
#Html.DisplayFor(modelItem => item.adsociety)
</td>
<td>
#Html.DisplayFor(modelItem => item.addesc)
</td>
<td>
#Html.DisplayFor(modelItem => item.isapproved)
</td>
<td>
#Html.DisplayFor(modelItem => item.contactNumber)
</td>
<td>
#Html.DisplayFor(model => Model.ImagePath)
</td>
<td>
#Html.DisplayFor(modelItem => item.price)
</td>
<td>
#Html.DisplayFor(modelItem => item.Size)
</td>
<td>
#Html.DisplayFor(modelItem => item.tbl_Category.cname)
</td>
<td>
#Html.DisplayFor(modelItem => item.tbl_User.useremail)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.adid }) |
#Html.ActionLink("Details", "Details", new { id = item.adid }) |
#Html.ActionLink("Delete", "Delete", new { id = item.adid })
</td>
</tr>
}
</table>
Try to replace
#Html.DisplayFor(model => Model.ImagePath)
with
<img src= "#Url.Content(item.ImagePath)" alt="Image" />
Should work.
Your define that your model is a collection:
#model IEnumerable<BOL.tbl_Advertisement>
So every time you write Model., you are referencing this collection.
The collection (IEnumerable<BOL.tbl_Advertisement>) has no property for Imagepath, as the error message tells you.
IEnumerable<tbl_Advertisement> does not contain a definition for Imagepath
Rather, the elements (tbl_Advertisement) of the collection have this property.
This is what Stephen and Igor meant when they wrote that you need to access the Imagepath through the elements of the collection.
Either by looping over the collection:
#foreach (var item in Model) {
<img src= "#Url.Content(item.ImagePath)" alt="Image" />
}
Or for the first element only:
var imagePath = Model.ElementAt(0).ImagePath;

How can I compare the session value to current user id [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
How can I compare the session value with the current user id.
To display only the record of that user who is login.
Here I join three tables to make this view.
if (Session["UserId"] == Model.userAccount.UserId) Here is the code where I got error.
code:
#model IEnumerable<OnlineTaxiReservationSystem.Models.BookingViewModel>
#{
ViewBag.Title = "Index";
}
<h2 id="h1">Bookings Detail</h2>
<p>
#Html.ActionLink("Add New Booking", "Create")
</p>
#if (Session["User"] == null)
{
Response.Redirect(Url.Action("Login", "Account"));
}
else if (Session["LoginRole"].ToString() == "Admin")
{
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.taxi.TaxiName)
</th>
<th>
#Html.DisplayNameFor(model => model.userAccount.FirstName)
</th>
<th>
#Html.DisplayNameFor(model => model.booking.BookingStartDateandTime)
</th>
<th>
#Html.DisplayNameFor(model => model.booking.BookingEndDateandTime)
</th>
<th>
#Html.DisplayNameFor(model => model.booking.UserContactNo)
</th>
<th>
#Html.DisplayNameFor(model => model.booking.UserStartingLoaction)
</th>
<th>
#Html.DisplayNameFor(model => model.booking.UserDistination)
</th>
<th>
#Html.DisplayNameFor(model => model.bookingStatus.Status)
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.taxi.TaxiName)
</td>
<td>
#Html.DisplayFor(modelItem => item.userAccount.FirstName)
</td>
<td>
#Html.DisplayFor(modelItem => item.booking.BookingStartDateandTime)
</td>
<td>
#Html.DisplayFor(modelItem => item.booking.BookingEndDateandTime)
</td>
<td>
#Html.DisplayFor(modelItem => item.booking.UserContactNo)
</td>
<td>
#Html.DisplayFor(modelItem => item.booking.UserStartingLoaction)
</td>
<td>
#Html.DisplayFor(modelItem => item.booking.UserDistination)
</td>
<td>
#Html.DisplayFor(modelItem => item.bookingStatus.Status)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.booking.BookingId }) |
#Html.ActionLink("Details", "Details", new { id = item.booking.BookingId }) |
#Html.ActionLink("Delete", "Delete", new { id = item.booking.BookingId })
</td>
</tr>
}
</table>
}
else if (Session["UserId"] == Model.userAccount.UserId)
{
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.taxi.TaxiName)
</th>
<th>
#Html.DisplayNameFor(model => model.userAccount.FirstName)
</th>
<th>
#Html.DisplayNameFor(model => model.booking.BookingStartDateandTime)
</th>
<th>
#Html.DisplayNameFor(model => model.booking.BookingEndDateandTime)
</th>
<th>
#Html.DisplayNameFor(model => model.booking.UserContactNo)
</th>
<th>
#Html.DisplayNameFor(model => model.booking.UserStartingLoaction)
</th>
<th>
#Html.DisplayNameFor(model => model.booking.UserDistination)
</th>
<th>
#Html.DisplayNameFor(model => model.bookingStatus.Status)
</th>
<th></th>
</tr>
#foreach (var item in #Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.taxi.TaxiName)
</td>
<td>
#Html.DisplayFor(modelItem => item.userAccount.FirstName)
</td>
<td>
#Html.DisplayFor(modelItem => item.booking.BookingStartDateandTime)
</td>
<td>
#Html.DisplayFor(modelItem => item.booking.BookingEndDateandTime)
</td>
<td>
#Html.DisplayFor(modelItem => item.booking.UserContactNo)
</td>
<td>
#Html.DisplayFor(modelItem => item.booking.UserStartingLoaction)
</td>
<td>
#Html.DisplayFor(modelItem => item.booking.UserDistination)
</td>
<td>
#Html.DisplayFor(modelItem => item.bookingStatus.Status)
</td>
</tr>
}
</table>
}
Model is an enumeration of BookingViewModel, so this statement will fail:
else if (Session["UserId"] == Model.userAccount.UserId)
Because Model is a group of items, not just one item.
What you need to do instead is look for the user account and display it:
//This is the else statement that was giving you trouble. Change it to:
else
{
string sessionId = Session["UserId"] as string;
var account = Model.FirstOrDefault(a => a.userAccount.UserId == sessionId);
if(account != null)
{
//Use your display code here
}
else
{
//Figure out what to do if for some odd reason, you can't find it.
}
}
The quick code sample assumes userId is a string. Use casting as needed.
I would suggest creating a partial view to display the fields as opposed to code repetition.
You can do it through the User property of your ViewPage. Do not save user ID in session
Suppose you have authenticated user and he has role & identity.
public class MyPrincipal: IPrincipal
{
private MyIdentity _identity;
private string[] _roles;
public MyPrincipal(MyIdentity identity, string[] roles)
{
_identity = identity;
_roles = roles;
}
public bool IsInRole(string role)
{
return _roles?.Length > 0 && _roles.Contains(role);
}
IIdentity IPrincipal.Identity
{
get
{
return _identity;
}
}
public MyIdentity Identity
{
get { return _identity;}
}
// User ID you need
public int UserId
{
get
{
return Identity.UserId;
}
}
}
somewhere in your code
#{
int currentUserId = (User as MyPrincipal).UserId;
}
#if (currentUserId == Model.userId)
{
// this will be executed personally per executing user
}

C# Table add new rows with textbox

I got a question.
I'm making a table but I need a add page where the user can fill in a textbox, (or something else) Then press add. If this happens the table needs to be updated with the information the user added.
Could some one help me? Because I do not know how to start.
The code from the table page:
#model IEnumerable<DNDB.Models.Domeinnaam>
#Styles.Render("~/Content/StyleSheet.css")
#{
ViewBag.Title = "Index";
}
<h2>Domeinnaam Overzicht</h2>
#Html.ActionLink("add", "CreateDomeinnaam.cshtml")
<table id="tabledomeinnamen">
<tr>
<th>
#Html.DisplayNameFor(model => model.IsActief)
</th>
<th>
#Html.DisplayNameFor(model => model.Naam)
</th>
<th>
#Html.DisplayNameFor(model => model.TLD)
</th>
<th>
#Html.DisplayNameFor(model => model.DatumRegistratie)
</th>
<th>
#Html.DisplayNameFor(model => model.Omschrijving)
</th>
<th>
#Html.DisplayNameFor(model => model.DatumOpzeg)
</th>
<th>
#Html.DisplayNameFor(model => model.EigenaarID)
</th>
<th>
#Html.DisplayNameFor(model => model.Opmerking)
</th>
<th>
#Html.DisplayNameFor(model => model.BeheerAccountID)
</th>
<th>
#Html.DisplayNameFor(model => model.KlantID)
</th>
<th>
#Html.DisplayNameFor(model => model.RegistrarID)
</th>
<th>
#Html.DisplayNameFor(model => model.BetaaldVan)
</th>
<th>
#Html.DisplayNameFor(model => model.BetaaldTot)
</th>
<th>
#Html.DisplayNameFor(model => model.AfspraakPrijs)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.IsActief)
</td>
<td>
#Html.DisplayFor(modelItem => item.Naam)
</td>
<td>
#Html.DisplayFor(modelItem => item.TLD)
</td>
<td>
#Html.DisplayFor(modelItem => item.DatumRegistratie)
</td>
<td>
#Html.DisplayFor(modelItem => item.Omschrijving)
</td>
<td>
#Html.DisplayFor(modelItem => item.DatumOpzeg)
</td>
<td>
#Html.DisplayFor(modelItem => item.EigenaarID)
</td>
<td>
#Html.DisplayFor(modelItem => item.Opmerking)
</td>
<td>
#Html.DisplayFor(modelItem => item.BeheerAccountID)
</td>
<td>
#Html.DisplayFor(modelItem => item.KlantID)
</td>
<td>
#Html.DisplayFor(modelItem => item.RegistrarID)
</td>
<td>
#Html.DisplayFor(modelItem => item.BetaaldVan)
</td>
<td>
#Html.DisplayFor(modelItem => item.BetaaldTot)
</td>
<td>
#Html.DisplayFor(modelItem => item.AfspraakPrijs)
</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>
The code from the table page:
#Html.ActionLink("add", "CreateDomainName", "Domain") //Second parameter is the action name, Third parameter is the controller name. If your 'list'(table) page action and 'add' action are in the same controller then this field is optional.
CreateDomainName action in your controller.
public ActionResult CreateDomainName()
{
return View();
}
[HttpPost]
public ActionResult CreateDomainName(Domeinnaam model)
{
if(ModelState.IsValid)
{
//Your code to save
}
return RedirectToAction("Index");
}
To generate the view of CreateDomainName action, right click on action and click on 'add view'.
View of CreateDomainName action.
#using(Html.BeginForm())
{
<!-- Your html code -->
<input type="submit">Add</input>
}
You can perform this task in two ways:
Using Ajax
By submitting form to server and refreshing the page
Here's how you can do it via ajax.
Add form at top or bottom of table with required fields
On submit of form event process form and submit via ajax
In success callback append tr to table with required cells.
$( document ).ready(function() {
$("#newForm").submit(function(){
//TODO: Perform ajax call to add reccord in database
// Append row to table
return false;
});
Here's a code demo you can follow to do it with Ajax. Add new row to table on form submit

Categories

Resources