Passing an ID from Razor view to Controller - razor

In a view of type List I'm trying to pass the id (which is an eMail in this case) of the item from the view to an actionResult in the controller: I used the following code():
#Html.ActionLink("Contact", "CreateMessage", "Member", new { id = item.eMail })
I get a null reference because the id passed is null.
Here's the view which works just fine and the id in it isn't null:
#model IEnumerable<Mutuelle.Domain.Entities.Adherent>
#{
ViewBag.Title = "lister";
}
<h2>Liste des adhérents</h2>
<table class="table">
<tr>
<body style="overflow:scroll;">
<th>
#Html.DisplayNameFor(model => model.dateOfBirth)
</th>
<th>
#Html.DisplayNameFor(model => model.address)
</th>
<th>
#Html.DisplayNameFor(model => model.phoneNumber)
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.dateOfBirth)
</td>
<td>
#Html.DisplayFor(modelItem => item.address)
</td>
<td>
#Html.DisplayFor(modelItem => item.phoneNumber)
</td>
<td>
#Html.ActionLink("Contacter", "CreateMessage", "MembreComite", new { id = item.eMail })
</td>
</tr>
}
</table>
Here's the controller:
public ActionResult CreateMessage(string id)
{
Message message = new Message();
return View(message);
}
[HttpPost]
public ActionResult CreateMessage(Message message, string id)
{
if (ModelState.IsValid)
{
AMDMService service = new AMDMService();
Member member = service.GetMemberByeMail(id);
message.member = member;
message.adherentId = id;
member.listMessages.Add(message);
return RedirectToAction("listeMessages");
}
return View(message);
}

When you use routeValues like new { id = item.eMail } in your ActionLink, then you always should provide value for html attributes, which mostly used for styling your link, so if you don't want to style your link then you pass null otherwise you pass something like that new { #class = "btn btn-rounded btn-blue" }). So your code for ActionLink should look like this if you don't want to style your link:
#Html.ActionLink("Contact", "CreateMessage", "Member", new { id = item.eMail }, null);
Also you can replace #Html.ActionLink helper with #Url.Action helper like below:
Contact

Related

ASP.NET Core MVC returning checked items from a form in a razor view to controller

I am working with a view that shows a list of delisted books (with isActive = false). In this view I have added a column of checkbox against each book . When the form is submitted I want to set all the checked books to become active (isActive = true).
This is the view I am working with :
#model IEnumerable<MvcBooksList.Models.Book>
#{
ViewData["Title"] = "Delisted Books";
}
#if (Model != null)
{
#using (Html.BeginForm("DelistedForm", "Book", FormMethod.Post))
{
<table class="table">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.BookName)
</th>
<th>
#Html.DisplayNameFor(model => model.Author)
</th>
<th>
#Html.DisplayNameFor(model => model.Publisher)
</th>
<th>
Enlist
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.BookName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Author)
</td>
<td>
#Html.DisplayFor(modelItem => item.Publisher)
</td>
<td>
#Html.CheckBoxFor(modelItem => item.IsActive)
</td>
</tr>
}
</tbody>
</table>
<input type="submit" value="Save" /> <input type = "button" value = "Cancel" onclick = "location.href='#Url.Action("Index","Home")'" />
}
}
else
{
<h3>No Books currently delisted</h3>
}
So my question is: how do I process this data in my controller action. As in when I click submit, will the form return IEnumerable of Books with IsActive set to true to the action??
I am trying something like this:
[HttpPost]
public ActionResult DelistedForm(IEnumerable<Book> fromDelist)
{
foreach (var item in fromDelist)
{
if (item.IsActive == true) ;
// enlist code here
}
return View("~/Views/Home/Index.cshtml");
}
If you only want to pass a list of books which IsActive is true.YOu can add hidden inputs to bind the data of BookName,Author,Publisher.And then change the name attribute of the inputs to correct format when checkbox is checked before form submitting.Here is a demo:
Action:
[HttpGet]
public IActionResult DelistedForm()
{
return View(new List<Book> { new Book { Author="a1", BookName="b1", IsActive=false, Publisher="p1"},
new Book { Author = "a2", BookName = "b2", IsActive = false, Publisher = "p2" },
new Book { Author = "a3", BookName = "b3", IsActive = false, Publisher = "p3" } });
}
[HttpPost]
[Route("/Book/DelistedForm")]
public ActionResult DelistedForm(IEnumerable<Book> fromDelist)
{
foreach (var item in fromDelist)
{
if (item.IsActive == true) ;
// enlist code here
}
return View("~/Views/Home/Index.cshtml");
}
View:
#if (Model != null)
{
#using (Html.BeginForm("DelistedForm", "Book", FormMethod.Post,new { #id="myForm"}))
{
<table class="table">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.BookName)
</th>
<th>
#Html.DisplayNameFor(model => model.Author)
</th>
<th>
#Html.DisplayNameFor(model => model.Publisher)
</th>
<th>
Enlist
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.BookName)
#Html.HiddenFor(modelItem => item.BookName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Author)
#Html.HiddenFor(modelItem => item.Author)
</td>
<td>
#Html.DisplayFor(modelItem => item.Publisher)
#Html.HiddenFor(modelItem => item.Publisher)
</td>
<td>
#Html.CheckBoxFor(modelItem => item.IsActive)
</td>
</tr>
}
</tbody>
</table>
<input type="submit" value="Save" />
<input type="button" value="Cancel" onclick="location.href='#Url.Action("Index","Home")'" />
}
}
else
{
<h3>No Books currently delisted</h3>
}
js:
<script>
$("#myForm").submit(function () {
var count = 0;
$("tbody tr").each(function () {
if ($(this).find("#item_IsActive").prop("checked")) {
$(this).find("#item_BookName").attr("name", "fromDelist[" + count + "].BookName");
$(this).find("#item_Author").attr("name", "fromDelist[" + count + "].Author");
$(this).find("#item_Publisher").attr("name", "fromDelist[" + count + "].Publisher");
$(this).find("#item_IsActive").attr("name", "fromDelist[" + count + "].IsActive");
count++;
}
})
})
</script>
result:

