I have this controller:
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public PartialViewResult SearchData(DataClass dc)
{
//Some logic
return PartialView(data);
}
public ActionResult Search(DataClass dc)
{
//Some logic
return View(dc);
}
[HttpGet]
public ActionResult Info(string edrpou)
{
//Some logic
return View(dc);
}
[HttpPost]
public ActionResult Info(DataClass dc)
{
// ???
return View("Search", dc);
}
}
In view Search.cshtml I have some forms like
#Html.TextBoxFor(x => x.Param, new { #class = "form-control", #id = "textBox" })
to create query string and <input type="submit" /> to confirm. Then I show some info from db and create link
#Html.ActionLink((string)Model.Rows[i]["NAME"], "Info", "Home", new { edrpou = (string)Model.Rows[i]["EDRPOU"] }, null)
after pressing it redirected to view Info.cshtml. In result I get /Home/ResultInfo?edrpou=41057472 page with some info and forms like in Search
After pressing confirm button in Info reference still /Home/ResultInfo?edrpou=41057472 but I expect to use logic from Search after pressing that button.
P.S. PartialViewResult triggered in Search and it exactly what I need by pressing confirm button in Info
Thank you for help!
Looks like you need RedirectToAction:
[HttpPost]
public ActionResult Info(DataClass dc)
{
// some specific logic, if any
return RedirectToAction("Search");
}
And because you need to move around the DataClass object, you could also use TempData:
[HttpPost]
public ActionResult Info(DataClass dc)
{
// some specific logic, if any
TempData['data'] = dc; //of course 'data' is not a good name, use something more specific
return RedirectToAction("Search");
}
public ActionResult Search(DataClass dc)
{
if (dc == null && TempData.ContainsKey('data'))
dc = (DataClass)TempData['data'];
//Some logic
return View(dc);
}
Alternatively you could just call Search directly, but that's not as nice, because it won't redirect user to the correct route: it will appear as though user is still on "info" page while in reality they are already on "search".
Related
I have this mvc controller that add a customer to the database called CustomerController. This Controller has one ActionResult called Add. It works as it is but I want to display a status message after the user hit submit, and I want all information added to the model be kept on the page as is. How can I keep the all the entered text in the form fields and also show a status message after the form has been posted?
public ActionResult Add()
{
// This is the empty view the user see when he is about to add new form data
return View(new CreateSupplierViewModel());
}
public ActionResult AddNew(CreateSupplierViewModel model)
{
// I post to this and need to display the status of this on the view with the entered text fields as is
return RedirectToAction("Add", "Supplier");
}
You need to refactor your code as below :
The CustomerController :
public ActionResult Add()
{
return View(new CreateSupplierViewModel());
}
public ActionResult Add(CreateSupplierViewModel model)
{
return View(model);
}
public ActionResult AddNew(CreateSupplierViewModel model)
{
return RedirectToAction("Add", "Supplier", model);
}
Your SupplierController
public ActionResult Add(CreateSupplierViewModel model)
{
//save the entity
Viewbag.Message ="submit result";
return RedirectToAction("Add", "Customer", model);
}
The Customer/Add.cshtml (show the submit result in view)
#if( Viewbag.Message != null)
{
<p> #Viewbag.Message </p>
}
I'm developing a simple Custom Role-based Web Application using ASP.Net MVC, In my login Action, I'm creating a Profile session as below:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginModel model, string returnUrl)
{
using (HostingEnvironment.Impersonate())
{
if (ModelState.IsValid)
{
if (Membership.ValidateUser(model.UserName, model.Password))
{
var employeeProfile = AccountBal.Instance.GetEmployee(loginId);
Session["Profile"] = employeeProfile;
FormsAuthentication.SetAuthCookie(model.UserName, true);
}
}
// If we got this far, something failed, redisplay form
ModelState.AddModelError("", #"The user name or password provided is incorrect.");
return View(model);
}
}
And I'm checking this or using this session in all Controller Actions as below:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult CreateOrEdit(MyModel model)
{
var employee = (Employee) Session["Profile"];
if (employee == null)
return RedirectToAction("Login", "Account");
if (ModelState.IsValid)
{
// Functionality goes here....
}
}
Is there any way I can move this piece of session checking code in a base class or centralized class? so that, I do not need to check it every time in a Controller Actions instead I will access the properties directly
say,
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult CreateOrEdit(MyModel model)
{
var employee = _profileBase.GetCurrentProfile();
if (employee == null)
return RedirectToAction("Login", "Account");
if (ModelState.IsValid)
{
// Functionality goes here....
}
}
Create a base controller that contains your GetCurrentProfile method to retrieve current user profile like
public class BaseController : Controller
{
public Employee GetCurrentProfile()
{
return (Employee)Session["Profile"];
}
public bool SetCurrentProfile(Employee emp)
{
Session["Profile"] = emp;
return true;
}
}
And inherit your desired controller with above BaseController and access your GetCurrentProfile method like below
public class HomeController : BaseController
{
public ActionResult SetProfile()
{
var emp = new Employee { ID = 1, Name = "Abc", Mobile = "123" };
//Set your profile here
if (SetCurrentProfile(emp))
{
//Do code after set employee profile
}
return View();
}
public ActionResult GetProfile()
{
//Get your profile here
var employee = GetCurrentProfile();
return View();
}
}
GetCurrentProfile and SetCurrentProfile directly available to your desired controller because we directly inherit it from BaseController.
You may usetry/catch in above code snippet.
Try once may it help you
I will have a registration form on my website which will firstly show the boardrules / legal. Once accepted it will then show the main registration form. Using a ViewModel as below:
public class MyViewModel
{
public int Readrules { get; set; }
public int Coppa { get; set; }
}
public ActionResult Register(MyViewModel model)
{
... at this stage model.Readrules and model.Coppa will contain the values passed
as query string parameters tat you could use here
}
The idea is if I go to /register it will show the rules and then /register?readrules=1 it will then show the registration form. This is how it was done in PHP but now I am migrating to ASP.NET..
What is the best way of doing this? Can I redirect to the same action and just parse the value of model.ReadRules or must I use more than one action? I would prefer to keep this in one action and just check if model.ReadRules == 1 and either display the boardrules or registration form.
Thanks
Instead of re-using the Register action, you could have different controller actions for displaying the rules, registering and processing the registration, like so:
Controller Actions:
public ActionResult BoardRules()
{
return View();
}
public ActionResult Register(MyViewModel model)
{
if (model.ReadRules != 1)
return RedirectToAction("BoardRules");
return View();
}
public ActionResult Registration(MyViewModel model)
{
if (model.ReadRules != 1)
return RedirectToAction("BoardRules");
//Process the registration
return View();
}
Views:
BoardRules.cshtml:
#* HTML Displaying Rules *#
Accept Rules
Register.cshtml:
#using (Html.BeginForm("Registration", "[Controller Name]", new { ReadRules = 1 }))
{
#* Form Fields *#
<input type="submit" value="Process Registration" />
}
Registration.cshtml
<h2>Congratz on Registering!</h2>
public ActionResult Register()
{
return View("boardrules"); //Default
}
public ActionResult Register(MyViewModel model)
{
if (model.ReadRules == 1)
{
model.ReadRules++; //Next time it won't be 1 but step 2
return View("registration",model);
}
else
{
//Do IF or Case for other step
}
return View("boardrules"); //Default
}
I am working on a ASP.NET MVC website and I am new to this.
I have a controller with few actions. I want to use these actions through out my website.
For example
[HttpPost]
public ActionResult MyAction(ViewModel model)
{
if (ModelState.IsValid)
{
//code is here
}
return RedirectToAction(); // redirect to same view
}
I want to redirect to same view from where request is generated. I am not sure if this is possible or not ?
Based on your comment, I would create a Controller that looks like:
public MyController : Controller
{
private ActionResult SharedMethod(SomeModel model)
{
if (ModelState.IsValid)
{
//code is here
}
// viewname is required, otherwise the view name used will be
// the original calling method (ie public1.cshtml, public2.cshtml)
return this.View("SharedViewName");
}
public ActionResult Public1(SomeModel model)
{
return this.SharedMethod(model);
}
public ActionResult Public1(SomeModel model)
{
return this.SharedMethod(model);
}
}
I'd like show a form with some field (one in the example), submit it, save and display the same page with a reset of all fields. The probelm when I submit, I go the "Save" action but when I display the view the form is still filled in.
The model :
public class TestingModel
{
public string FirstName { get; set; }
}
The controller :
public class ChildController : Controller
{
public ActionResult Index()
{
TestingModel model = new TestingModel();
return View(model);
}
public ActionResult Save(TestingModel model)
{
Console.WriteLine(model.FirstName); //OK
//Save data to DB here ...
TestingModel testingModel = new TestingModel() { FirstName = string.Empty };
return View("Index", testingModel);
}
}
The view :
#using (Html.BeginForm("Save", "Child",FormMethod.Post))
{
#Html.TextBoxFor( m => m.FirstName)
<input type="submit" id="btSave" />
}
When Id debug to the view, in "Immediat window" Model.FirstName = "" but when the page is show I still have the value posted. I tried a ReditrectionToAction("Index") at the end of the Save method but same result.
Do you have an idea ?
Thanks,
If you want to do this you need to clear everything that's in the ModelState. Otherwise HTML helpers will completely ignore your model and use data from ModelState when binding their values.
Like this:
[HttpPost]
public ActionResult Save(TestingModel model)
{
//Save data to DB here ...
ModelState.Clear();
TestingModel testingModel = new TestingModel() { FirstName = string.Empty };
return View("Index", testingModel);
}
or simply redirect to the Index GET action in case of success:
[HttpPost]
public ActionResult Save(TestingModel model)
{
//Save data to DB here ...
return RedirectToAction("Index");
}
Try to return Index view without any model
return View("Index");
You should be posting your form back to the same ActionResult
public ActionResult Index()
{
TestingModel model = new TestingModel();
return View(model);
}
[HttpPost]
public ActionResult Index(TestingModel model)
{
Console.WriteLine(model.FirstName); //OK
//Save data to DB here ...
return RedirectToAction("Index");
}
You would be able to use the parameterless overload for BeginForm too
#using(Html.BeginForm())
{
//form
}