Wrapping JsonResults in ASP.NET MVC

Like a lot of web developers I like to load page content dynamically but this can cause problems if the Ajax request causes an error on the server. Timeouts can be handled in jQuery but what if the user needs to see more details about the error? This is simple to do if the dynamic content is wrapped inside a JSON object. Here’s an example:

The JSON object I use looks like this:

{
  successful: bool,
  html: string,
  errorMessage: string,
  redirect: string
}

Here’s the JsonResponse class for wrapping the dynamic content.

public class JsonResponse
{
    public bool Successful { get; set; }
    public string Html { get; set; }
    public string ErrorMessage { get; set; }
    public string Redirect { get; set; }

    private JsonResponse()
    { }

    public static JsonResponse Success()
    {
        return Success(null);
    }

    public static JsonResponse Success(string html)
    {
        return new JsonResponse
        {
            Successful = true,
            Html = html
        };
    }

    public static JsonResponse Error(string errorMessage)
    {
        return new JsonResponse
        {
            Successful = false,
            Html = errorMessage
        };
    }

    public static JsonResponse RedirectTo(string url)
    {
        return new JsonResponse
        {
            Successful = true,
            Redirect = url
        };
    }
}

Here’s an example of returning the object from a controller action:

public class HomeController : Controller
{
    [HttpPost]
    public JsonResult SuccessTest()
    {
        return Json(JsonResponse.Success("<p>All done!</p><br />"));
    }

    [HttpPost]
    public JsonResult RedirectTest()
    {
        return Json(JsonResponse.RedirectTo("/another/page"));
    }

    [HttpPost]
    public JsonResult ErrorTest()
    {
        return Json(JsonResponse.Error("Something went wrong"));
    }
}

How can you return a view?

Ion Drimba has written an excellent article on how to render a view as a string. His article can be found here.

What if the request times-out?

An Ajax timeout is easy to detect using jQuery. Here’s an example with a 30 second timeout which uses also assumes the use of the JsonResponse wrapper:

$.ajax({
    type: "POST",
    url: '/basket/buy',
    data: data,
    timeout: 30000,
    success: function (response) {
        if (response.Successful)
            window.location.href = response.Redirect;
        else
            // TODO: Show an error using response.ErrorMessage
    },
    error: function (request, status, err) {
        if (status === "timeout")
            toastr.error('There was a timeout');
        else
            toastr.error('There was a problem retrieving your results');
    }
});

Can the JavaScript properties be Camel Cased?

While the examples above don’t require this, it’s nice to have the JavaScript properties appear as Camel Case. ASP.NET MVC doesn’t do this by default so here’s a link to help.

Displaying toast notifications

John Papa and Hans Fjällemark have created an excellent JavaScript script for displaying UI toast notifications for Success, Error and Information. The Nuget page for ‘toastr’ can be found here.

Advertisements
This entry was posted in Reference, Tips and Tricks and tagged , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s