调用启用了Ajax的Web服务
这是前一个问题的延续。
现在我试图调用一个在ASP.NET MVC应用程序(即MovieService.svc
)中定义的支持AJAX的Web服务。 但是我的getMovies
javascript函数永远不会调用这个服务。
如果我在非ASP.NET MVC应用程序中尝试调用AJAX Web服务,这种调用AJAX Web服务的相同技术仍然可以正常工作,所以它让我怀疑当尝试使AJAX Web服务调用时,ASP MVC路由可能会干扰某些事情。
你有什么想法为什么我的Web服务没有被调用? 下面的代码。
<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" />
这是我的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
);
}
以下是我的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
中读取从Web服务器返回的数据。
更新:在我看来,编辑功能的描述,我会稍后做,并在这里解释如何获取JSON数据,并填写里面的jqGrid。
首先,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; }
}
你应该说,微软序列化的DataTime
类型不是一个可读的日期字符串,但作为一个字符串/Date(utcDate)/
,其中utcDate
是这个数字(请参阅jQuery.param() - 不序列化JavaScript日期对象?)。 为了在开始时减少问题,我将ReleaseDate
定义为字符串。
方法IList<Movie> GetMovies()
返回JSON数据,如对象Movie
数组。 因此,作为对HTTP GET
请求的响应, MovieService.svc/GetMovies
从MovieService.svc/GetMovies
URL接收如下数据:
[{"Id":1, "Name": "E.T.", "Director": "Steven Spielberg",...},{...},...]
我可以说这不是数据的典型格式,它们正在等待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 });
备注 :我从示例中删除了任何排序参数,因为在请求JSON数据的情况下,排序参数将仅发送给服务器(一些附加参数附加服务器URL),服务器必须返回排序数据。 欲了解更多信息,请参阅的说明prmNames
上http://www.trirand.com/jqgridwiki/doku.php?id=wiki:options参数和说明sopt
参数上http://www.trirand.com/jqgridwiki/doku。 PHP ID =维基:singe_searching。
关于datatype: 'json'
我们定义了jQuery.ajax
dataType: 'json'
参数(不要混淆datatype
参数内部的情况)。 colModel
的所有字段的名称都与我们的JSON对象中的字段名称完全相同 。 一些额外的参数viewrecords
, rownumbers
, sortable
和headertitles
在这个例子中并不是非常重要,我选择这里是因为1)我喜欢那里,2)我设置了rowNum: 0
使选项rownumbers: true
成为可能rownumbers: true
works rownumbers: true
correct,not show negative如果您的原始示例中有rowNum: 5
则以-5开头的行数。
使用ajaxGridOptions: { contentType: "application/json" }
我们定义了附加参数,这些参数将被直接转发到jQuery.ajax
。
这个例子中最复杂的部分是
jsonReader: { repeatitems: false, id: "Id", root: function(obj) { return obj; }}
它定义所有行的id都具有名称“Id”(请参阅class Movie
定义)。 “ repeatitems: false
”表示我们希望通过字段名称(在colModel
定义)来标识每个数据字段,而不是每个位置的默认定义。 root
的定义有点奇怪,但它定义了如何在JSON数据中找到行的根 。 JSON数据的默认格式如下
{
total: "xxx",
page: "yyy",
records: "zzz",
rows : [
{id:"1", cell:["cell11", "cell12", "cell13"]},
{id:"2", cell:["cell21", "cell22", "cell23"]},
...
]
}
并且行的根被定义为root: "rows"
。 所以如果分配给变量res
的JSON数据,根可以作为res.rows
返回。 为了让jqGrid读取我们的数据,我们将jsonReader.root
定义为一个函数(自jqGrid 3.6.5开始存在这个特性,参见http://www.trirand.com/jqgridwiki/doku.php?id=wiki:change#additions_and_changes)。 你可以验证这个奇怪的方法工作。 典型的附加参数page
, total
( lastpage
)和records
不存在于我们的JSON数据中,它们将被初始化为如下page:0, total:1, records:0
。 所以我们无法进行数据分页。 您可以使用定义page
, total
和records
(也作为函数)的函数来扩展jsonReader
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
将不再需要。
我以这种方式展示了jqGrid的灵活性。 只有在访问无法更改的Web服务器时,才应使用描述的方式。 jqGrid具有诸如分页,排序和两种搜索(更多地用相应的SELECT中的WHERE过滤)数据的特性:简单和高级。 如果我们希望在我们的网页上使用jqGrid中的这些好功能,我们应该在Web Service中定义一个额外的方法
[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)
其中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; }
}
或者,如果我们想要使用从服务器传输到客户端的最紧凑形式的数据,那么
// 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上阅读有关此类数据传输的更多信息)
PS:关于jsonReader,您可以在http://www.trirand.com/jqgridwiki/doku.php?id=wiki:retrieving_data#json_data上阅读更多内容。 我的旧回答在JQGrid中映射JSON数据对你来说也很有趣。
更新2 :因为你没有将答案标记为已接受,你仍然有一些问题。 所以我在Visual Studio 2010中创建了一个新项目,演示了我所写的内容。 您可以从http://www.ok-soft-gmbh.com/jqGrid/jQueryMVC.zip下载源代码。 与您的项目比较,特别是将完整url作为jqGrid的参数和描述WCF服务接口的web.config的一部分。
更新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应该打补丁(参见http://www.asp.net/learn/whitepapers/aspnet-mvc2-升级-NOTES)。
这是因为global.asax中的注册路由不会识别这个.svc文件。 它会尝试用动作getmovies搜索该控制器,并将失败。 尝试使用萤火虫调试。 你可以通过忽略global.asax中的这个路由来解决这个问题
我遇到了同样的问题。 我得出这样的结论:路线干扰了服务电话。 你有没有试过Phil Haack的Route Debugger? 它保存了我的培根几次。
最后,我从其中一个控制器创建了一个终端。
链接地址: http://www.djcxy.com/p/25943.html