Why can't the value of ViewBag be cleared after PostBack? - c#

My controller name is "demo". I write 2 actions with the same name "Index". The first uses [HttpGet] and the seconds is [HttpPost].
But, when I require a PostBack from View, the value of ViewBag.Name in the action [HttpGet] public ActionResult Index() {} can't be cleared.
[HttpGet]
public ActionResult Index()
{
ViewBag.Name = "HttpGet";
return View();
}
[HttpPost]
public ActionResult Index(FormCollection form)
{
ViewBag.Name = "HttpPost";
return View();
}
In RouteConfig.cs:
routes.MapRoute(
name: "newroute",
url: "demo/index/{type}",
defaults: new { controller = "demo", action = "Index", type = UrlParameter.Optional }
);
and the View:
<form method="post" action="#Url.Action("Index", "demo", new { type = #ViewBag.Name })">
<input type="submit" value="Click me" />
</form>
#ViewBag.Name
Here is my problem: When I click the button, the value of #ViewBag.Name in the page is "HttpPost". But, in URL, it's /demo/index/HttpGet
Why?

If you navigate to this page with a GET request, you're executing method Index(), and as the page is rendered the Name is HttpGet, so it will create the URL for the form action as /demo/index/HttpGet.
Later, once you press the button, you're posting to that very URL created in the previous step, but since the form is POSTing you're executing Index(FormCollection form), and that sets Name to HttpPost. The URL remains what it was generated at the previous step.

Try it :
[HttpGet]
public ActionResult Index()
{
ViewBag.Name = "HttpGet";
return View();
}
[HttpPost]
public ActionResult Index(FormCollection form)
{
ViewBag.Name = "HttpPost";
return RedirectToAction("Index");
}

Related

Redirect back with message after file upload MVC 4 c#

I've working on MVC 4 application and want to redirect back with message to call action view:
Action that called : Upload
Current view : Index
public class HospitalController: Controller {
public ActionResult Index()
{
return View(Model);
}
[HttpPost]
public ActionResult Index(Model model)
{
return View(ohosDetailFinal);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Upload(HttpPostedFileBase upload,FormCollection form)
{
//Here i want to pass messge after file upload and redirect to index view with message
// return View(); not working
}
}
#using (Html.BeginForm("Upload", "Hospital", null, FormMethod.Post, new { enctype = "multipart/form-data", #class = "" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary()
<input type="file" id="dataFile" name="upload" class="hidden" />
}
Thanks !
Follow the PRG pattern. After successful processing, redirect the user to another GET action.
You can return a RedirectResult using RedirectToAction method. This will return a 304 response to the browser with the new url in the location header and the browser will make a new GET request to that url.
[HttpPost]
public ActionResult Upload(HttpPostedFileBase upload,FormCollection form)
{
//to do : Upload
return RedirectToAction("Index","Hospital",new { msg="success"});
}
Now in the Index action, you may add this new parameter msg and check the value of this and show appropriate message. The redirect request will have a querystring with key msg (Ex :/Hospital/Index?msg=success)
public ActionResult Index(string msg="")
{
//to do : check value of msg and show message to user
ViewBag.Msg = msg=="success"?"Uploaded successfully":"";
return View();
}
and in the view
<p>#ViewBag.Msg</p>
If you do not prefer the querystring in the url, you may consider using TempData. But tempdata is available only for the next request.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Upload(HttpPostedFileBase upload,FormCollection form)
{
//Here i want to pass messge after file upload and redirect to index view with message
return Index();//or with model index
}
Try the below code, Hope It helps.!
View
#using (Html.BeginForm("Upload", "Hospital", null, FormMethod.Post, new { enctype = "multipart/form-data", #class = "" }))
{
if (TempData["Info"] != null)
{
#Html.Raw(TempData["Info"])
}
#Html.AntiForgeryToken()
#Html.ValidationSummary()
<input type="file" id="dataFile" name="upload" class="hidden" />
}
Controller
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Upload(HttpPostedFileBase upload,FormCollection form)
{
//Here i want to pass messge after file upload and redirect to index view with message
TempData["Info"]="File Uploaded Successfully!";
return RedirectToAction("Index");
}

Pass Value from Controller to View by ViewBag

