接受List 的ASP.NET Web方法失败,“Web服务方法名称无效”。

我想创建一个接受自定义对象列表的Web方法(通过jQuery / JSON传入)。

当我在本地运行网站时,一切似乎都有效。 jQuery和ASP.NET,每个人都很高兴。 但是,当我把它放在我们的一台服务器上时,它会爆炸。 在ajax请求之后,jQuery获得500错误,响应为:

System.InvalidOperationException:EditCustomObjects Web服务方法名称无效。

这是Web服务方法:

[WebMethod] public void EditCustomObjects(int ID, List CustomObjectList) { // Code here } 

我的jQuery代码(我认为不重要,因为错误似乎发生在Web服务级别):

 var data = JSON.stringify({ ID: id, CustomObjectList: customObjectList }); $.ajax({ type: "POST", url: "/manageobjects.asmx/EditCustomObjects", data: data, contentType: "application/json; charset=utf-8", async: false, dataType: "json", success: function(xml, ajaxStatus) { // stuff here } }); 

customObjectList初始化如下:

 var customObjectList = []; 

我像这样添加项目(通过循环):

 var itemObject = { ObjectTitle = objectTitle, ObjectDescription = objectDescription, ObjectValue = objectValue } customObjectList.push(itemObject); 

那么,我在这里做错了吗? 有没有更好的方法将数据数组从jQuery传递到ASP.NET Web服务方法? 有没有办法解决“Web服务方法名称无效”。 错误?

仅供参考,我在Windows Server 2003机器上运行.NET 2.0,我从这个站点获得了上述代码: http : //elegantcode.com/2009/02/21/javascript-arrays-via-jquery-ajax -to-AN-ASPNET-的webmethod /

编辑:有人要求更多关于网络服务的信息,我宁愿不提供整个class级,但这里有一点可能会有所帮助:

 [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [ScriptService] public class ManageObjects : Custom.Web.UI.Services.Service { } 

巴拉

我根据您可以直接在浏览器中访问Web服务的评论进行分组。

只是为了将自定义对象与配置隔离开来,您可以放置​​另一个服务,例如:

 [WebMethod] public static string GetServerTimeString() { return "Current Server Time: " + DateTime.Now.ToString(); } 

从客户端调用jQuery ajax调用。 如果这样做,那么它可能与您的对象有关,而不是在服务器端配置。 否则,继续查看服务器端配置跟踪。

编辑:一些示例代码:

 [WebMethod(EnableSession = true)] public Category[] GetCategoryList() { return GetCategories(); } private Category[] GetCategories() { List category = new List(); CategoryCollection matchingCategories = CategoryList.GetCategoryList(); foreach (Category CategoryRow in matchingCategories) { category.Add(new Category(CategoryRow.CategoryId, CategoryRow.CategoryName)); } return category.ToArray(); } 

以下是我发布复杂数据类型JSON值的示例

 [WebMethod] public static string SaveProcedureList(NewProcedureData procedureSaveData) { ...do stuff here with my object } 

这实际上包含了两个对象数组……我的NewProcedureData类型是在一个类中定义的。

EDIT2:

以下是我在一个实例中处理复杂对象的方法:

 function cptRow(cptCode, cptCodeText, rowIndex) { this.cptCode = cptCode; this.cptCodeText = cptCodeText; this.modifierList = new Array(); //...more stuff here you get the idea } /* set up the save object */ function procedureSet() { this.provider = $('select#providerSelect option:selected').val(); // currentPageDoctor; this.patientIdtdb = currentPatientIdtdb;// a javascript object (string) //...more object build stuff. this.cptRows = Array(); for (i = 0; i < currentRowCount; i++) { if ($('.cptIcdLinkRow').eq(i).find('.cptEntryArea').val() != watermarkText) { this.cptRows[i] = new cptRow($('.cptIcdLinkRow').eq(i).find('.cptCode').val(), $('.cptIcdLinkRow').eq(i).find('.cptEntryArea').val(), i);//this is a javscript function that handles the array object }; }; }; //here is and example where I wrap up the object function SaveCurrentProcedures() { var currentSet = new procedureSet(); var procedureData = ""; var testData = { procedureSaveData: currentSet }; procedureData = JSON.stringify(testData); SaveProceduresData(procedureData); }; function SaveProceduresData(procedureSaveData) { $.ajax({ type: "POST", contentType: "application/json; charset=utf-8", data: procedureSaveData, the rest of the ajax call... }); }; 

注意!重要信息procedureSaveData名称必须与客户端和服务器端完全匹配才能使其正常工作。 EDIT3:更多代码示例:

 using System; using System.Collections.Generic; using System.Web; namespace MyNamespace.NewProcedure.BL { ///  /// lists of objects, names must match the JavaScript names ///  public class NewProcedureData { private string _patientId = ""; private string _patientIdTdb = ""; private List _cptRows = new List(); public NewProcedureData() { } public string PatientIdTdb { get { return _patientIdTdb; } set { _patientIdTdb = value; } } public string PatientId { get { return _patientId; } set { _patientId = value; } } public List CptRows = new List(); } -------- using System; using System.Collections.Generic; using System.Web; namespace MyNamespace.NewProcedure.BL { ///  /// lists of objects, names must match the JavaScript names ///  public class CptRows { private string _cptCode = ""; private string _cptCodeText = ""; public CptRows() { } public string CptCode { get { return _cptCode; } set { _cptCode = value; } } public string CptCodeText { get { return _cptCodeText; } set { _cptCodeText = value; } } } } 

希望这可以帮助。

由于错误提到了Web方法名称的问题,我怀疑这完全是由于WSDL如何生成并映射到Web服务的问题。 我看到两个潜在的问题:

  1. ID是一个非常常见的名称,可能会被保留或可能导致冲突。 尝试将其重命名为objectId (无论如何,大写参数名称都不是.NET的标准)
  2. WSDL没有generics类型的概念。 根据生成器,为ListCustomObject[]生成的类型名称可能与您的参数名称CustomObjectList冲突。 尝试重命名第二个参数customObjects

或许这里还有一些其他愚蠢的框架问题。 在任何情况下,您都应该向您的问题添加.NET生成的WSDL。 您可以通过从Web服务器下载/manageobjects.asmx?WSDL来获取WSDL XML。

您可能需要检查system.web部分中的webServices / protocols元素,并确保添加了HttpPost。 通常,本地post默认启用为开发模式,但不支持远程,这是在服务器上部署服务时的情况……

  ...       

我在这里详细介绍

也许您使用jquery传递的路径不存在尝试使用FireBug查看响应。

每当我遇到这些类型的错误(在本地但不在服务器上工作)时,我会启动IIS管理工具(或者你正在使用的任何东西)并检查一切是否完全相同。 如果没有使它们相同,那么一次改变1个小东西。

根据您的角色/组织,您可能无法以这种方式访问​​服务器,但通常这些错误会归结为您从未查看的选项卡上最奇怪的随机复选框。

这是一个远景,但不能尝试。

您是否已注册所需的httpHandler以允许标记为ScriptService的Web服务?

    

这是javascript中的错误声明。

 var itemObject = { ObjectTitle = objectTitle, ObjectDescription = objectDescription, ObjectValue = objectValue } 

正确的对象初始化应该是:

 var itemObject = { ObjectTitle : objectTitle, ObjectDescription : objectDescription, ObjectValue : objectValue }; 

还可以尝试从$.ajax的参数中临时删除async: false

不得不说,我不是100%卖出我的回答是(全部)问题,但这会解决反序列化问题。 为您的特定对象添加一些细节。

在客户端:

 function itemObject (objectTitle, objectDescription ,objectValue ) { this.ObjectTitle = objectTitle,; this.ObjectDescription = objectDescription ; this.ObjectValue = objectValue ; }; // 4 objects in source-fix for your list function objRow() { this.myCode = myCode; this.myCodeText = myCodeText; this.customObjectList = new Array(); for (k = 0; k < 4; k++) { this.customObjectList [k] = new itemObject (sourceTitle[k],sourceDescription[k],sourceValue[k]); }; }; var myCode = "hicode1"; var myCodeText = "hicodeText1"; $(function() { function SaveCurrentObjects() { var currentSet = new objRow(); var objectData = ""; var testData = {objectSaveData : currentSet }; objectData = JSON.stringify(testData); SaveObjectsData(objectData ); }; /* save the objects */ function SaveObjectsData(objectSaveData) { $.ajax({ type: "POST", contentType: "application/json; charset=utf-8", data: objectSaveData, dataFilter: function(data) { var msg; if (typeof (JSON) !== 'undefined' && typeof (JSON.parse) === 'function') msg = JSON.parse(data); else msg = eval('(' + data + ')'); if (msg.hasOwnProperty('d')) return msg.d; else return msg; }, url: "/manageobjects.asmx/EditCustomObjects", success: function(msg) { //do stuff }, failure: function(msg) { //handlefail } }); }; }); 

在服务器端,您将拥有:(客户端代码中的“objectSaveData”的确切名称)。

 [WebMethod] public static string EditCustomObjects(ObjectData objectSaveData) { // code to save your object return "saved objects"; } 

创建一个ObjectData类,其中包含一个objectItem列表,类似于我匹配对象的其他示例(注意名称)。

注意:我安装了ASP.NET ajax扩展 - 为此示例使用asp.net 2.0代码。

好吧,这是一个对象,它只是测试了这个:==================================== ======== ASPX ==================================

  $("#btngeMethodCallWithAnObjectAsAParameter").click(function (event) { $.ajax({ type: 'POST', url: 'Default.aspx/PageMethodCallWithAnObjectAsAParameter', data: '{"id":"' + '5' + '", "jSonAsset":' + JSON.stringify(new BuildJSonAsset()) + '}', contentType: "application/json; charset=utf-8", dataType: "json", success: function (msg) { if (msg.d) { alert(msg.d); } }, error: function () { alert("Error! Try again..."); } }); }); }); function BuildJSonAsset() { this.AssetId = '100'; this.ContentId = '200'; this.AssetName = 'Asset1'; } 

================================================== ======================

 [WebMethod()] public static string PageMethodCallWithAnObjectAsAParameter(int id, JSonAsset jSonAsset) { return "Success!"; } 

================================================== ====================

这适用于单个对象,接下来我将尝试一个对象列表:)

确保在课程顶部有这个

 [ScriptService] <--- this bit :D public class Surveyors : WebService 

还检查了你所有的parathesis,resharper对我有点疯狂,需要一段时间来检查。

此外,如果你有很多webmethods,尝试创建一个基本的hello world webservice,确保它实际上在第一个工作,然后你可以从那里进行故障排除。

祝好运。