I am using Asp.net MVC 2 and I need some server-side solution.
Scenario:
I have a form with a submit button.
The action that handles that post request takes a long time to finish.
When that action finishes, it has got to send the client back to the same page. Then, a custom beautiful message box is shown to the user through javascript.
Finally, when the user clicks on a button of that MessageBox, the client is redirected via javascript.
My problem:
After the first time the client sends the post request to the heavy action, the client can click on the submit button a lot of times while waiting for the response.
So, if the client clicks three times on the submit button, after some time the client receives three responses from the server. However, I cannot allow this since just the
first post request needs be processed and the others must be ignored.
What do I want?
So, I just want get the first reponse to arrive to the client. The other requests and responses must be ignored after the first post request and the first response goes to the client.
After the first time the client sends the post request to the heavy action, the client can click on the submit button a lot of times while waiting for the response.
So, if the client clicks three times on the submit button, after some time the client receives three responses from the server. However, I cannot allow this since just the
first post request needs be processed and the others must be ignored.
Its a bad design.
Starter2
What do I want?
So, I just want get the first reponse to arrive to the client. The other requests and responses must be ignored after the first post request and the first response goes to the client.
Just disable button till you are getting the response.
Regardless of it being a server side solution you need to stop multiple submits from the client. Check out the jquery BlockUI plugin. Very easy to implement.
Reporting by definition is different. Otherwise we would just show it on the screen.
In fact, I need some server-side validation... Client-side solution are not a problem. I did a small sample of the problem.
Here is my viewModel and the Controller:
public class ViewModel
{
public int? Id { get; set; }
public string Name { get; set; }
}
public class HomeController : Controller
{
[HttpGet]
public ActionResult Index()
{
Session["FirstPostRequestExecuted"] = false;
return View(new ViewModel());
}
[HttpPost]
public ActionResult Index(ViewModel viewModel)
{
if ((bool)Session["FirstPostRequestExecuted"])
{
// I need to ignore the post requests that come after the first post request
}
else
{
Thread.Sleep(5000); // some heavy task here
viewModel.Id = 1;
viewModel.Name = "Some name";
Session["FirstPostRequestExecuted"] = true;
}
return View(viewModel);
}
}
So, I want to click a couple of times on the submit button and get the informations of my viewModel to be shown on the page, i. e., just the first response of the first request is taken into account. In the sample, the last response is sent to the client.
If you run this sample, when you click twice on the submit button, the viewModel fields are not shown. I also do not want to use Session or even TempData to save the ViewModel on the server memory. I am searching for a clean server-side solution.
Move this up before the heavy task so that you will know task has started and processing is happening.
Starter2
If you run this sample, when you click twice on the submit button, the viewModel fields are not shown. I also do not want to use Session or even TempData to save the ViewModel on the server memory. I am searching for a clean server-side solution.
ActionFilter is your friend, you can design one to check if this is a HttpPost and then assign the value in session and check the same value next time when post happens, something like below,
public class BlockMultiplePostAttribute: IAuthorizationFilter
{
public void OnAuthorization(AuthorizationContext authorizationContext)
{
if (authorizationContext.RequestContext.HttpContext.Request.HttpMethod == "POST")
{
if(authorizationContext.RequestContext.HttpContext.Session["MultiplePostCheck"]== true)
{
authorizationContext.Result = new EmptyResult();
return
}
authorizationContext.RequestContext.HttpContext.Session["MultiplePostCheck"] = true;
return;
}
return;
}
}
See how this works for you, you can modify this to create a unique session key by adding the Action Name from ActionDescriptor.
I still get the same problem. The first response with the valid viewModel is kind of replaced by the last EmptyResult. Then, I get an empty page when I click more than once on the submit button.
ah, I realized now, it will not work and I suspect there is no way you will be able to stop this.
The best you can do is to implement PRG patter, ie Post - Redirect - Get, this way you will immideatly move the user from current page to a new page and he will not be able to submit it again, but you can not stop is completly.
Starter2
0 Points
4 Posts
Handling several post requests from the same Form
Jan 26, 2013 05:43 PM|LINK
I am using Asp.net MVC 2 and I need some server-side solution.
Scenario:
I have a form with a submit button.
The action that handles that post request takes a long time to finish.
When that action finishes, it has got to send the client back to the same page. Then, a custom beautiful message box is shown to the user through javascript.
Finally, when the user clicks on a button of that MessageBox, the client is redirected via javascript.
My problem:
After the first time the client sends the post request to the heavy action, the client can click on the submit button a lot of times while waiting for the response.
So, if the client clicks three times on the submit button, after some time the client receives three responses from the server. However, I cannot allow this since just the
first post request needs be processed and the others must be ignored.
What do I want?
So, I just want get the first reponse to arrive to the client. The other requests and responses must be ignored after the first post request and the first response goes to the client.
Thanks for the help!!
CPrakash82
All-Star
18270 Points
2839 Posts
Re: Handling several post requests from the same Form
Jan 26, 2013 05:56 PM|LINK
Its a bad design.
Just disable button till you are getting the response.
Starter2
0 Points
4 Posts
Re: Handling several post requests from the same Form
Jan 26, 2013 06:20 PM|LINK
yeah. But it's a client-side solution. I need some server-side solution.
Thank you :)
ryanbesko
Contributor
3561 Points
619 Posts
Re: Handling several post requests from the same Form
Jan 26, 2013 07:40 PM|LINK
Starter2
0 Points
4 Posts
Re: Handling several post requests from the same Form
Jan 27, 2013 01:02 AM|LINK
In fact, I need some server-side validation... Client-side solution are not a problem. I did a small sample of the problem.
Here is my viewModel and the Controller:
public class ViewModel { public int? Id { get; set; } public string Name { get; set; } } public class HomeController : Controller { [HttpGet] public ActionResult Index() { Session["FirstPostRequestExecuted"] = false; return View(new ViewModel()); } [HttpPost] public ActionResult Index(ViewModel viewModel) { if ((bool)Session["FirstPostRequestExecuted"]) { // I need to ignore the post requests that come after the first post request } else { Thread.Sleep(5000); // some heavy task here viewModel.Id = 1; viewModel.Name = "Some name"; Session["FirstPostRequestExecuted"] = true; } return View(viewModel); } }And here my view:
@model UniquePostSample.Controllers.ViewModel @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Index</title> </head> <body> <div> @using (Html.BeginForm()) { @Html.DisplayTextFor(r=>r.Id) @Html.DisplayTextFor(r=>r.Name) <input type="submit" /> } </div> </body> </html>So, I want to click a couple of times on the submit button and get the informations of my viewModel to be shown on the page, i. e., just the first response of the first request is taken into account. In the sample, the last response is sent to the client.
If you run this sample, when you click twice on the submit button, the viewModel fields are not shown. I also do not want to use Session or even TempData to save the ViewModel on the server memory. I am searching for a clean server-side solution.
Thank you guys for the attention :)
CPrakash82
All-Star
18270 Points
2839 Posts
Re: Handling several post requests from the same Form
Jan 27, 2013 12:19 PM|LINK
Move this up before the heavy task so that you will know task has started and processing is happening.
ActionFilter is your friend, you can design one to check if this is a HttpPost and then assign the value in session and check the same value next time when post happens, something like below,
public class BlockMultiplePostAttribute: IAuthorizationFilter { public void OnAuthorization(AuthorizationContext authorizationContext) { if (authorizationContext.RequestContext.HttpContext.Request.HttpMethod == "POST") { if(authorizationContext.RequestContext.HttpContext.Session["MultiplePostCheck"]== true) { authorizationContext.Result = new EmptyResult(); return } authorizationContext.RequestContext.HttpContext.Session["MultiplePostCheck"] = true; return; } return; } }See how this works for you, you can modify this to create a unique session key by adding the Action Name from ActionDescriptor.
Starter2
0 Points
4 Posts
Re: Handling several post requests from the same Form
Jan 27, 2013 03:51 PM|LINK
I still get the same problem. The first response with the valid viewModel is kind of replaced by the last EmptyResult. Then, I get an empty page when I click more than once on the submit button.
CPrakash82
All-Star
18270 Points
2839 Posts
Re: Handling several post requests from the same Form
Jan 27, 2013 04:10 PM|LINK
ah, I realized now, it will not work and I suspect there is no way you will be able to stop this.
The best you can do is to implement PRG patter, ie Post - Redirect - Get, this way you will immideatly move the user from current page to a new page and he will not be able to submit it again, but you can not stop is completly.