I'm using MVC4 and I have 2 methods in my controller:
Get Method
public ActionResult Create()
{
var vm = new User
{
Client= new Catastro_Cliente()
Genre = ClienteRepository.GetGenres(),
Type= ClienteRepository.GetTypes()
};
ViewBag.Genre = new SelectList(vm.Genre, "IdGenre", "Genre");
ViewBag.Type= new SelectList(vm.Type, "IdType", "Type");
return View(vm);
}
Post Method
[HttpPost]
public ActionResult CrearUsuario(Catastro_Cliente client)
{
if(Validator(client.document))
{
ModelState.AddModelError("NoDocument", "The document is invalid or not registered");
}
if(ModelState.IsValid)
{
return View();
}
}
Basically, I'm trying keep all the data that the user filled in before the post Method,
I tried with return RedirectToAction("Create"); but it always refreshes the page.
You have to pass back the posted model when you call View. What you need is something like:
[HttpPost]
public ActionResult CrearUsuario(Catastro_Cliente client)
{
if(Validator(client.document))
{
ModelState.AddModelError("NoDocument", "The document is invalid or not registered");
}
if(ModelState.IsValid)
{
// save to database of whatever
// this is a successful response
return RedirectToAction("Index");
}
// There's some error so return view with posted data:
return View(client);
}
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));
}
}
I have a POST method that returns me to my summary page that looks like this
public ActionResult SpecialOrderSelection(ItemViewModel model)
{
if (ModelState.IsValid)
{
JobOrder jobOrder = db.JobOrders.Find(model.Id);
if (jobOrder == null)
{
return HttpNotFound();
}
ViewBag.JobOrderID = jobOrder.ID;
}
return SpecialOrderSummary(model);
}
And here is my Summary GET method
public ActionResult SpecialOrderSummary(ItemViewModel model)
{
return View("SpecialOrderSummary", model);
}
It sends me to my SpecialOrderSummary View Page, however the URL still displays as what my POST method is and not my GET. Also on every refresh it goes to the post first.
Why is this?
This is normal, because mvc runs like this.
You should use redirect,
public ActionResult SpecialOrderSelection(ItemViewModel model)
{
if (ModelState.IsValid)
{
JobOrder jobOrder = db.JobOrders.Find(model.Id);
if (jobOrder == null)
{
return HttpNotFound();
}
ViewBag.JobOrderID = jobOrder.ID;
}
return Redirect("SpecialOrderSummary?(your model serialize)");;
}
I am trying to customize a POST and GET method called CreateOrEdit(int id, Request request) inside of the controller so that when I am in the Index view which is a list of requests generated from a SQL Table and I click either on the Edit button on the right of each row or on the Create New button, I am redirected to the same View which I have called CreateOrEdit.cshtml. I have managed to make the configuration on RouteConfig.cs but I don't how to come up with an 'if - else' condition in order to check whether id is null or is a number. Someone could help me on solving this?
P. s.: Maybe this is children easy but today is my 9th day as a developer guys :)
I have tried:
1. Add another 2 routes.MapRoute() inside RouteConfig.cs
2. Inside the ActionResult CreateOrEdit() GET and POST methods tried to add a condition in order to know whether id != null but it doesn't seem to help.
[HttpGet]
public ActionResult CreateOrEdit(int? id)
{
return View();
}
[HttpPost]
public ActionResult CreateOrEdit(int? id, Request request)
{
if (/* id is not null (Edit has been clicked) */)
{
try
{
using (DbModels dbModel = new DbModels())
{
dbModel.Requests.Add(request);
dbModel.SaveChanges();
}
return RedirectToAction("Index");
}
catch
{
return View();
}
}
else
{
try
{
// Ketu shtojme logjiken e update-imit
using (DbModels dbModel = new DbModels())
{
dbModel.Entry(request).State = System.Data.EntityState.Modified;
dbModel.SaveChanges();
}
return RedirectToAction("Index");
}
catch
{
return View();
}
}
return View();
}
first your condition is wrong. so just change your condition and then try.
[HttpPost]
public ActionResult CreateOrEdit(int? id, Request request)
{
if (id == null)
{
try
{
using (DbModels dbModel = new DbModels())
{
dbModel.Requests.Add(request);
dbModel.SaveChanges();
}
return RedirectToAction("Index");
}
catch
{
return View();
}
}
else
{
try
{
// Ketu shtojme logjiken e update-imit
using (DbModels dbModel = new DbModels())
{
dbModel.Entry(request).State = System.Data.EntityState.Modified;
dbModel.SaveChanges();
}
return RedirectToAction("Index");
}
catch
{
return View();
}
}
return View();
}**strong text**
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
This works:
[HttpPost]
public ActionResult Slots(Slots slots, ICollection<int> jobNos)
{
if (!ModelState.IsValid)
return View(new SlotsViewModel() { JobNos = jobNos, Slots = slots });
//
// Do stuff
//
return View("MyResults", jobNos);
}
public ActionResult MyResults(ICollection<int> jobs)
{
return View(jobs);
}
However, this does not work.
[HttpPost]
public ActionResult Slots(Slots slots, ICollection<int> jobNos)
{
if (!ModelState.IsValid)
return View(new SlotsViewModel() { JobNos = jobNos, Slots = slots });
//
// Do stuff
//
return RedirectToAction("MyResults", new { jobs = jobNos });
}
public ActionResult MyResults(ICollection<int> jobs)
{
return View(jobs);
}
When I redirect to the new action the ICollection jobs is empty when it should have a count > 0.
Anyone got an idea why redirecting would empty the collection?
RedirectToAction returns a 302 response to the client browser and thus the browser will make a new GET requst to the specified URL.
In this case, If you really want to pass the collection between these two (stateless) HTTP requests, You need some temp storage mechanism like TempData
TempData["Jobs"] =jobNos ;
return RedirectToAction("MyResults");
And Read it in the other ActionMethod
public ActionResult MyResults()
{
var model=TempData["Jobs"] as List<int>;
return View(model);
}
TempData uses Session object behind the scene to store the data. But once the data is read the data is terminated.