How to pass data between controller and view in .Net MVC? - c#

What I want is that when the schedule form is loaded for the first time (or without data passing), it shows a list of MovieName. When I click on one MovieName, its ID is sent back to controller as an input of a SQL query, then the result is passed back to the view.
Here are what I've done. But I think when I click on the ActionLink, the controller doesnt handle the data passed back as it is not HttpPost. Also, I dont know how to show the new data back in view. Please help!
ScheduleController.cs
[HttpGet]
public ActionResult Index()
{
var schedules = db.Schedules.Include(s => s.Movie)
.OrderByDescending(s => s.Movie.MovieName)
.ToList();
return View(schedules);
}
[HttpPost]
public ActionResult Index(int MovieID)
{
//return ("Clicked");
var schedules = (from s in db.Schedules
orderby s.ShowDate
select s).ToList();
return View(schedules);
}
Schedule/Index
#using Booking_Ticket_Management_System.Models;
#model IEnumerable<Schedule>
#{
ViewBag.Title = "Schedule";
}
<h2>Choose movies</h2>
#using (Html.BeginForm())
{
<div>
#foreach (Schedule schedule in #Model)
{
#Html.ActionLink(schedule.Movie.MovieName, "Index", "Schedule", new { MovieID = schedule.MovieID},null)
<br />
}
<br />
</div>
}

Ideally listing and detail view are always separate. i suggest you to make both the view separate.
[HttpGet]
public ActionResult Index()
{
var schedules = db.Schedules.Include(s => s.Movie)
.OrderByDescending(s => s.Movie.MovieName)
.ToList();
return View(schedules);
}
[HttpGet]
public ActionResult Movie(int id)
{
//return ("Clicked");
var schedules = (from s in db.Schedules
Where s.MovieId == id
orderby s.ShowDate
select s).ToList();
return View(schedules);
}

As you do not pass the movieId in your query
Try this :
[HttpPost]
public ActionResult Index(int MovieID)
{
//return ("Clicked");
var schedules = (from s in db.Schedules
where s.MovieId==MovieId
orderby s.ShowDate
select s).ToList();
return View(schedules);
}
But what I will suggest to you is to create another Action and another view to display only the movie clicked.
And as you just want to Get not to modify the value inside the Database. You have to use the [HttpGet]
[HttpGet]
public ActionResult Detail(int MovieID)
{
//return ("Clicked");
var schedule = (from s in db.Schedules
where s.MovieId==MovieId
orderby s.ShowDate
select s).FirstOrDefault();
return View(schedule);
}
And in your Detail view created
#using Booking_Ticket_Management_System.Models;
#model Schedule
In your Index view you must change the ActionLink to:
#Html.ActionLink(schedule.Movie.MovieName, "Detail", "Schedule", new { MovieID = schedule.MovieID},null

Related

Routing issue in Asp.net MVC (404 Error)

Hello People i have a list of Customers (with Name and Id) that i have hardcoded in my Customers Controller as: Click to view Customer Controller i am sending list to a view named Customer to display all the three customers with their names as links using following code :
#model IEnumerable<App.Models.Customer>
#{
ViewBag.Title = "Customer";
}
#foreach (var customer in Model)
{
<li>
#Html.ActionLink(customer.Name, "Details", "Customers", new { id = customer.Id }, null)
</li>
}
It displays list of customers but problem is when i click any customer name(Which is a link) it gives a HTTP 404 error as :Click to see Error details
i have made a Details method in Costumers Controller as
[HttpPost]
public ActionResult Details(int id)
{
var customer = GetCustomers().SingleOrDefault(x => x.Id == id);
if (customer == null)
{
return HttpNotFound();
}
return View(customer);
}
that recieves id of the customer name being clicked and simply displays its name again but it doesnt works and gives 404 error i have debugged the code and what i have found that control never reached the details Method in Controller, is the issue in ActionLink or what ?
Help is highly appreciated thank you
The method should be HttpGet:
[HttpGet]
public ActionResult Details(int id)
{
var customer = GetCustomers().SingleOrDefault(x => x.Id == id);
if (customer == null)
{
return HttpNotFound();
}
return View(customer);
}

Edit order details in ASP.NET MVC

