I have a controller to show up a model (User) and want to create a screen just with a button to activate. I don't want fields in the form. I already have the id in the url. How can I accomplish this?
5 Answers
Use [ActionName] attribute - this way you can have the URLs seemingly point to the same location but perform different actions depending on the HTTP method:
[ActionName("Index"), HttpGet]
public ActionResult IndexGet(int id) { ... }
[ActionName("Index"), HttpPost]
public ActionResult IndexPost(int id) { ... }
Alternatively you can check the HTTP method in code:
public ActionResult Index(int id)
{
if (string.Equals(this.HttpContext.Request.HttpMethod, "POST", StringComparison.OrdinalIgnoreCase))
{ ... }
}

- 20,827
- 7
- 66
- 80
A bit late to the party on this but I found an easier solution to what I think is a fairly common use-case where you prompt on GET ("are you sure you want to blah blah blah?") and then act on POST using the same argument(s).
The solution: use optional parameters. No need for any hidden fields and such.
Note: I only tested this in MVC3.
public ActionResult ActivateUser(int id)
{
return View();
}
[HttpPost]
public ActionResult ActivateUser(int id, string unusedValue = "")
{
if (FunctionToActivateUserWorked(id))
{
RedirectToAction("NextAction");
}
return View();
}
On a final note, you can't use string.Empty in place of ""
because it must be a compile-time constant. And it's a great place to put funny comments for someone else to find :)

- 2,251
- 1
- 17
- 23
You could use a hidden field inside the form:
<% using (Html.BeginForm()) { %>
<%= Html.HiddenFor(x => x.Id) %>
<input type="submit" value="OK" />
<% } %>
or pass it in the action of the form:
<% using (Html.BeginForm("index", "home",
new { id = RouteData.Values["id"] }, FormMethod.Post)) { %>
<input type="submit" value="OK" />
<% } %>

- 1,023,142
- 271
- 3,287
- 2,928
-
But i cant have httpost and httpget with same paramets, can you show the sample for .cs too ? – waldecir Dec 13 '10 at 13:17
-
@waldecir, no, you can't have two controller actions with the same arguments. You will need to modify the signatures of either your GET or POST action. – Darin Dimitrov Dec 13 '10 at 13:23
-
Yes i know. my firt page is a get with id to show the infos about user, so i need a post to activate/deactivate, how would be the httppost call? – waldecir Dec 13 '10 at 13:25
-
3@waldecir, you have two possibilities: either rename your controller action to make the compiler happy and still use the `[ActionName("Index")]` along with the `[HttpPost]` attribute to make this action accessible with the same name as the GET action, or add some dummy action parameter to it. – Darin Dimitrov Dec 13 '10 at 13:28
-
Thnkx very much, i thinkg the best option is create a new action, and use the second solution with routes, sice i dont need any model information, do you agree? – waldecir Dec 13 '10 at 13:34
-
@waldecir, yes that's an option. – Darin Dimitrov Dec 13 '10 at 13:40
My approach is not to add an unused parameter as that seems like it would cause confusion, and is in general bad practice. Instead, what I do is append "Post" to my action name:
public ActionResult UpdateUser(int id)
{
return View();
}
[HttpPost]
public ActionResult UpdateUserPost(int id)
{
// Do work here
RedirectToAction("ViewCustomer", new { customerID : id });
}

- 2,786
- 8
- 36
- 60
The easiest way for such simple situation is to give a name to submit button and check in action if it has value or not. If it has the value, then it Post action, if not, then it Get action :
<% using (Html.BeginForm("index", "home",
new { id = RouteData.Values["id"] }, FormMethod.Post)) { %>
<input type="submit" value="OK" name="btnActivate" />
<% } %>
For Cs you can combine get and post controller methods in one:
public ActionResult Index(int? id, string btnActivate)
{
if (!string.IsNullOrEmpty(btnActivate))
{
Activate(id.Value);
return RedirectToAction("NextAction");
}
return View();
}

- 1,573
- 1
- 15
- 20