data is not deleted after click on Delete Button in ASP.NET MVC

I created view where i listed my all records and i wanted to delete particular record after click on delete Button . But my record is deleted.
Following is the code-
Controller code-
public ActionResult Faqdelete()
{
var res = dbobj.tbl_FAQ.ToList();
return View(res);
}
[HttpPost]
public ActionResult Faqdelete(int id)
{
var res = dbobj.tbl_FAQ.Where(x => x.FAQ_ID == id).FirstOrDefault();
dbobj.tbl_FAQ.Remove(res);
dbobj.SaveChanges();
var Faqdata = dbobj.tbl_FAQ.ToList();
return View("Faqdelete",Faqdata);
}
- View page Code-
#model IEnumerable<ClassOne_SampleProject.Models.tbl_FAQ>
#{
ViewBag.Title = "Faqdelete";
}
<h2>Faqdelete</h2>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.FAQ_Question_Answer)
</th>
<th>Action</th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.Raw(item.FAQ_Question_Answer)
</td>
<td>
Delete
</td>
</tr>
}
</table>
Please tell me where exactly the problem.
Modify your anchor tag as
<td>
<a href="Url.Action("Faqdelete", "somecontroller", new { id = item.FAQ_ID })"
class="btn btn-danger">Delete</a>
</td>

Displaying values of a view to another view (MVC)

I have a table in a View with some Car details on it. After I click 'Rent' button, to redirect me to another View and display the data of the selected row there. Using the button that I already have on the code, I am only able to display details of that row in the URL but they are not being displayed on the page.
Here is my ListOfCars View:
#model IEnumerable<CarDataAccess.Car>
#{
ViewBag.Title = "List";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>ListCars</title>
<script src="~/Scripts/OnClick.js">
</script>
</head>
<body>
#*<p>
#Html.ActionLink("Create New", "Post")
</p>*#
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.model)
</th>
<th>
#Html.DisplayNameFor(model => model.make)
</th>
<th>
#Html.DisplayNameFor(model => model.location)
</th>
<th>
#Html.DisplayNameFor(model => model.avaStart)
</th>
<th>
#Html.DisplayNameFor(model => model.avaEnd)
</th>
<th>
#Html.DisplayNameFor(model => model.price)
</th>
<th>
</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.model)
</td>
<td>
#Html.DisplayFor(modelItem => item.make)
</td>
<td>
#Html.DisplayFor(modelItem => item.location)
</td>
<td>
#Html.DisplayFor(modelItem => item.avaStart)
</td>
<td>
#Html.DisplayFor(modelItem => item.avaEnd)
</td>
<td>
#Html.DisplayFor(modelItem => item.price)
</td>
<td>
<td>#Html.ActionLink("Rent", "Payment", new { id = item.Id })</td>
</td>
</tr>
}
</table>
<div>
Login
</div>
And here is the other View where I want the row to be displayed:
#model IEnumerable<CarDataAccess.Car>
#{
/**/
ViewBag.Title = "Payment";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Payment</title>
</head>
<body>
<table class="paymenttable">
</table>
</body>
</html>
Controller's code:
namespace RentCarApplication.Controllers
{
public class HomeController : Controller
{
BookCarDBEntities db = new BookCarDBEntities();
public ActionResult Index(int? id)
{
ViewBag.Title = "Home Page";
return View();
}
public ActionResult ListCars()
{
string username = User.Identity.Name;
var cars = db.Cars.ToList();
return View(cars);
}
public ActionResult Payment(int id)
{
using (BookCarDBEntities entities = new BookCarDBEntities())
{
var entity = entities.Cars.FirstOrDefault(c => c.Id == id);
if (entities != null)
{
return View(entity);
}
else
{
return View("Not Found");
}
}
}
}
}
In the controller action Payment(int id) you are passing a single entity of type CarDataAccess.Car to the view (the line in your code entities.Cars.FirstOrDefault(c => c.Id == id) gets a single entity from the database).
The Payment view expects a collection of type IEnumerable<CarDataAccess.Car>. You can see this on the first line of the view #model IEnumerable<CarDataAccess.Car>. Change this to just #model CarDataAccess.Car and see if that solves the problem.
Update the view to this:
#model CarDataAccess.Car
#{
/**/
ViewBag.Title = "Payment";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Payment</title>
</head>
<body>
#* access model properties here *#
<span>#Model.Id</span>
</body>
</html>
There is an error in your controller too. Check that the Car entity is not null, not the database context (entities):
public ActionResult Payment(int id)
{
using (BookCarDBEntities entities = new BookCarDBEntities())
{
var entity = entities.Cars.FirstOrDefault(c => c.Id == id);
if (entity != null) // check if entity is null, not entities
{
return View(entity);
}
else
{
return View("Not Found");
}
}
}
There is another issue in your controller too - you have declared multiple instances of your database context (BookCarDBEntities). It is best to wrap your database context in using statements like you did in the Payment method. Do the same for the ListCars method and remove BookCarDBEntities db = new BookCarDBEntities(); from the top of the controller. If you wrap the context in using statements then that ensures the context is properly disposed of and cleaned up by the garbage collector.
The ListCars method should look like:
public ActionResult ListCars()
{
string username = User.Identity.Name;
var cars = new List<CarDataAccess.Car>();
using (var db = new BookCarDBEntities())
{
cars = db.Cars.ToList();
}
return View(cars);
}

