1

I'm pretty new to ASP.NET MVC and was wondering how to do the following:

I have a list with some buttons like this:

@model List<SitefinityWebApp.Mvc.Models.ProfileModel>

@using (Html.BeginForm())
{
   <ul>
      @foreach (var item in Model)
      {
         <li>
            <span>@item.EmailAddress</span>
            <button id="submit">Generate code</button>
        </li>
      }
   </ul>
}

So when a user clicks on the button, I need to execute some code on the server where I need the email address as a parameter.

I think I would need a POST for this, but I'm not sure how to set this up. In the end I want the same list to be rendered again.

I tried an ActionLink, but this is only for GET requests as I understood?

Any ideas on how to do this?

Thanks, Daniel

Daniel Plomp
  • 176
  • 1
  • 12
  • you could do 1 form per email address and put a hidden form field. – Daniel A. White Mar 20 '15 at 13:49
  • Posts are generated using HTML forms, see: [What is the difference between POST and GET?](http://stackoverflow.com/questions/3477333/what-is-the-difference-between-post-and-get). So to send some data to the controller as a post you need to add a form and a submit button. – Liam Mar 20 '15 at 13:50
  • 5
    This just sounds like an ordinary POST to a controller method. – Robert Harvey Mar 20 '15 at 13:51
  • @Liam Your comment makes it sound as though a GET request cannot be formed using the input from a form. Although I know what you meant, it doesn't come across very well. – John H Mar 20 '15 at 13:58

2 Answers2

3

You can define POST function in the Controller. Same name as the GET call.
Your Get Call should like somehing like this:

public ActionResult Index()
{
    List<ProfileModel> list = new List<ProfileModel>();
    list.add(listItem);

    return View(list);
}

Then make the POST function:

[HttpPost]
public ActionResult Index(List<ProfileModel> postModel)
{
    var emailAddress = postModel.EmailAddress
    // do some stuff here

    return RedirectToAction("Index");
}

You can call any POST function with the parameters in the Html.BeginForm:

@using (Html.BeginForm("MothodeName", "ControllerName", FormMethod.Post))
{
<!-- form here -->
}
Andre
  • 560
  • 1
  • 8
  • 18
0

It's not entirely clear what you want to do. Currently you are rendering multiple buttons in side a single form, but the form has no controls so nothing will post back (and since you have not specified the buttons type attribute, it may not trigger a submit anyway depending on the browser). One way to solve this is to have a form (specifying a route parameter) for each item that posts back the email address and then redirects back to the index page.

@foreach (var item in Model)
{
  <span>@item.EmailAddress</span>
  @using (Html.BeginForm("ProcessEmail", new { emailAddress = item.EmailAddress }))
  {
    <button type="submit">Generate code</button>
  }
}

and the POST method would be

[HttpPost]
public ActionResult ProcessEmail(string emailAddress)
{
  // do something with the email
  return RedirectToAction("Index"); // redisplay the page
}

Alternatively you could use a hidden input instead of a route parameter

@foreach (var item in Model)
{
  <span>@item.EmailAddress</span>
  @using (Html.BeginForm("ProcessEmail"))
  {
    @Html.HiddenFor(m => item.EmailAddress , new { id = "" }) // remove the id attribute to prevent invalid html
    <button type="submit">Generate code</button>
  }
}

However, to get far better performance and avoid having to regenerate the view each time, you can use ajax to post the value

@foreach (var item in Model)
{
  <span>@item.EmailAddress</span>
  <button type="button" class="process-email" data-email="@item.EmailAddress">Generate code</button>
}

var url = '@Url.Action("ProcessEmail")';
$('.process-email').click(function() {
  $.post(url, { emailAddress: $(this).data('email') }, function(response) {
    if(response) {
      // processing succeeded - display message?
    } else {
      // processing failed = display error?
    }
  })
})

and modify the method to

[HttpPost]
public JsonResult ProcessEmail(string emailAddress)
{
  // do something with the email
  return Json(true); // or return Json(null) if an error occured
}