Pergunta

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?

Foi útil?

Solução

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" />
<% } %>

Outras dicas

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))
    { ... }
}

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

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 });
}

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();
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top