Tag Archive: javascript


A breaking change in ASP.NET 4.0 causes a javascript error to be thrown on a page if a query string has a “potentially unsafe” character, such as an apostrophe in a last name.

You’ll see the error (possibly only while debugging): “A potentially dangerous Request.QueryString value was detected from the client” when passing the special character in a query string in a button click or a jqgrid’s FillGrid postData BuildGrigArgs function.

The fix is easy:  set the behavior back to ASP.NET 2.0 in the web.config with this line in the system.web section right below your </compilation> tag (the requestPathInvalidCharacters parameter here blocks everything except a single quote):

 <httpRuntime requestPathInvalidCharacters="&lt;,&gt;,*,%,:,&amp;,\" requestValidationMode="2.0" />

And in your pages be sure you don’t encode the parameter in the MVC code in your javascript (i.e. you’ll need to use <%= instead of <%: for those parameters that need special characters). 

For example, this:

    function BuildPreviousArgs() {   

            var args = new Object();

            args.FilterLastName = "<%: Model.FilterLastName %>";

            return $.param(args);

        }

Has to be changed to this:

    function BuildPreviousArgs() {   

            var args = new Object();

            args.FilterLastName = "<%= Model.FilterLastName %>";

            return $.param(args);

        }

The ParentError.aspx page described earlier tries to close the popup browser window after passing the error to the parent page. If the javascript just calls window.close(), Internet Explorer prompts the user if they want to allow the page to close. With the following code, the window will close without a prompt and it works in both IE and Firefox:

// close the window without a prompt in both IE and Firefox
window.open('', '_self');
window.close();

JQuery’s ajax function is automatically caching data

FYI: If you are using jquery’s ajax function , be aware that it is automatically caching the data. Normally this is a good thing, but if you want to do a get, then modify the database, and then get the data again, the ajax method won’t try to hit your controller action and will go straight to the success callback function returning the cached value. This will make it appear to the user that the update hasn’t occurred. To turn off caching in your ajax function call, simply add the “cache: false” setting. (normally you want to leave this to “true”, so use it only where necessary)

Example:

How to send a business object from a jquery ajax call to an MVC.NET controller action

If you need to send more than one value to a controller action from an ajax call, you can wrap those values together into a business object and send that to the controller action. Jquery automagically maps your javascript object to your controller action’s business object. If you’ve sent a fill-grid object from a jqgrid call, you may notice that the syntax is very similar. Here’s how:

In your ajax call be sure your type is Get, your url is set to your dynamically generated MVC controller action, and in your “data” property call a BuildGridObject javascript function, like this:

function LoadSender() {
  $.ajax({
    url: '',
    success: function(data) {
      // fill the ddl with the data from the json call
      var ddl = $('#ddlTransferTo');
      optionArray = [];
      $.each(data, function(i, option) {
        optionArray[i] = "<option value="&quot; + option.Value + &quot;">" + option.Disp + "</option>";
      });
      ddl.children().remove();
      ddl.append(optionArray.join(''));
    },
    data: BuildGridObject (),
    type: "GET",
    dataType: 'json'
  });
}

In your BuildGridObject function, create a new object and assign the values to the properties you want to send to the controller action. In this example, selected values are pulled from a drop down list. Note: your javascript object won’t have intellisense for the properties of your business object, so you’ll have to copy/paste them manually into the javascript object. Like this:

function BuildGridObject (){
    var objToSend = new Object();
    objToSend.TransferFrom = $('#ddlTransferFrom').val();
    objToSend.TransferTo = $('#ddlRegion').val();
    return objToSend;
}

Create your business object in the usual place, like this:

namespace Models
{
    public class Transfer
    {
        public long TransferTo{ get; set; }
        public long TransferFrom { get; set; }
    }
}

Finally, make sure your controller action accepts the business object in its parameter, like this:

[AcceptVerbs(HttpVerbs.Get)]
public JsonResult GetList(Transfer transfer)
{
    try
    {
        returnJson(myBLL.GetScreenerList(transfer.TransferTo, transferTo.TransferFrom));
    }
    catch (Exception ex)
    {
        return HandleError(ex, null);
    }
}

