带有 ASP.NET MVC 的 jquery - 调用支持 ajax 的 Web 服务 [英] jquery with ASP.NET MVC - calling ajax enabled web service

查看:19
本文介绍了带有 ASP.NET MVC 的 jquery - 调用支持 ajax 的 Web 服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是上一个问题的延续.

现在我正在尝试调用我在 ASP.NET MVC 应用程序(即 MovieService.svc)中定义的支持 AJAX 的 Web 服务.但是在我的 getMovies javascript 函数中永远不会调用该服务.

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.

如果我在非 ASP.NET MVC 应用程序中尝试调用 AJAX Web 服务的相同技术,则它可以正常工作,因此我想知道 ASP MVC 路由在尝试创建 AJAX 时是否会以某种方式干扰事物网络服务调用.

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" />

<input type="button" id="bedata" value="Edit Selected"/>

Here's my RegisterRoutes code:

这是我的 RegisterRoutes 代码:

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:

这是我的 MovieService 类的样子:

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(); } } }


推荐答案

您的主要问题是您在 ajax 调用中使用的不是绝对 URL.web.config 中的错误条目也会导致问题.此外,您使用 datatype: getMovies 而不是 datatype: 'json'postData: yourData.使用 datatype 作为函数的方式存在(见 http://www.trirand.com/jqgridwiki/doku.php?id=wiki:retrieving_data#function),但从 jqGrid 3.6.5 开始,您在 jsonReader读取从网络服务器返回的数据.

UPDATED: It seems to me that describing of editing features I'll make later and explain here just how to get JSON data and fill there inside of jqGrid.

更新:在我看来,我将在稍后进行编辑功能的描述,并在这里解释如何获取 JSON 数据并将其填充到 jqGrid 中.

First of all jqGrid can request itself the JSON data from the server. So we don’t need to make a separate jQuery.ajax call. You need only define a URL which point to the server and define some 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

首先,jqGrid 可以向自己请求来自服务器的 JSON 数据.所以我们不需要进行单独的 jQuery.ajax 调用.您只需要定义一个指向服务器的 URL 并定义一些您喜欢的附加 jQuery.ajax 参数.您没有在问题中发布 Movie 类的定义.所以我自己定义如下

public class Movie { public int Id { get; set; } public string Name { get; set; } public string Director { get; set; } public string ReleaseDate { get; set; } public string IMDBUserRating { get; set; } public string Plot { get; set; } public string ImageURL { get; set; } }

You should remark, that Microsoft serialize DataTime type not as a readable date string but as a string /Date(utcDate)/, where utcDate is this number
(see jQuery.param() - doesn't serialize javascript Date objects?). To make fewer problems at the beginning I define ReleaseDate as string. 

您应该注意,Microsoft 序列化 DataTime 类型不是作为可读的日期字符串,而是作为字符串 /Date(utcDate)/,其中 utcDate是这个数字(参见 jQuery.param() - 不序列化 javascript 日期对象?).为了在开始时减少问题,我将 ReleaseDate 定义为字符串.

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:

方法<代码>IList<电影>GetMovies() 返回 JSON 数据,就像一个对象数组 Movie.因此,jqGrid 作为对 HTTP GET 请求的响应从 MovieService.svc/GetMovies URL 接收如下数据:

[{"Id":1, "Name": "E.T.", "Director": "Steven Spielberg",...},{...},...]

I can say that 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 we must define a jsonReader. So we do following

我可以说它不是典型的数据格式,它正在等待 jqGrid(与 http://www.trirand.com/jqgridwiki/doku.php?id=wiki:retrieving_data#json_data).为了能够将数据放入 jqGrid,我们必须定义一个 jsonReader.所以我们做以下

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 example any sorting parameters, because in case of request of JSON data, the sorting parameter will be only send to server (some additional parameters append the server URL) and server must give 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.

备注:我从示例中删除了任何排序参数,因为在请求 JSON 数据的情况下,排序参数将只发送到服务器(一些附加参数附加到服务器 URL)和服务器必须返回排序的数据.有关详细信息,请参阅 上的 prmNames 参数说明http://www.trirand.com/jqgridwiki/doku.php?id=wiki:options 以及 http://www.trirand.com/jqgridwiki/doku.php?id=wiki:singe_searching.>

关于 datatype: 'json' 我们定义了 jQuery.ajaxdataType: 'json' 参数(不要混淆datatype 参数中的 case).colModel 中所有字段的名称我们定义的 exact 与 JSON 对象中的字段名称相同.一些附加参数 viewrecordsrownumberssortableheadertitles 在这个例子中不是很重要,我选择那里是因为1) 我喜欢那里 2) 我设置 rowNum: 0 以使选项 rownumbers: true 工作正确并且不向我们显示以 -5 开头的负行号如果 rowNum: 5 就像你原来的例子一样.

With respect of datatype: 'json' we define dataType: 'json' parameter of jQuery.ajax (don’t confuse the case inside of datatype parameter). The names of all fields inside of colModel we 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 because 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.

使用 ajaxGridOptions: { contentType: "application/json" } 我们定义了额外的参数,这些参数将直接转发到 jQuery.ajax.

With ajaxGridOptions: { contentType: "application/json" } we define additional parameters which will be direct forwarded to the jQuery.ajax.

这个例子中最复杂的部分是

The most complex part of this example is

jsonReader: { repeatitems: false, id: "Id", root: function(obj) { return obj; }}

它定义了所有行的 id 都具有名称Id"(参见 类 Movie 的定义)."repeatitems: false" 表示我们想要通过字段名称(在 colModel 中定义)而不是每个位置的默认定义来识别每个数据字段.root 的定义有点奇怪,但它定义了如何在 JSON 数据中找到 rowsroot.JSON 数据默认格式如下

It defines that id of all rows have the name "Id" (see definition of the class Movie). "repeatitems: false" say that every data field we want identify by the field name (defined in colModel) instead of default definition per position. The definition of root is a little strange, but 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"]},
      ...
  ]
}