So I have a controller and I can seem to understand how to pass a parameter to my ActionResult method.
routes.MapRoute(
name: "MyRoute",
url: "{controller}/{name}/{id}",
defaults: new { controller = "Project", name = "Search", id = UrlParameter.Optional }
);
This is my route. Now in my controller i've created a method
[HttpGet]
public ActionResult Search()
{
return View();
}
[HttpPost]
public ActionResult Search(int Id)
{
ViewBag.iD = Id;
return View();
}
And in my view
<body>
<div>
ASDF + #ViewBag.iD
</div>
</body>
How can I pass a value to my iD parameter from Search Action? It seems whatever I call
http://localhost:52992/Project/Search/id=2
or http://localhost:52992/Project/Search/1
Both method go into the Search() method, none goes to Search(int iD).
What Am I missing?
A link in your view (or a form with FormMethod.Get or entering a url in the address bar) makes a GET call, not a POST, so your method should be
[HttpGet]
public ActionResult Search(int ID)
{
// do something based on the value of ID
ViewBag.iD = ID;
return View();
}
and delete the [HttpPost] method.
You have to pass value from the HttpGet 'SearchAction' method. if you pass from it, then only the value will be shown in the view
[HttpGet]
public ActionResult Search()
{
ViewBag.iD = your Id value here;
return View();
}
on intial load the get method will be called, on submission only the 'post' method will be call.
hope this helps.
On your view
<a href='#Url.Action("ActionName", "ControllerName", new { id= 10})'>...</a>
OR
#{
int id = 10
}
...
On Your Action
Public ActionResult Search(int id)
{
Viewbag.Id = id;
return view();
}
Action is by default on [HTTPGET] you wont have to mention it

Get clicked anchor element's id property

When user click this element, I want catch id data in controller or in OnActionExecuting method in ActionFilter class.
How I can do this?
In view:
<a id="123" href="AreaName/ControllerName">TEST</a>
You could try this...
In Controller:
public ActionResult Index()
{
var model = new HomeViewModel { Id = 123 };
return View(model);
}
public void RecordClick(int id)
{
int incomingId = id;
}
In View:
#Html.ActionLink("Link Text", "RecordClick", "Home", new { id = #Model.Id }, null)
Generated HTML:
Link Text
Upon clicking link, id value will be sent to RecordClick action.
TEST
your controller
[HttpGet]
public ActionResult Index(int userid)
{
return View();
}
if you debug you should have that value

MVC submit button not firing