The standard way to edit a record in ASP.NET MVC is the following:
//
// GET: /Movies/Edit/5
public ActionResult Edit(int id = 0)
{
Movie movie = db.Movies.Find(id);
if (movie == null)
{
return HttpNotFound();
}
return View(movie);
}
//
// POST: /Movies/Edit/5
[HttpPost]
public ActionResult Edit(Movie movie)
{
if (ModelState.IsValid)
{
db.Entry(movie).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(movie);
}
The problem is that I need to edit order details (1 order, many details) and therefore based on two IDs (the order and the product ones). It does not work (I cannot get an OrderDetail item as action parameter). How can I solve this problem?
Thanks.
//
// GET: /Orders/EditDetails
public ActionResult EditDetails(int id, string productID)
{
OrderDetail od = GetOrderDetail(id, productID);
return View(od);
}
//
// POST: /Orders/EditDetails
[HttpPost]
public ActionResult EditDetails(OrderDetail od)
{
if (ModelState.IsValid)
{
context.Entry(od).State = EntityState.Modified;
context.SaveChanges();
return RedirectToAction("Index");
}
return View(od);
}
EDIT: Here is the code requested by Shimmy:
#using (Html.BeginForm("EditDetails", "Orders", FormMethod.Post))
{
#Html.LabelFor(m => m.quantity)
#Html.TextBoxFor(m => m.quantity)
#Html.LabelFor(m => m.productID)
#Html.DropDownListFor(m => m.productID, new SelectList((IEnumerable)ViewBag.productList, "productID", "fullProductName"))
#Html.HiddenFor(model => model.orderID)
}
Make sure the OrderDetail.Id itself as well as the OrderDetail.OrderId and the OrderDetail.MovieId properties are all present in the form as a hidden field.
In that way, when you post it back to the server you have track on what Movie and Order this OrderDetail is of, in the action.

MVC 3 - Passing model to controller from different controller

At the moment this is what I have in my HomeController:
[HttpPost]
public ActionResult Index(HomeFormViewModel model)
{
...
...
TempData["Suppliers"] = service.Suppliers(model.CategoryId, model.LocationId);
return View("Suppliers");
}
This is what I have in my SupplierController:
public ViewResult Index()
{
SupplierFormViewModel model = new SupplierFormViewModel();
model.Suppliers = TempData["Suppliers"] as IEnumerable<Supplier>;
return View(model);
}
This is my Supplier Index.cshtml:
#model MyProject.Web.FormViewModels.SupplierFormViewModel
#foreach (var item in Model.Suppliers) {
...
...
}
Instead of using TempData is there a different way to pass objects to a different controller and its view?
Why don't you just pass those two ID's in as parameters, then call the service class from the other controller? Something like:
Have your SupplierController method like so:
public ViewResult Index(int categoryId, int locationId)
{
SupplierFormViewModel model = new SupplierFormViewModel();
model.Suppliers = service.Suppliers(categoryId, locationId);
return View(model);
}
Then, I'm assuming you're calling your view from within the Supplier view via a link of some sort? You can do:
#foreach (var item in Model.Suppliers)
{
#Html.ActionLink(item.SupplierName, "Index", "Supplier", new { categoryId = item.CategoryId, locationId = item.LocationId})
//The above assumes item has a SupplierName of course, replace with the
//text you want to display in the link
}

How can I show two ActionResult in Home/index view MVC C#

I have two controllers
BloggsController:
//Last blogg from the database
public ActionResult LastBlogg()
{
var lastblogg = db.Bloggs.OrderByDescending(o => o.ID).Take(1);
return View(lastblogg);
}
DishesController:
//Last recipe from the database
public ActionResult LastRecipe()
{
var last = db.Dishes.OrderByDescending(o => o.ID).Take(1);
return View(last);
}
I want to show the result of this on my start-page, Views/Home/index.
If I put this in my HomeController:
//Last recipe from the database
public ActionResult Index()
{
var last = db.Dishes.OrderByDescending(o => o.ID).Take(1);
return View(last);
}
Can I show the result in of recipe on my start-page but how do I show both the result of the blogg and recipe on om startpage?
You should create separate partial views for LastBlogg and LastRecipe and place both of them to your home page (new Model will be required).
Create a View Model and add both Blogg and Recipe to it.
public ActionResult Index()
{
var lastRecipe = db.Dishes.OrderByDescending(o => o.ID).Take(1);
var lastblogg = db.Bloggs.OrderByDescending(o => o.ID).Take(1);
var model = new BloggRecipeModel(lastRecipe, lastblogg);
return View(model);
}
You could simply create a custom ViewData in your Models folder, like this:
public class MyCustomViewData
{
public Dish Dish {get;set;}
public Blog Blog {get;set;}
}
Then in your controller:
ViewData.Model = new MyCustomViewData
{
Dish = db.Dishes.OrderByDescending(o => o.ID).Take(1);
Blog = db.Bloggs.OrderByDescending(o => o.ID).Take(1);
}
return View();
And in your view, set the #Model property to Models.MyCustomViewData and handle it accordingly.

ASP.NET MVC Show success message

Here is an example method I have that deletes a record from my app:
[Authorize(Roles = "news-admin")]
public ActionResult Delete(int id)
{
var ArticleToDelete = (from a in _db.ArticleSet where a.storyId == id select a).FirstOrDefault();
_db.DeleteObject(ArticleToDelete);
_db.SaveChanges();
return RedirectToAction("Index");
}
What I would like to do is show a message on the Index view that says something like: "Lorem ipsum article has been deleted" how would I do this? Thanks
Here is my current Index method, just in case:
// INDEX
[HandleError]
public ActionResult Index(string query, int? page)
{
// build the query
var ArticleQuery = from a in _db.ArticleSet select a;
// check if their is a query
if (!string.IsNullOrEmpty(query))
{
ArticleQuery = ArticleQuery.Where(a => a.headline.Contains(query));
//msp 2011-01-13 You need to send the query string to the View using ViewData
ViewData["query"] = query;
}
// orders the articles by newest first
var OrderedArticles = ArticleQuery.OrderByDescending(a => a.posted);
// takes the ordered articles and paginates them using the PaginatedList class with 4 per page
var PaginatedArticles = new PaginatedList<Article>(OrderedArticles, page ?? 0, 4);
// return the paginated articles to the view
return View(PaginatedArticles);
}
One way would be to use TempData:
[Authorize(Roles = "news-admin")]
public ActionResult Delete(int id)
{
var ArticleToDelete = (from a in _db.ArticleSet where a.storyId == id select a).FirstOrDefault();
_db.DeleteObject(ArticleToDelete);
_db.SaveChanges();
TempData["message"] = ""Lorem ipsum article has been deleted";
return RedirectToAction("Index");
}
and inside the Index action you could fetch this message from TempData and make use of it. For example you could pass it as a property of your view model which will be passed to the view so that it can show it:
public ActionResult Index()
{
var message = TempData["message"];
// TODO: do something with the message like pass to the view
}
UPDATE:
Example:
public class MyViewModel
{
public string Message { get; set; }
}
and then:
public ActionResult Index()
{
var model = new MyViewModel
{
Message = TempData["message"] as string;
};
return View(model);
}
and inside the strongly typed view:
<div><%: Model.Message %></div>

Categories

Resources