views:

449

answers:

1

I want to be able to check the form inputs prior to launching a long running asynchronous task.

Two approaches that come to mind:

  1. Check values on the Begin method and throw an exception?
  2. Post to a normal (synchronous method) which validates as per normal. redirects to the asynchonrous method if no errors found.

Throwing an exception i thought would be a simple solution. I can't return the view from the begin method, so the exception is handled on the end method. Only it isn't getting across to the end method (I thought this was the normal pattern)

Validating in a normal synchronous method is fine... but how do i transfer or redirect the request to the asynchronous method???

A: 

You don't need to use exceptions or a synchronous method, you can just pass back a different IAsyncResult (assuming that's the pattern you're using - if you're using the event or delegate patterns, you'd still be able to achieve something similar without exceptions).

Here's a simple example of this where we use a dummy delegate to return if there's an error (in this case an invalid ID):

public class MyAsyncController : AsyncController
{
    public IAsyncResult BeginFoo(int id, AsyncCallback callback, object state)
    {
        Action errorDelegate = () => ViewData["errors"] = "Invalid ID";
        // Here's our validation check, return the error delegate if necessary
        if (id <= 0) return errorDelegate.BeginInvoke(callback, state);

        var webRequest = WebRequest.Create("http://www.apple.com");
        return webRequest.BeginGetResponse(callback, webRequest);
    }

    public ActionResult EndFoo(IAsyncResult asyncResult)
    {
        if (asyncResult.AsyncState is WebRequest)
        {
            var webRequest = (WebRequest) asyncResult.AsyncState;
            var httpResponse = (HttpWebResponse) webRequest.EndGetResponse(asyncResult);
            ViewData["status"] = httpResponse.StatusCode;
        }
        return View();
    }
}
Michael Hart