I am using ASP.net MVC 4 with the Razor engine.
I have a page (Index.cshtml) and a controller (HomeController.cs)
I am trying to hook up my submit button to an Action Result in my controller - however i can't seem to get it to fire.
My HTML :
#using (Html.BeginForm("SubmitForm", "Home", FormMethod.Post))
{
<div class="main-Background">
******lots of other html here*******
<button type="submit" id="btnSave">Save</button>
</div>
}
My Controller :
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application.";
return View();
}
public ActionResult About()
{
ViewBag.Message = "Your app description page.";
return View();
}
public ActionResult Contact()
{
ViewBag.Message = "Your contact page.";
return View();
}
[HttpPost]
public ActionResult SubmitForm()
{
return View();
}
}
At the moment i havn't implemented a model to pass the values through to the controller, i just wanted to see if i could get the ActionResult SubmitForm to fire.
I have tried #using (Html.BeginForm()) with no parameters, i have also tried including [HttpPost] above my ActionResult, without any luck.
Edit i have also tried using <input type="submit" id="btnSave">Save</input> instead of a button.
Not sure where i am going wrong
It turns out that jQuery was stopping the ActionResult from being hit.
I had a button click event which was "eating up" the ActionResult functionality. I solved this by calling my ActionResult using Ajax.
You dont need to use "-Controller" suffix. Use just Home instead of HomeController, MVC will convert it for you.
Use
#using (Html.BeginForm("SubmitForm", "Home", FormMethod.Post, new { id = "submitForm" }))
instead of
#using (Html.BeginForm("SubmitForm", "HomeController", FormMethod.Post, new { id = "submitForm" }))
Full codes
view
#using (Html.BeginForm("SubmitForm", "Home", FormMethod.Post, new { id = "submitForm" }))
{
<div class="main-Background">
******lots of other html here*******
<input type="submit" id="btnSave">Save</input>
</div>
}
And controller
[HttpPost]
public ActionResult SubmitForm()
{
return View();
}
View:
#using (Html.BeginForm("SubmitForm", "Home", FormMethod.Post))
{
<div class="main-Background">
******lots of other html here*******
<button type="submit" id="btnSave">Save</button>
</div>
}
Controller:
[HttpPost]
public ActionResult SubmitForm()
{
return View();
}
May be the problem is occurred because of other HTML inside your div so check it out. Otherwise it works perfectly.
You need to add Html.BeginForm with the parameters. Here is an example:
ActionName – Name of the Action. In this case the name is Create.
ControllerName – Name of the Controller. In this case the name is Home.
FormMethod – It specifies the Form Method i.e. GET or POST. In this case it will be set to POST.
http://localhost:60386//Home/Create
#using (Html.BeginForm("Create", "Home", FormMethod.Post))
{
#Html.EditorFor(model => model.FirstName)
<input type="submit" value="Create"/>
}
HomeController.cs:
[HttpPost]
public ActionResult Create(Person person)
{
if (ModelState.IsValid)
{
db.Persons.Add(person);
db.SaveChanges();
return RedirectToAction("Create");
}
return View(person);
}
TL;DR
I had [Required] data attributes on my view model preventing the submit from working when the form wasn't filled.
I had two submit buttons in my MVC code, one for Submit, the other for Cancel.
Both buttons were firing correctly on data entry, but neither when nothing was entered.
It took me a bit to realize that my view model had [Required] field validations in place!
View:
#using (Html.BeginForm(actionName: "Index", controllerName: "User", method: FormMethod.Post))
{
#Html.AntiForgeryToken()
#Html.TextBoxFor(m => m.PhoneNumber)
...
<input type="submit" name="submitAction" value="Verify" />
<input type="submit" name="submitAction" value="Cancel" />
}
ViewModel:
public class UserViewModel
{
[Required]
[MaxLength(10)]
public string PhoneNumber { get; set; }
[Required]
...
}
Controller Method:
[HttpPost]
[ValidateAntiForgeryToken()]
public ActionResult Index(UserViewModel viewModel, string submitAction)
{
switch(submitAction)
{
case "Verify": ...
case "Cancel": ...
}
}
Change this #using (Html.BeginForm("SubmitForm", "HomeController", FormMethod.Post, new { id = "submitForm" }))
to
#using (Html.BeginForm("SubmitForm", "Home", FormMethod.Post, new { id = "submitForm" }))
Explanation : No need to suffix Controller anywhere, it being accepted by default
and in the Controller
[HttpPost]
public ActionResult SubmitForm(string id)
{
return View();
}
Explanation : as the Form Method given by you is Post so need to include [HttpPost] before the Action and the parameter you were passing was missing in the action method

HTTPPost does not work asp mvc 3

I am really confused,
here is the code :
[HttpPost]
public ActionResult Settings(string SubmitButton)
{
if (SubmitButton == "Sign In") {
ServiceLocator.Current.GetInstance<IAppContext>().LoggedUser = null;
Response.Cookies["loginuser"].Expires = DateTime.Now;
return RedirectToAction("Logon", "Account");
}
if (SubmitButton == "Sign Up") { return RedirectToAction("register", "Account"); }
if (SubmitButton == "Change Default Ride Settings") { return RedirectToAction("changeSettings", "Home"); }
return View();
}
The view contain
<% using (Html.BeginForm()) { %>
Three input ,
<% } %>
the controller is not fired with httppost but fired with httpget
You probably need to pass in the controller and action names in Html.BeginForm() in your view. Since the [HttpPost] Settings() action is being invoked for HTTP get requests, that implies that there isn't another Settings() action for get requests, so I'm guessing that your view is being served from a different action. In such a case, you need to explicitly set the controller and action in your Html.BeginForm(). Try this:
<% using (Html.BeginForm("Settings", "YourControllerName")) { %>
You have to generate a html form with the method attribute set to post if you want a post to happen:
Html.BeginForm("action","controller", FormMethod.Post) { ... }
There should be action with name Index() and should not containg any parameters in it. This is the problem I have faced.
I have used ActionName() to solve the same problem,
Not working code:
[HttpGet]
public ViewResult RsvpForm()
{
[HttpPost]
public ViewResult RsvpFrom()
{
}
Working code:
[HttpGet]
public ViewResult RsvpForm()
{
}
[HttpPost, ActionName("RsvpForm")]
public ViewResult RsvpFromPost()
{
}
The proper way using razor
#using (Html.BeginForm("LogOn", "Account", FormMethod.Post, new { id = "form1" }))
{
//form content
}

Categories

Resources