和行的根定义为 root: "rows".因此,如果将 JSON 数据分配给变量 res,则根可以作为 res.rows 返回.为了允许 jqGrid 读取我们的数据,我们将 jsonReader.root 定义为一个函数(此功能自 jqGrid 3.6.5 开始存在,请参阅 http://www.trirand.com/jqgridwiki/doku.php?id=wiki:change#additions_and_changes).您可以验证这种奇怪的方法是否有效.典型的附加参数 pagetotal (lastpage) 和 records 在我们的 JSON 数据中不存在,它们将被初始化为如下 page:0, total:1, records:0.所以我们无法进行数据分页.您可以使用定义 pagetotalrecords(也作为函数)的函数来扩展 jsonReader,如

and the root of rows are defined as root: "rows". So if the JSON data assigned to the variable res, the root can be returned as res.rows. To allow jqGrid to read our data we 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 can verify that 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 we are not able to make data paging. You can 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; }
}

这将完成我们的 jsonReader.那么rowNum: 0的设置就不再需要了.

which will complete our jsonReader. Then setting of rowNum: 0 will not more needed.

我展示这种方式只是为了展示jqGrid的灵活性.仅当您访问无法更改的 Web 服务器时,才应使用描述的方式.jqGrid 具有分页排序和两种搜索(更多是在相应的SELECT中用WHERE过滤)数据的功能:简单和高级.如果我们希望在我们的网页上的 jqGrid 中有这些不错的功能,我们应该在 Web Service 中定义一个额外的方法,如

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 we want have these nice features inside of jqGrid on our web pages we 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 { get; set; }      // total number of pages
    public int page { get; set; }       // current zero based page number
    public int records { get; set; }    // total number of records
    public List<jqGridRow> rows { get; set; }
}
public class jqGridRow
{
    public string id { get; set; }
    public List<string> cell { get; set; }
}

或者,如果我们想使用从服务器传输到客户端的最紧凑形式的数据,那么

Or if we 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 { get; set; }          // total number of pages
    public int page { get; set; }           // current zero based page number
    public int records { get; set; }        // total number of records
    public List<List<string>> rows { get; set; }// first element in every row must be id of row.
}

(您可以在 http://www.trirand.com/blog/jqgrid/jqgrid.html 如果您在左侧树部分选择数据映射",然后选择数据优化")

(you can read more about 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")

PS:关于 jsonReader,您可以在 http://www.trirand.com/jqgridwiki/doku.php?id=wiki:retrieving_data#json_data.我的一个旧答案 在 JQGrid 中映射 JSON 数据 也很有趣你.

P.S.: About jsonReader you can read more on http://www.trirand.com/jqgridwiki/doku.php?id=wiki:retrieving_data#json_data. One my old answer Mapping JSON data in JQGrid can be also interesting for you.

更新 2:因为您没有将答案标记为已接受,所以您仍然存在一些问题.所以我在 Visual Studio 2010 中创建了一个新项目来演示我所写的内容.您可以从 http://www.ok-soft-gmbh 下载源代码.com/jqGrid/jQueryMVC.zip.和你的项目对比一下,特别是jqGrid的参数为full url的部分,以及web.config中描述WCF服务接口的部分.

UPDATED 2: Because you don't mark the answer as accepted, you stay have some problems. So I created a new Project in Visual Studio 2010 which demonstrate what I written. You can 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:我使用 VS2010 的时间不长.所以我可以很快将其降级到 VS2008.所以几乎相同的代码在 Visual Studio 2008 中工作,但使用 ASP.NET MVC 2.0,您可以从 http://www.ok-soft-gmbh.com/jqGrid/VS2008jQueryMVC.zip.ASP.NET MVC 1.0 中的代码应该是相同的,但是应该修补项目文件中的 GUID 和 Web.config 中的一些字符串(请参阅 http://www.asp.net/learn/whitepapers/aspnet-mvc2-upgrade-notes).

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, but with ASP.NET MVC 2.0 you can download from http://www.ok-soft-gmbh.com/jqGrid/VS2008jQueryMVC.zip. The code in ASP.NET MVC 1.0 should be the same, but a GUID from the project file and some strings from Web.config should be patched (see http://www.asp.net/learn/whitepapers/aspnet-mvc2-upgrade-notes).

这篇关于带有 ASP.NET MVC 的 jquery - 调用支持 ajax 的 Web 服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