WebService中方法返回值类型名称的天坑
-
星级:★★☆☆☆
-
说明:此坑由于场景特殊,遇到的概率并不大,属于平时貌不惊人,一踩深不见底之坑,因此评价两星。
-
场景:哼次哼次的根据需求写完WebService,每个Webservice方法都返回对应的类型,包括调用结果、失败信息、各个业务信息,一眼看过去就是高大上。编译一次性通过!完美,结果一运行,报错!下面show代码!
1 /// <summary> 2 /// TestWebService 的摘要说明 3 /// </summary> 4 [WebService(Namespace = "http://tempuri.org/")] 5 [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] 6 [System.ComponentModel.ToolboxItem(false)] 7 // 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消对下行的注释。 8 [System.Web.Script.Services.ScriptService] 9 public class TestWebService : System.Web.Services.WebService 10 { 11 12 [WebMethod] 13 public HelloWordResponse HelloWord(string name) 14 { 15 return new HelloWordResponse() { IsSuccess = true, Message = "OK" , Other = "OTHER" }; 16 } 17 } 18 19 public class CheckIntegralRequest 20 { 21 public string Name { get; set; } 22 } 23 24 public class HelloWordResponse 25 { 26 public bool IsSuccess { get; set; } 27 public string Message { get; set; } 28 public string Other { get; set; } 29 }
-
错误信息:
来自命名空间“http://tempuri.org/”的 XML 元素“HelloWordResponse”引用了某个方法和类型。请使用 WebMethodAttribute 更改该方法的消息名称,或使用 XmlRootAttribute 更改该类型的根元素。
说明: 执行当前 Web 请求期间,出现未处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。
异常详细信息: System.InvalidOperationException: 来自命名空间“http://tempuri.org/”的 XML 元素“HelloWordResponse”引用了某个方法和类型。请使用 WebMethodAttribute 更改该方法的消息名称,或使用 XmlRootAttribute 更改该类型的根元素。
源错误:
执行当前 Web 请求期间生成了未处理的异常。可以使用下面的异常堆栈跟踪信息确定有关异常原因和发生位置的信息。 |
堆栈跟踪:
[InvalidOperationException: 来自命名空间“http://tempuri.org/”的 XML 元素“HelloWordResponse”引用了某个方法和类型。请使用 WebMethodAttribute 更改该方法的消息名称,或使用 XmlRootAttribute 更改该类型的根元素。] System.Xml.Serialization.XmlReflectionImporter.ReconcileAccessor(Accessor accessor, NameTable accessors) +864647 System.Xml.Serialization.XmlReflectionImporter.ImportElement(TypeModel model, XmlRootAttribute root, String defaultNamespace, RecursionLimiter limiter) +370 System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(Type type, XmlRootAttribute root, String defaultNamespace) +97 System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(Type type, XmlRootAttribute root) +10 System.Web.Services.Description.MimeXmlReflector.ReflectReturn() +270 System.Web.Services.Description.HttpProtocolReflector.ReflectMimeReturn() +83 System.Web.Services.Description.HttpPostProtocolReflector.ReflectMethod() +30 System.Web.Services.Description.ProtocolReflector.ReflectBinding(ReflectedBinding reflectedBinding) +1798 System.Web.Services.Description.ProtocolReflector.Reflect() +703 System.Web.Services.Description.ServiceDescriptionReflector.ReflectInternal(ProtocolReflector[] reflectors) +394 System.Web.Services.Description.ServiceDescriptionReflector.Reflect(Type type, String url) +109 System.Web.Services.Protocols.DocumentationServerType..ctor(Type type, String uri) +156 System.Web.Services.Protocols.DocumentationServerProtocol.Initialize() +284 System.Web.Services.Protocols.ServerProtocol.SetContext(Type type, HttpContext context, HttpRequest request, HttpResponse response) +50 System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type, HttpContext context, HttpRequest request, HttpResponse response, Boolean& abortProcessing) +77 [InvalidOperationException: 无法处理请求。] System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type, HttpContext context, HttpRequest request, HttpResponse response, Boolean& abortProcessing) +285 System.Web.Services.Protocols.WebServiceHandlerFactory.CoreGetHandler(Type type, HttpContext context, HttpRequest request, HttpResponse response) +183 [InvalidOperationException: 处理请求失败。] System.Web.Services.Protocols.WebServiceHandlerFactory.CoreGetHandler(Type type, HttpContext context, HttpRequest request, HttpResponse response) +354 System.Web.Services.Protocols.WebServiceHandlerFactory.GetHandler(HttpContext context, String verb, String url, String filePath) +212 System.Web.Script.Services.ScriptHandlerFactory.GetHandler(HttpContext context, String requestType, String url, String pathTranslated) +47 System.Web.HttpApplication.MapHttpHandler(HttpContext context, String requestType, VirtualPath path, String pathTranslated, Boolean useAppConfig) +193 System.Web.MapHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +93 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155 |
-
排坑过程:
- 观察错误信息及堆栈信息,发现关于XML的序列化有问题,于是猜想难道是类没声明序列化?于是又哼次哼次给每个类及属性加上相应的XMLRootAttribute/XMLElementAttribute等,结果运行还是报错。失败!
- 问度娘!作为一个合格的程序员,排障除BUG问度娘基本等同于电脑有问题重启,可解决90%的问题,结果很遗憾这次错误在关键的10%中!!
- 度娘不给力,只能自己瞎琢磨了,几经苦思冥想,最终我想啊,既然说元素HelloWordResponse引用了某个为声明XMLAttribute的方法和类型,而我只有这个类是这个命名,那我干脆换个名字试试吧!就改成HelloWordResult吧!结果一试!成了!!!居然成了!!!当时只想大喊一声“我擦咧,微软这是给我挖了多大一个坑啊!!”
-
坑内奇景:
在运行生成WebSerivce的WSDL时有一套潜规则,即以【方法名+Response】来作为WSDL中方法的返回类型,而我们创建的返回类型名跟其重名,导致XML序列化混乱而报错。
-
触发条件:
在写DEMO重现此问题时,发现触发条件比较奇特,除了返回参数类型名外,方法的请求参数需为简单类型,即int,string之类的,如请求参数也为复杂类型,则无此问题,这个估计跟WSDL的生成规则有关系了,今天较晚就不深究了,错误代码:
[WebMethod] public HelloWordResponse HelloWord(string name) { return new HelloWordResponse() { IsSuccess = true, Message = "OK" , Other = "OTHER" }; }

浙公网安备 33010602011771号