ASMX返回类在ASPX后台代码中的转换问题求助
这个错误的核心原因很简单:你有两个完全不同的websvc_returnvalues类——一个是ASMX服务里定义的websvctest.websvc_returnvalues(通过服务引用生成的类型),另一个是你在ASPX后台自己定义的WebServiceConsume.websvc_returnvalues。虽然它们的结构和名字完全一样,但在.NET的CLR眼里,这是两个毫不相关的类型,所以直接强制转换肯定会失败。
下面是两种可行的解决方案,优先推荐第一种:
方案1:直接使用服务引用生成的类(最简洁)
当你在项目中引用ASMX服务时,Visual Studio已经自动帮你生成了服务中所有类的本地副本,包括websvc_returnvalues。你完全不需要在ASPX后台重复定义这个类,直接用生成的类型就行:
修改你的WebServiceconsume.aspx.vb代码,删掉自己定义的websvc_returnvalues类,直接使用服务引用的类型:
Partial Class WebServiceConsume Inherits System.Web.UI.Page Private websvc As New websvctest.WebServiceTest ' 移除你自己定义的websvc_returnvalues类 Private Sub form1_Load(sender As Object, e As EventArgs) Handles form1.Load ' 直接使用服务引用的类型 Dim rtnvals As websvctest.websvc_returnvalues Try rtnvals = websvc.test() ' 现在不会有编译错误了 Me.websvc_ok.Text = rtnvals.Ok.ToString Me.websvc_value.Text = rtnvals.value.ToString Me.websvc_err.Text = rtnvals.err.ToString Catch ex As Exception MsgBox(ex.Message, MsgBoxStyle.Critical, "Testing") End Try End Sub End Class
这样做的好处是完全避免了类型转换的问题,同时减少了重复代码,后续如果ASMX服务的类结构有变化,只要更新服务引用就能同步修改,不用手动维护两个类的一致性。
方案2:手动映射属性(特殊场景下使用)
如果你因为某些特殊原因必须保留ASPX后台自己的websvc_returnvalues类,那你不能用强制类型转换,而是需要手动复制每个属性的值,把服务返回的对象的属性逐个赋值给你自己定义的对象:
修改你的转换方法:
Private Function cvt_websvc_returnvalues(serviceResult As websvctest.websvc_returnvalues) As websvc_returnvalues Dim localResult As New websvc_returnvalues() ' 逐个复制属性值 localResult.Ok = serviceResult.Ok localResult.value = serviceResult.value localResult.err = serviceResult.err Return localResult End Function
然后在调用的时候使用这个方法:
rtnvals = cvt_websvc_returnvalues(websvc.test())
这种方式的核心是承认两个类是不同的类型,通过显式复制属性来完成“转换”,而不是依赖CLR的类型转换机制。
为什么强制转换不行?
.NET的类型系统是基于命名空间+类名来区分类型的,哪怕两个类的字段、属性、方法完全一样,只要它们属于不同的命名空间(或者不同的程序集),CLR就会认为它们是不同的类型,无法直接转换。你之前尝试的CType强制转换本质上是告诉CLR“把这个对象当成另一种类型”,但CLR不允许这么做,所以会抛出运行时错误。
内容的提问来源于stack exchange,提问作者Michael

