views:

193

answers:

2

I'm trying to combine 2 parts of MVC that I haven't seen used together: 1) Ajax and 2) Error handling. The problem lies in what is returned and where (div element to update) that it's returned.

I have an ASP.net MVC page that looks like the following

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<Store>" %>

<div id="MainPage>
  <div id="Some Stuff>
    Lorem Ipsum
  </div>
  <div id="CustomerList>
    <% Html.RenderPartial("~/Views/Customers/List.ascx", Model.Customers); %>
  </div>
  <div id="dialog">
    <div id="dialogErrorMessage"></div>
  </div>
</div>

The Customers List partial view will be a table with a list of customers. Each record will have an Edit link, which will open a dialog populate it with information from Customers/Edit.ascx partial view, which will look like:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Customer>" %>
<fieldset>
<p>
<label for="CustomerName"></label>: <%= Html.TextBox("CustomerName", Model.CustomerName)) %>
</p>
<p>
<label for="CustomerAddress"></label>: <%= Html.TextBox("CustomerAddress", Model.CustomerAddress)) %>
</p>
<p>
<input id="btnSave" type="submit" value="Save" />
</p>
</fieldset>

When btnSave is clicked, it will do a post to Customers/Edit. If the update succeeds, the dialog should close and #CustomersList should refresh. However, if the update fails, the #dialog should remain open and #dialogErrorMessage should display "Update Failed, the error is blah, blah. . . ".

Here's where I'm stuck. Both the ASP.Net MVC Ajax helper methods and the jQuery library make doing an Ajax post and easily replace a div, however in most examples, the client knows which div to replace before it makes the Ajax call. In the case of my error handling example, the client doesn't know which div to update until after it learns that the update was a success. I've come up with 2 potential solutions, but both have drawbacks:

  1. Use jQuery + 2 controller actions: 1) Sends back success/fail message and, if successful, the client side code will 2) use an Ajax call to Customers/List and refresh #CustomerList.

    Pro: Straightforward. Easy to understand. Can reuse the Customers/List controller action that already exists.

    Con: Requires 2 calls to the server. At this point, performance isn't an issue, but in the past, I've worked at places where no thought is given to number of calls and it gradual creeps in as a problem that you cannot easily back out of.

  2. Use jQuery + 1 controller action. Return a JsonResult that includes both 1)success/failure and 2)the refreshed results of #CustomersList.

    Pro: 1 service call.

    Con: Complexity. #CustomersList is initially created using a partial view and a very simple controller method. Returning a Json result, it's not readily apparent how the CustomersList.ascx partial view fits into the picture.

  3. ASP.Net MVC Ajax helper methods -- I cannot see that this provides a solution at all, because it's main methodology is to update a target using UpdateTargetID.

I'm still relatively new to jQuery and doing serious Ajax programming. I know that both ways can work, but I'd like to know "why" one choice is better than other. From a lot of painful Javascript programming, I've learned from Douglas Crockford and others that the patterns of programming in Javascript are not the same as server-side C#, Java, etc.

What is the best way?

RESOLUTION

At John's recommendation, I did look into the error functionality built into jQuery's $.ajax, however there was still another piece that I was missing:

In the controller, I needed to put

     catch(Exception ex)
    {
        Response.StatusCode = 500;
        return Content("An Error occured.");
    }

Initially, I chose to just throw the exception. That forced the error to run, but what I really wanted was a custom message coming from the server and not an ASP.Net exception.

By adding the line Response.StatusCode = 500, it causes jQuery to understand that an error occured, but it also provides me with the ability to better customize what gets sents back. Here, I just chose to send a single generic error message, but in the future, I will probably make that more robust.

A: 

Simple--as part of the POST/Response cycle, pass in a variable telling the UI where to update stuff, such as the ID of the list or DIV.

Wyatt Barnett
+1  A: 

The JQuery ajax call has function handlers for both success and failure. If you throw an exception containing your failure text, then you can use one server call. The result will be a success or a failure, calling into different processing functions, which each know exactly where to show the results and how to get them from the resulting JSON object.

Take a look at http://docs.jquery.com/Ajax/jQuery.ajax to see the description of both the success and error options for the ajax() method of JQuery. (Use error, just like success.)

John Fisher
I'll look at that. Thanks.
John
It works. Thanks.
John