jquery with ASP.NET MVC - calling ajax enabled web service

jquery with ASP.NET MVC - calling ajax enabled web service

This is a bit of a continuation of a previous question.

Now I'm trying to make a call to an AJAX enabled web service which I have defined within the ASP.NET MVC application (i.e. the MovieService.svc). But the service is never being called in my getMovies javascript function.

This same technique of calling the AJAX web service works ok if I try it in a non ASP.NET MVC application, so it makes me wonder if maybe the ASP MVC routes are interfering with things somehow when it tries to make the AJAX web service call.

Do you have any idea why my web service isn't getting called? Code below.

    <script src="<%= ResolveClientUrl("~/scripts/jquery-1.4.2.min.js") %>" type="text/javascript"></script>      <script src="<%= ResolveClientUrl("~/scripts/grid.locale-en.js") %>" type="text/javascript"></script>      <script src="<%= ResolveClientUrl("~/scripts/jquery-ui-1.8.1.custom.min.js") %>"         type="text/javascript"></script>      <script src="<%= ResolveClientUrl("~/scripts/jquery.jqGrid.min.js") %>" type="text/javascript"></script>      <script type="text/javascript">         var lastsel2;          function successFunction(jsondata) {             debugger             var thegrid = jQuery("#editgrid");             for (var i = 0; i < jsondata.d.length; i++) {                 thegrid.addRowData(i + 1, jsondata.d[i]);             }         }          function getMovies() {             debugger             // ***** the MovieService#GetMovies method never gets called             $.ajax({                 url: 'MovieService.svc/GetMovies',                 data: "{}",  // For empty input data use "{}",                 dataType: "json",                 type: "GET",                 contentType: "application/json; charset=utf-8",                 success: successFunction             });         }          jQuery(document).ready(function() {             jQuery("#editgrid").jqGrid({                 datatype: getMovies,                 colNames: ['id', 'Movie Name', 'Directed By', 'Release Date', 'IMDB Rating', 'Plot', 'ImageURL'],                 colModel: [                   { name: 'id', index: 'Id', width: 55, sortable: false, hidden: true, editable: false, editoptions: { readonly: true, size: 10} },                   { name: 'Movie Name', index: 'Name', width: 250, editable: true, editoptions: { size: 10} },                   { name: 'Directed By', index: 'Director', width: 250, align: 'right', editable: true, editoptions: { size: 10} },                   { name: 'Release Date', index: 'ReleaseDate', width: 100, align: 'right', editable: true, editoptions: { size: 10} },                   { name: 'IMDB Rating', index: 'IMDBUserRating', width: 100, align: 'right', editable: true, editoptions: { size: 10} },                   { name: 'Plot', index: 'Plot', width: 150, hidden: false, editable: true, editoptions: { size: 30} },                   { name: 'ImageURL', index: 'ImageURL', width: 55, hidden: true, editable: false, editoptions: { readonly: true, size: 10} }                 ],                 pager: jQuery('#pager'),                 rowNum: 5,                 rowList: [5, 10, 20],                 sortname: 'id',                 sortorder: "desc",                 height: '100%',                 width: '100%',                 viewrecords: true,                 imgpath: '/Content/jqGridCss/redmond/images',                 caption: 'Movies from 2008',                 editurl: '/Home/EditMovieData/',                 caption: 'Movie List'             });              $("#bedata").click(function() {                 var gr = jQuery("#editgrid").jqGrid('getGridParam', 'selrow');                 if (gr != null)                     jQuery("#editgrid").jqGrid('editGridRow', gr, { height: 280, reloadAfterSubmit: false });                 else                     alert("Hey dork, please select a row");             });                      });      </script>      <h2>         <%= Html.Encode(ViewData["Message"]) %></h2>     <p>         To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">             http://asp.net/mvc</a>.     </p>     <table id="editgrid">     </table>     <div id="pager" style="text-align: center;">     </div>     <input type="button" id="bedata" value="Edit Selected" /> 

Here's my RegisterRoutes code:

public static void RegisterRoutes(RouteCollection routes) {     routes.IgnoreRoute("{resource}.axd/{*pathInfo}");     routes.IgnoreRoute("*MovieService.svc*");      routes.MapRoute(         "Default",                                              // Route name         "{controller}/{action}/{id}",                           // URL with parameters         new { controller = "Home", action = "Index", id = "" }  // Parameter defaults     ); } 

Here's what my MovieService class looks like:

namespace jQueryMVC {     [ServiceContract(Namespace = "")]     [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]     public class MovieService     {         // Add [WebGet] attribute to use HTTP GET         [OperationContract]         [WebGet(ResponseFormat = WebMessageFormat.Json)]         public IList<Movie> GetMovies()         {             return Persistence.GetMovies();         }      } } 

“this” in function parameter


Failing to connect to Database due to database in recovery
Your main problem is this you use not complete URLs in the ajax call. Partial view postback from a standard Html form with MVCWrong entries in web.config must make also problems. Using a .NET MVC Controller Action as the Source for an HTML <img>Moreover you use datatype: receive Movies instead of datatype: 'json' and postData: yourData. ASP.NET MVC: How do I validate a model wrapped in a ViewModel?The way with datatype as functions exist (see http://www.trirand.com/jqgridwiki/doku.php?id=wiki:retrieving_data#function), although since jqGrid 3.6.5 you have more direct way inside of jsonReader to read the data returned from web server.. ASP.NET MVC Rich Text Editor not showing buttons UPDATED: It seems to me this describing of editing features I'll make later and explain here just how to receive JSON data and fill there inside of jqGrid.. Is there a template language for ASP.NET MVC like JSTL and OGNL? First of all jqGrid must request itself the JSON data from the server. Selling upper management on converting to ASP.NET from Classic ASPSo i don’t need to make a separate jQuery.ajax call. You need only define a URL which point to the server and define any additional jQuery.ajax parameters which you prefer. You don’t post in your question the definition of the Movie class. So I define it myself like following.
public class Movie {     public int Id { receive ; set; }     public string Name { receive ; set; }     public string Director { receive ; set; }     public string ReleaseDate { receive ; set; }     public string IMDBUserRating { receive ; set; }     public string Plot { receive ; set; }     public string ImageURL { receive ; set; } } 
You should remark, this Microsoft serialize DataTime type not as a readable date string although as a string /Date(utcDate)/, where utcDate is this number (see http://stackoverflow.com/questions/2794633/jquery-param-doesnt-serialize-javascript-date-objects/2794836#2794836). To make fewer problems at the beginning I define ReleaseDate as string. . Method IList<Movie> GetMovies() returns JSON data like an array of objects Movie. So jqGrid as a response to HTTP GET request receive from the MovieService.svc/GetMovies URL the data like following:.
 [{"Id":1, "Name": "E.T.", "Director": "Steven Spielberg",...},{...},...] 
I must say this it is not typical format of data, which are waiting jqGrid (compare with http://www.trirand.com/jqgridwiki/doku.php?id=wiki:retrieving_data#json_data). To be able to place the data inside of jqGrid i need define a jsonReader. So i did following.
jQuery("#editgrid").jqGrid({     url: '<%= Url.Content("~/MovieService.svc/GetMovies")%>',     datatype: 'json',     ajaxGridOptions: { contentType: "application/json" },     jsonReader: { repeatitems: false, id: "Id", root: function(obj) { return obj; }},     headertitles: true,     sortable: true,     colNames: ['Movie Name', 'Directed By', 'Release Date',                'IMDB Rating', 'Plot', 'ImageURL'],     colModel: [         { name: 'Name', width: 250},         { name: 'Director', width: 250, align: 'right' },         { name: 'ReleaseDate', width: 100, align: 'right' },         { name: 'IMDBUserRating', width: 100, align: 'right' },         { name: 'Plot', width: 150 },         { name: 'ImageURL', width: 55, hidden: true }     ],     pager: jQuery('#pager'),     pginput: false,     rowNum: 0,     height: '100%',     viewrecords: true,     rownumbers: true,     caption: 'Movies from 2008' }).jqGrid('navGrid', '#pager', { add: false, edit: false, del: false, search: false }); 
REMARK: I remove from the case any sorting parameters, for the reason this in case of request of JSON data, the sorting parameter will be only send to server (any additional parameters append the server URL) and server need commit back sorted data. For more information see description of prmNames parameter on http://www.trirand.com/jqgridwiki/doku.php?id=wiki:options and description of sopt parameter on http://www.trirand.com/jqgridwiki/doku.php?id=wiki:singe_searching.. With respect of datatype: 'json' i define dataType: 'json' parameter of jQuery.ajax (don’t confuse the case inside of datatype parameter). The names of all fields inside of colModel i define exact the same as the field names inside our JSON objects. Some additional parameters viewrecords, rownumbers, sortable and headertitles are not very important in this example, I choosed there for the reason this 1) I like there and 2) I set rowNum: 0 to make possible the options rownumbers: true works correct and not show us negative row numbers started with -5 if rowNum: 5 like in your original example.. With ajaxGridOptions: { contentType: "application/json" } i define additional parameters which will be direct forwarded to the jQuery.ajax.. The most complex part of this case is .
jsonReader: { repeatitems: false, id: "Id", root: function(obj) { return obj; }} 
It defines this id of all rows have the name "Id" (see definition of the class Movie). "repeatitems: false" say this every data field i want identify by the field name (defined in colModel) instead of default definition per position. The definition of root is a little strange, although it defines how to find the root of rows inside of JSON data. Default format of JSON data is following.
{   total: "xxx",    page: "yyy",    records: "zzz",   rows : [     {id:"1", cell:["cell11", "cell12", "cell13"]},     {id:"2", cell:["cell21", "cell22", "cell23"]},       ...   ] } 
and the root of rows are defined as root: "rows". So if the JSON data assigned to the variable res, the root must be returned as res.rows. To allow jqGrid to read our data i define jsonReader.root as a function (this feature exist since jqGrid 3.6.5 see http://www.trirand.com/jqgridwiki/doku.php?id=wiki:change#additions_and_changes). You must verify this this strange method work. The typical additional parameters page, total (lastpage) and records are not exist inside of our JSON data and they will be initialized as following page:0, total:1, records:0. So i are not able to make data paging. You must expand jsonReader with functions defining page, total and records (also as functions) like.
jsonReader: {     repeatitems: false,     id: "Id",     root: function (obj) { return obj; },     page: function (obj) { return 1; },     total: function (obj) { return 1; },     records: function (obj) { return obj.length; } } 
which will complete our jsonReader. Then setting of rowNum: 0 will not more needed.. I showed this way only to show the flexibility of jqGrid. You should use described way only if you access a web server which you cannot change. jqGrid has features like paging, sorting and two kind of searching (more as filtering with WHERE in the corresponding SELECT) of data: simple and advanced. If i want have these nice features inside of jqGrid on our web pages i should define in Web Service an additional method like.
[OperationContract] [WebGet(ResponseFormat = WebMessageFormat.Json,         UriTemplate = "jqGridGetTestbereiche?_search={_search}&page={page}&"+                       "rows={rows}&sidx={sortIndex}&sord={sortDirection}&"+                       "searchField={searchField}&searchString={searchString}&"+                       "searchOper={searchOper}&filters={filters}")] public jqGridTable jqGridGetMovies(   int page, int rows, string sortIndex, string sortDirection,   string _search, string searchField, string searchString,   string searchOper, string filters) 
where jqGridTable.
public class jqGridTable {     public int total { receive ; set; }      // total number of pages     public int page { receive ; set; }       // current zero based page number     public int records { receive ; set; }    // total number of records     public List<jqGridRow> rows { receive ; set; } } public class jqGridRow {     public string id { receive ; set; }     public List<string> cell { receive ; set; } } 
Or if i want use the most compact form of data transferred from server to client then.
// jsonReader: { repeatitems : true, cell:"", id: "0" } public class jqGridTable {     public int total { receive ; set; }          // total number of pages     public int page { receive ; set; }           // current zero based page number     public int records { receive ; set; }        // total number of records     public List<List<string>> rows { receive ; set; }// first element in every row need be id of row. } 
(you must read more around this kind of data transfer on http://www.trirand.com/blog/jqgrid/jqgrid.html if you choose on the left tree part "Data Mapping" and then "Data Optimization"). P.S.: About jsonReader you must read more on http://www.trirand.com/jqgridwiki/doku.php?id=wiki:retrieving_data#json_data. One my old answer http://stackoverflow.com/questions/2690657/mapping-json-data-in-jqgrid/2706620#2706620 must be also interesting for you.. UPDATED 2: Because you don't mark the answer as accepted, you stay have any problems. So I created a new Project in Visual Studio 2010 which demonstrate what I written. You must download the source from http://www.ok-soft-gmbh.com/jqGrid/jQueryMVC.zip. Compare with your project, especially the part with full url as a parameter of jqGrid and a part of web.config which describes WCF service interface.. UPDATED 3: I use VS2010 not so long time. So I could very quickly downgrade this to VS2008. So almost the same code working working in Visual Studio 2008, although with ASP.NET MVC 2.0 you must download from http://www.ok-soft-gmbh.com/jqGrid/VS2008jQueryMVC.zip. The code in ASP.NET MVC 1.0 should be the same, although a GUID from the project file and any strings from Web.config should be patched (see http://www.asp.net/learn/whitepapers/aspnet-mvc2-upgrade-notes). .


That is for the reason this the registered route in the global.asax, will not be recognizing this .svc file. it will try to search for this controller with the action receive movies and will fail. try out debugging using firebug. you must fix this by ignoring this route in the global.asax.


I encountered the same issue. I came to the conclusion this the routes were interfering with the service call. Have you tried Phil Haack's Route Debugger? It's saved my bacon a couple times.. In the ended, I created an endpoint off one of the controllers. .


Oleg,. Do you have the case you were talking around as i am working with jqgrid/asp.net mvc and a restful service and having a bugger of a time. It would guidance out seeing an case as i am at a wall. Thx. SEM.

79 out of 100 based on 49 user ratings 1099 reviews