views:

30

answers:

1

if i call a ajax request using jquery to an asp.net mvc controller action and inside that action an exception gets thrown, what is the best way to capture that and show something to the user.

right now my loading image just goes on forever . . . .

here is an example of my controller code:

  public ActionResult BatchAdd(int[] sharepointKeys)
  {
           MyViewModel vm = GetViewModel();
            return PartialView("MyPartialView", vm);
  }
+3  A: 

c#

public JsonResult Action(...)
{
    bool error = false;
    string msg = "";
    var data = "your data";

    try
    {
       //you code
    }
    catch (Exception ex)
    {
        error = true;
        msg = "Error ...";
    }

    return Json(new { error = error, msg = ms, data = data });
}

js:

$.ajax({
   type: "POST",
   url: "Controller/Action",
   data: "...",
   beforeSend: function(xhr){
        $("#showError").empty();
   },
   error: function(xhr, ts, et){
        $("#showError").append("<div>Error</div>");
   },
   success: function(response){

     if (response.error) {
        $("#showError").append("<div>"+response.msg+"</div>");
     } 
     else {
        // code ok response
     }


   }
 });

With return ActionResult:

Index.asp:

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    Home Page
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

    <div id="showError"></div>
    <div id="dataHtml"></div>

    <button id="example">Example</button>
    <script type="text/javascript">

        $(function () {

            $("#example").bind('click', function (ex) {

                $.ajax({
                    type: "POST",
                    url: "Home/BatchAdd",
                    data: { sharepointKeys: [1, 2, 3] },
                    beforeSend: function (xhr) {
                        $("#showError").empty();
                    },
                    error: function (xhr, ts, et) {
                        $("#showError").append("<div>Error</div>");
                    },
                    success: function (response) {

                        if ($(response).find("#error-message").length > 0) {
                            $("#showError").append("<div>" + $(response).find("#error-message").html() + "</div>");
                        }
                        else {
                            $("#dataHtml").html("<div>" + $(response).find("#container-response-ok").html() + "</div>");
                        }


                    }
                });
            });

        });

    </script>

</asp:Content>

Site.master:

<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml"&gt;
<head runat="server">
    <title><asp:ContentPlaceHolder ID="TitleContent" runat="server" /></title>
    <link href="../../Content/Site.css" rel="stylesheet" type="text/css" />
    <script src="../../Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
</head>

<body>
    <div class="page">

        <div id="header">

            <div id="menucontainer">
                <ul id="menu">              
                    <li><%= Html.ActionLink("Home", "Index", "Home")%></li>
                    <li><%= Html.ActionLink("About", "About", "Home")%></li>
                </ul>
            </div>
        </div>

        <div id="main">
            <asp:ContentPlaceHolder ID="MainContent" runat="server" />
            <div id="footer"></div>
        </div>
    </div>
</body>
</html>

MyPartialView.ascx:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<MvcApplication1.Controllers.MyViewModel>" %>
<div>
    <% if (Model.Error)
    { %>
    <div id="error-message"><%= Model.Message %></div>
    <% } else { %>
    <div id="container-response-ok">
      <div> all ok </div>
    </div>
    <% } %>
</div>

HomeController.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MvcApplication1.Controllers
{
    [HandleError]
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            ViewData["Message"] = "Welcome to ASP.NET MVC!";

            return View();
        }

        public ActionResult BatchAdd(int[] sharepointKeys)
        {
            MyViewModel vm = GetViewModel();

            try
            {
                vm.Error = true;
                vm.Message = "Error testing";
            }
            catch (Exception ex)
            {
                vm.Error = true;
                vm.Message = "Errro";
            }

            return PartialView("MyPartialView", vm);
        }

        public ActionResult About()
        {
            return View();
        }

        private MyViewModel GetViewModel()
        {
            return (new MyViewModel());
        }
    }



    public class MyViewModel
    {
        public bool Error { get; set; }
        public string Message { get; set; }

        public MyViewModel()
        {
            this.Error = false;
            this.Message = "";
        }
    }

}
andres descalzo
+1 , nice and clean.
jim
@andres descalzo - right now i am returning a PartialResult (which obviously is html) so how can i support that will still supporting the exception respon
ooo
Could you give an example of how you're returning now with ajax
andres descalzo
@andres descalzo - i updated the question
ooo
@andres descalzo - i just added an Error property to my model . . .
ooo