How can I use #Html.DisplayFor without using foreach loop

I am trying to make a project where I want to display the details of user and then in a table I want to show the courses done by that user. When I try to display user details, the details of that user is shown as many number of courses they are taking since I am using a foreach loop. How can I do it without using foreach? I can do it if all the data is stored and retrieved from a single table but in this project I am using three tables- User, Course and UserCourse. UserCourse has foreign key reference to both UserId and CourseId. Now I want to retrieve details from user table.
HomeController:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Login(User u)
{
if (ModelState.IsValid)
{
using (DetailsEntities dc = new DetailsEntities())
{
var v = dc.Users.Where(a => a.UserName.Equals(u.UserName) && a.Password.Equals(u.Password)).FirstOrDefault();
if (v != null)
{
Session["User"] = v;
return RedirectToAction("Index", "Course");
}
}
}
return View(u);
}
CourseController:
public class CourseController : Controller
{
private DetailsEntities db = new DetailsEntities();
//
// GET: /Course/
public ActionResult Index()
{
User user = (User)Session["User"];
//var usr = db.Users.Find(user.UserId);
//int userId = (int)Session["UserId"];
var user1 = db.Users.FirstOrDefault(u => u.UserId==user.UserId);
if (Session["User"] != null)
{
var course = db.UserCourses.Where(u => u.UserId == user1.UserId);
if (user1 != null)
return View(course);
}
return View(user1);
}
}
Index:
<table border="1" align="center" height ="200px" width ="100%" #*style ="background-color: darkgray"*#>
<tr>
<th>
#Html.DisplayNameFor(model => model.User.FirstName)
</th>
<th>
#Html.DisplayNameFor(model => model.User.LastName)
</th>
<th>
#Html.DisplayNameFor(model => model.User.Address)
</th>
<th>
#Html.DisplayNameFor(model => model.User.City)
</th>
<th>
#Html.DisplayNameFor(model => model.User.Email)
</th>
<th>
#Html.DisplayNameFor(model => model.User.PhoneNo)
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.User.FirstName)
</td>
<td>
#Html.DisplayFor(modelItem => item.User.LastName)
</td>
<td>
#Html.DisplayFor(modelItem => item.User.Address)
</td>
<td>
#Html.DisplayFor(modelItem => item.User.City)
</td>
<td>
#Html.DisplayFor(modelItem => item.User.Email)
</td>
<td>
#Html.DisplayFor(modelItem => item.User.PhoneNo)
</td>
</tr>
}
</table>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table border="1" align="left" height ="200px" width ="300px" #*style ="background-color: darkgray"*#>
<tr>
<th>
#Html.DisplayNameFor(model => model.Course.CourseName)
</th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Course.CourseName)
</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>
I know the question is silly but I am new at this so please help me.

use a model as IEnumerable and static in same view

Am trying to put together a view where it will generate a detail list from a table through code first and a strongly typed view but also allow the user to input data into through the model into the table.
So the first part is:
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.Gender)
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Gender)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.GenderID }) |
#Html.ActionLink("Details", "Details", new { id = item.GenderID }) |
#Html.ActionLink("Delete", "Delete", new { id = item.GenderID })
</td>
</tr>
}
</table>
The next part to enter a new gender would be:
<div>#Html.LabelFor(model => model.Gender)</div>
<div>#Html.EditorFor(model => model.Gender, new { htmlAttributes = new { #class = "div-form-control", id = "LkUpGender" } })</div>
<div>#Html.ValidationMessageFor(model => model.Gender, "", new { #class = "text-danger" })</div>
The problem is the first part requires:
IEnumerable<OrwellFrontEnd.LkUpModels.vwLkUpGender>
But the second part seems to not work with that and require:
OrwellFrontEnd.LkUpModels.vwLkUpGender
How can I make this work?