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>
Related
I want to know, there is any technique so we can pass Model as a parameter in RedirectToAction
For Example:
public class Student{
public int Id{get;set;}
public string Name{get;set;}
}
Controller
public class StudentController : Controller
{
public ActionResult FillStudent()
{
return View();
}
[HttpPost]
public ActionResult FillStudent(Student student1)
{
return RedirectToAction("GetStudent","Student",new{student=student1});
}
public ActionResult GetStudent(Student student)
{
return View();
}
}
My Question - Can I pass student model in RedirectToAction?
Using TempData
Represents a set of data that persists only from one request to the
next
[HttpPost]
public ActionResult FillStudent(Student student1)
{
TempData["student"]= new Student();
return RedirectToAction("GetStudent","Student");
}
[HttpGet]
public ActionResult GetStudent(Student passedStd)
{
Student std=(Student)TempData["student"];
return View();
}
Alternative way
Pass the data using Query string
return RedirectToAction("GetStudent","Student", new {Name="John", Class="clsz"});
This will generate a GET Request like Student/GetStudent?Name=John & Class=clsz
Ensure the method you want to redirect to is decorated with [HttpGet] as
the above RedirectToAction will issue GET Request with http status
code 302 Found (common way of performing url redirect)
Just call the action no need for redirect to action or the new keyword for model.
[HttpPost]
public ActionResult FillStudent(Student student1)
{
return GetStudent(student1); //this will also work
}
public ActionResult GetStudent(Student student)
{
return View(student);
}
Yes you can pass the model that you have shown using
return RedirectToAction("GetStudent", "Student", student1 );
assuming student1 is an instance of Student
which will generate the following url (assuming your using the default routes and the value of student1 are ID=4 and Name="Amit")
.../Student/GetStudent/4?Name=Amit
Internally the RedirectToAction() method builds a RouteValueDictionary by using the .ToString() value of each property in the model. However, binding will only work if all the properties in the model are simple properties and it fails if any properties are complex objects or collections because the method does not use recursion. If for example, Student contained a property List<string> Subjects, then that property would result in a query string value of
....&Subjects=System.Collections.Generic.List'1[System.String]
and binding would fail and that property would be null
[HttpPost]
public async Task<ActionResult> Capture(string imageData)
{
if (imageData.Length > 0)
{
var imageBytes = Convert.FromBase64String(imageData);
using (var stream = new MemoryStream(imageBytes))
{
var result = (JsonResult)await IdentifyFace(stream);
var serializer = new JavaScriptSerializer();
var faceRecon = serializer.Deserialize<FaceIdentity>(serializer.Serialize(result.Data));
if (faceRecon.Success) return RedirectToAction("Index", "Auth", new { param = serializer.Serialize(result.Data) });
}
}
return Json(new { success = false, responseText = "Der opstod en fejl - Intet billede, manglede data." }, JsonRequestBehavior.AllowGet);
}
// GET: Auth
[HttpGet]
public ActionResult Index(string param)
{
var serializer = new JavaScriptSerializer();
var faceRecon = serializer.Deserialize<FaceIdentity>(param);
return View(faceRecon);
}
[NonAction]
private ActionResult CRUD(someModel entity)
{
try
{
//you business logic here
return View(entity);
}
catch (Exception exp)
{
ModelState.AddModelError("", exp.InnerException.Message);
Response.StatusCode = 350;
return someerrohandilingactionresult(entity, actionType);
}
//Retrun appropriate message or redirect to proper action
return RedirectToAction("Index");
}
i did find something like this, helps get rid of hardcoded tempdata tags
public class AccountController : Controller
{
[HttpGet]
public ActionResult Index(IndexPresentationModel model)
{
return View(model);
}
[HttpPost]
public ActionResult Save(SaveUpdateModel model)
{
// save the information
var presentationModel = new IndexPresentationModel();
presentationModel.Message = model.Message;
return this.RedirectToAction(c => c.Index(presentationModel));
}
}
When I register a user, it redirects to the Manage controller (where the user profile is).
return RedirectToAction("Index", "Manage", new { id = user.Id });
and in the Manage Controller
[Route("")]
[Route("{id}")]
public ActionResult Index(string id)
{
if (id == null)
{
id = User.Identity.GetUserId();
}
var user = UserManager.FindById(id);
return View(user);
}
I need to send a string message of "newUser", so I can display a modal message the first time the user makes the account and is redirected to their profile.
My question is how exactly? I tried to send a string parameter like this:
return RedirectToAction("Index", "Manage", new { id = user.Id, msg = "newUser" });
and change the Index constructor to Index(string id, string msg) but for some reason both the id and msg get the value of the user id.
Anyone know a solution to this?
Manage / Index
public ActionResult Index(string id)
{
if (id == null)
{
id = User.Identity.GetUserId();
}
var user = UserManager.FindById(id);
return View(user);
}
You can make use of TempData for passing data from one controller to anhother.
Example :
public ActionResult Index()
{
var model = new Review()
{
Body = "Start",
Rating=5
};
TempData["ModelName"] = model;
return RedirectToAction("About");
}
public ActionResult About()
{
var model= TempData["ModelName"];
return View(model);
}
Refer this link for more info : https://www.codeproject.com/articles/476967/what-is-viewdata-viewbag-and-tempdata-mvc-option
You code syntax is almost correct except you are missing " in msg = "newUser
You could have use TempData for sending data from controller to controller.
For more reference :
http://www.tutorialsteacher.com/mvc/tempdata-in-asp.net-mvc
this is the controller
public ActionResult Test() {
#ViewBag.TheMessageIs = "this is the message";
return RedirectToAction("Details", new { id = theId});
}
on the view of Action Named Details I will check if it has the ViewBag to show and show it:
#{
if(ViewBag.TheMessageIs != null){
#ViewBag.TheMessageIs
}
}
but here the redirection is working fine to the page, it's not show the message I have stored in ViewBag.TheMessageIs
thanks
Basically what you're doing is invoking the method Details from your Index method and since you're already overloading your Details action with an id, pass it the message as well:
public ActionResult Index()
{
//ViewBag.TheMessageIs = "this is the message";
return RedirectToAction("Details", new { id = 1, TheMessageIs = "this is the message" });
}
public ActionResult Details(int id, string TheMessageIs)
{
ViewBag.TheMessageIs = TheMessageIs;
return View();
}
Then in the Details view you can access the property like this:
#ViewBag.TheMessageIs
public ActionResult Test() {
TempData["shortMessage"] = "MyMessage";
return RedirectToAction("Details", new { id = theId});
}
public ActionResult Details {
//now I can populate my ViewBag (if I want to) with the TempData["shortMessage"] content
ViewBag.TheMessageIs = TempData["shortMessage"].ToString();
return View();
}
You have to do it like this since the viewbag looses its value when you redirect to another active / view
I have below controllers:
// GET: /MaterialPaymentRequestSbuItem/CreateChild
public ActionResult CreateChild(int? parentId)
{
if (parentId==null)
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
var parenetRequest = (from request in db.MaterialPaymentRequests
where request.Id==(int)parentId
select request);
ViewBag.MaterialPaymentRequestId = new SelectList(parenetRequest, "Id", "Description", (int)parentId);
ViewBag.ParentID = parentId;
if (parenetRequest!=null && parenetRequest.First()!=null)
ViewBag.ParentTitle = parenetRequest.First().Description;
return View();
}
// POST: /MaterialPaymentRequestSbuItem/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult CreateChild([Bind(Include = "Id,Name,Unit,UnitPrice,MaterialPaymentRequestId,Quantity")] MaterialPaymentRequestSubItem materialpaymentrequestsubitem)
{
if (ModelState.IsValid)
{
try
{
db.MaterialPaymentRequestSubItems.Add(materialpaymentrequestsubitem);
db.SaveChanges();
}
catch (Exception e)
{
return new HttpStatusCodeResult(HttpStatusCode.InternalServerError);
}
updateTotalPriceOfParentPaymentRequest(db, db.MaterialPaymentRequests.Find(materialpaymentrequestsubitem.MaterialPaymentRequestId));
return RedirectToAction("List", new { id = materialpaymentrequestsubitem.MaterialPaymentRequestId });
}
ViewBag.MaterialPaymentRequestId = new SelectList(db.PaymentRequests, "Id", "Description", materialpaymentrequestsubitem.MaterialPaymentRequestId);
//need to becheked
ViewBag.ParentID = materialpaymentrequestsubitem.MaterialPaymentRequestId;
if (Request != null && Request["parentID"] != null)
{
try
{
int id = Int32.Parse(Request["parentID"]);
ViewBag.ParentTitle = db.MaterialPaymentRequests.Find(id).Description;
}
catch(Exception e)
{
}
}
return View(materialpaymentrequestsubitem);
}
My main problem is that user is allowed to select model.MaterialPaymentRequestId from drop-down and he/she may leave it with no value selected. MaterialPaymentRequestId is used in first controller (befor post) to find Parent title from db and pass it to view using ViewBag, however if user does not select MaterialPaymentRequestId dropdown items, after postback, I lost MaterialPaymentRequestId. Currently I read Request variable and look inside url to find parameters to lookup for parentID.
My url calls are like http://localhost:46813/Admin/MaterialPaymentRequestSbuItem/CreateChild?parentId=23.
However this practice seems like a bad practice than I cannot pass v variable between two controller methods a process like this:
Controller method(get) ---> View ---> Controller method(post)
Currently I feel a bit stuck in MVC!
i hope i got your point right, you can use an #Html.hiddenfor(model => model.ParentId) in your view it will store ParentId value from query string and when user submits form will be posted to POST method so you dont need to look into url to get it. use a viewmodel with ParentId property and do as below
public class MaterialPaymentsViewModel {
//other properties
public int ParentId {get;set;}
}
public ActionResult CreateChild(int? parentId)
{
var model = new MaterialPaymentsViewModel{ParentId = parentId};
//other stuff
return View(model);
}
//View
#using (Html.beginform()){
//
#html.hiddenfor(m => m.ParentId)
//submit
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult CreateChild(MaterialPaymentsViewModel model)
{
if(model.ParentId != null)
{
//
}
//
}
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.