8

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?

Kris van der Mast
  • 16,343
  • 8
  • 39
  • 61
waldecir
  • 376
  • 2
  • 8
  • 21

5 Answers5

24

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))
    { ... }
}
Knaģis
  • 20,827
  • 7
  • 66
  • 80
4

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 :)

Austin Thompson
  • 2,251
  • 1
  • 17
  • 23
2

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" />
<% } %>
Darin Dimitrov
  • 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
1

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 });
}
John Zumbrum
  • 2,786
  • 8
  • 36
  • 60
0

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();
}
Andrey Tagaew
  • 1,573
  • 1
  • 15
  • 20