How to make a parent/child drop down list using JQuery

If you need to make a drop down list populate based on the selection of another drop down list, here’s one way.

· You’ll want to use a jquery ajax call so it does proper error handling (using the default error delegate we built in a previous email).

· Make sure the datatype of your ajax call is json and that your controller action returns a JsonResult.

· Use jquery show/hide to hide the child drop down list on page load and show it when the user makes a selection from the parent drop down list.

· In the ajax success function, you will:

o Add options to your select control (a.k.a. drop down list) using jquery’s each statement. Note: the “option” object in the each function delegate is not strongly typed, so you will just need to know your CV properties and type them in manually (sorry, no intellisense for that). For example, if you return a List of DDLDispValueCVs in your BLL method, your option object’s properties will be “Disp” and “Value”.

o Then bind a change event handler to your select control that calls the load function for your second select control.

o Wrap the functions with jquery block/unblockUI calls so the user sees a soothing “In Progress…” popup while the ajax calls are filling the drop down lists.

Here’s an example of the view page:

<script type="text/javascript">
    $(document).ready
    (
        function()
        {
            $('#divTransferTo').hide();
            $.ajax
            (
                {
                    url: '<%= Url.Content("~/MyController/GetList") %>',
                    success: function(data) {
                        // fill the ddl with the data from the json call
                        var ddl = $('#ddlTransferFrom');
                        optionArray = [];
                        $.each(data, function(i, option) {
                            optionArray[i] = "<option value='" + option.Value + "'>" + option.Display + "</option>";
                        });
                        ddl.append(optionArray.join(''));
                        // bind an "on selected change" event to the ddl
                        ddl.change
                        (
                            function() {
                                $.blockUI({ message: $('#information'), css: { width: '275px'} });
                                LoadTransferToDDL($(this).val());
                                $.unblockUI();
                            }
                        );
                    },
                    dataType: 'json'
                }
           );
        }
    );
     function LoadTransferToDDL(id)
    {
        $('#divTransferTo').show();
        var transferToUrl = '<%= Url.Content("~/MyController/GetOtherList") %>';
        $.ajax
        (
            {
                url: transferToUrl + '/' + id,
                success: function(data)
                {
                    $('#ddlTransferTo').vis
                                       // fill the ddl with the data from the json call
                    var ddl = $('#ddlTransferTo');
                    optionArray = [];
                    $.each(data, function(i, option)
                    {
                        optionArray[i] = "<option value='" + option.Value + "'>" + option.Display + "</option>";
                    });
                    ddl.append(optionArray.join(''));
                     // bind an "on selected change" event to the ddl
                    ddl.change
                    (
                        function()
                        {
                            $.blockUI({ message: $('#message'), css: { width: '275px'} });
                            alert('You selected this value: ' + $(this).val());
                            $.unblockUI();
                        }
                    );
                },
                dataType: 'json'
            }
       );
    }</script>
<form id="mvcForm" method="post" action="">
    <h2>Reassign Something</h2>
Transfer From:
    <div id="divTransferFrom"><select id="ddlTransferFrom"></select></div>
Transfer To:
    <div id="divTransferTo"><select id="ddlTransferTo"></select></div>
</form>

Here’s an example of the controller actions used by the ajax calls. Notice that the Json method built into MVC.Controller automagically converts your list of cvs into json:

[AcceptVerbs(HttpVerbs.Get)]
public JsonResult GetList()
{
 try 
{
  return Json(myBLL.GetList());
 }
 catch (Exception ex)
 {
  return HandleError(ex, null);
 }
}

[AcceptVerbs(HttpVerbs.Get)]
public JsonResult GetOtherList(object id)
{
 try 
{
  return Json(myBLL.GetOtherList(Convert.ToInt64(id)
 }
 catch (Exception ex)
 {
  return HandleError(ex, null); 
}
}
© 2017 Robert Corvus