接受 List<CustomObject> 的 ASP.NET Web 方法因“Web 服务方法名称无效”而失败。
Posted
技术标签:
【中文标题】接受 List<CustomObject> 的 ASP.NET Web 方法因“Web 服务方法名称无效”而失败。【英文标题】:ASP.NET Web Method that accepts a List<CustomObject> is failing with "Web Service method name is not valid." 【发布时间】:2011-01-14 14:38:11 【问题描述】:我想创建一个接受自定义对象列表(通过 jQuery/JSON 传入)的 Web 方法。
当我在本地运行网站时,一切似乎都正常。 jQuery 和 ASP.NET,每个人都很高兴。但是当我把它放在我们的一台服务器上时,它就炸了。 jQuery 在 ajax 请求后收到 500 错误,响应为:
System.InvalidOperationException:EditCustomObjects Web 服务方法名称无效。
这是网络服务方法:
[WebMethod]
public void EditCustomObjects(int ID, List<CustomObject> 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 Service 方法名无效”。错误?
仅供参考,我在 Windows Server 2003 机器上运行 .NET 2.0,我从这个站点获得了上述代码:http://elegantcode.com/2009/02/21/javascript-arrays-via-jquery-ajax-to-an-aspnet-webmethod/
编辑:有人要求提供有关网络服务的更多信息,我宁愿不提供整个课程,但这里有更多可能会有所帮助:
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ScriptService]
public class ManageObjects : Custom.Web.UI.Services.Service
巴拉
【问题讨论】:
你能发布你完整的网络服务课程吗?至少是方法的父作用域? 我宁愿不发布整个 Web 服务,但请参阅上面的编辑以获取有关 Web 服务初始化的更多信息。 首先检查生产服务器上是否确实存在该方法确实。转到http://mysite.com/manageobjects.asmx
看看它列出了哪些方法。
确实存在,我已经查过了。
【参考方案1】:
我根据cmets做出假设,你可以直接在浏览器中访问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> category = new List<Category>();
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 类型是在一个类中定义的。
编辑2:
这是我在一个实例中处理复杂对象的方法:
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
/// <summary>
/// lists of objects, names must match the JavaScript names
/// </summary>
public class NewProcedureData
private string _patientId = "";
private string _patientIdTdb = "";
private List<CptRows> _cptRows = new List<CptRows>();
public NewProcedureData()
public string PatientIdTdb
get return _patientIdTdb;
set _patientIdTdb = value;
public string PatientId
get return _patientId;
set _patientId = value;
public List<CptRows> CptRows = new List<CptRows>();
--------
using System;
using System.Collections.Generic;
using System.Web;
namespace MyNamespace.NewProcedure.BL
/// <summary>
/// lists of objects, names must match the JavaScript names
/// </summary>
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;
希望这会有所帮助。
【讨论】:
服务中的其他方法工作正常(通过 AJAX 和 URL)。但是,您之前的假设是不正确的。当我通过 URL 访问该网站时,无论是否传入数据,都会收到我最初帖子中提到的错误。 Firebug 在提交 AJAX 请求后告诉我同样的错误。 太好了,所以我们知道它与实际数据有关,而不是一般的 Web 服务/配置问题。所以,我们需要序列化数据结构。我没有使用你的结构,但使用了我在类中定义的数组和复杂类型... 是否可以使用 CustomObject 数组而不是您所描述的 List? 例如,我使用了 MyObjectList.ToArray();使用如下方法: public MyObject [] GetMyObjectList()....return MyObjectList.ToArray(); 我尝试传入一个数组而不是一个列表: public void EditCustomObjects(int ID, CustomObject[] CustomObjectList) 但得到了同样的错误。我创建了一个包含 CustomObject 数组的新类,然后将 EditCustomObjects 方法设置为接受该类的对象,但我又遇到了同样的错误。但是,我不确定我是否完全理解您的建议。NewProcedureData 中究竟包含什么?【参考方案2】:由于错误提到了 Web 方法名称的问题,我怀疑这完全是由于 WSDL 的生成和映射到 Web 服务的问题。我看到两个潜在的问题:
ID
是一个非常常见的名称,可能会被保留或可能导致冲突。尝试将其重命名为 objectId
(无论如何,大写的参数名称不是 .NET 的标准)
WSDL 没有泛型类型的概念。根据生成器的不同,为List<CustomObject>
或CustomObject[]
生成的类型名称可能与您的参数名称CustomObjectList
冲突。请尝试重命名您的第二个参数 customObjects
。
或者这里可能还有其他一些愚蠢的框架问题。在任何情况下,您都应该将 .NET 生成的 WSDL 添加到您的问题中。您可以通过从 Web 服务器下载 /manageobjects.asmx?WSDL 来获取 WSDL XML。
【讨论】:
我删除了 ID 并重命名了我的列表,但它并没有解决问题。下次有机会我会看看 WSDL(明天早上)。 太棒了。另外,请尝试发布CustomObject
类定义。【参考方案3】:
您可能需要检查 system.web 部分中的 webServices/protocols 元素并确保添加了 HttpPost。通常情况下,本地发布默认启用为开发模式,但不用于远程,这是服务部署在服务器上时的状态...
<system.web>
...
<webServices>
<protocols>
<add name="HttpPost" />
</protocols>
</webServices>
</system.web>
我会详细介绍here
【讨论】:
我的 Web.Config 中已经有 HttpPost 和 HttpGet。在访问 Web 服务的 URL 时,我仍然遇到同样的错误。【参考方案4】:也许您使用 jquery 传递的路径不存在尝试使用 FireBug 查看响应。
【讨论】:
@Bara - 您确认 ajax 请求生成的 URL 存在吗? 是的,网址绝对存在。【参考方案5】:每当我遇到这类错误(在本地而不是在服务器上工作)时,我都会启动 IIS 管理工具(或您正在使用的任何工具)并检查一切是否完全相同。如果不能使它们相同,则一次更改一件小事。
根据您的角色/组织,您可能无法以这种方式访问服务器,但这些错误通常归结为您从未看过的选项卡上最奇怪的随机复选框。
这是一个很长的尝试,但不能帮助尝试。
【讨论】:
不幸的是,我在本地运行的是 IIS7,而服务器是 IIS6,所以这种检查不是很实用,甚至是不可能的。我想我可以尝试将网站放在不同的服务器上。 您在 IIS6 机器上运行了任何其他 Web 服务吗?该问题可能与 IIS 的不同版本有关。如果可能的话,我会尝试在 IIS7 服务器上获取它。 我们计划在未来移动该网站,但目前它必须保持原状。我不确定那台机器上是否有任何其他网络服务,但我倾向于没有。【参考方案6】:您是否注册了允许标记为 ScriptService 的 web 服务所需的 httpHandler?
<httpHandlers>
<add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</httpHandlers>
【讨论】:
这是我的 web.config 中的内容:。我应该删除它的“/ws/”部分吗? 是的,删除 /ws/,除非您的服务位于路径 /ws/manageobjects.asmx 我删除了 /ws/,但不幸的是没有帮助。【参考方案7】:这是 javascript 中的错误声明。
var itemObject =
ObjectTitle = objectTitle,
ObjectDescription = objectDescription,
ObjectValue = objectValue
正确的对象初始化应该是:
var itemObject =
ObjectTitle : objectTitle,
ObjectDescription : objectDescription,
ObjectValue : objectValue
;
还可以尝试从$.ajax
的参数中临时删除async: false
。
【讨论】:
是的,没错。我从内存中编写了这段代码,但我知道正确的方法是什么。无论如何,问题不在于 javascript,而在于 asp.net 网络方法。如前所述,仅访问该方法的 URL 就会出现主题中提到的错误。【参考方案8】:不得不说,我不是 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";
创建一个包含 objectItem 列表的 ObjectData 类,类似于我匹配对象的其他示例(注意名称)。
注意:我安装了 ASP.NET ajax 扩展 - 在本示例中使用 asp.net 2.0 代码。
【讨论】:
以前试过这个,没用。得到同样的错误。还尝试在 ObjectData 中使用数组而不是列表,但没有成功。但是,我没有安装 ASP.NET ajax 扩展。我不确定我是否只想为这个问题安装它们。【参考方案9】:好的,这是一个对象的情况,刚刚测试了这个: ==============================================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!";
================================================ ========================
这适用于单个对象,接下来我将尝试一个对象列表:)
【讨论】:
【参考方案10】:确保您在班级中名列前茅
[ScriptService] <--- this bit :D
public class Surveyors : WebService
同时检查你所有的parathesis,resharper对我有点疯狂,检查了一段时间。
此外,如果您有许多 webmethod,请尝试创建一个基本的 hello world webservice,首先确保它确实可以正常工作,然后您可以从那里进行故障排除。
祝你好运。
【讨论】:
以上是关于接受 List<CustomObject> 的 ASP.NET Web 方法因“Web 服务方法名称无效”而失败。的主要内容,如果未能解决你的问题,请参考以下文章
在数据表中使用 List<CustomObject> 时出现 NumberFormatException
<UUID,CustomObject>的Java排序图[重复]
将 Set<CustomObject> 存储到 UserDefaults