我有两个实验性的web服务。一种是包含在.net web应用程序中的asmx。另一个是从web应用程序调用的WCF服务库。
asmx基本上做了我需要的所有事情,但我认为WCF会更好,除了在摆弄了asmx服务之后,它没有做我所期望的任何事情。
例如,相同的方法在每个方法中的行为都不同:
' ASMX
<WebMethod(BufferResponse:=True, EnableSession:=False)>
Function Test(aObject as Object) as Object
' object will have been successfully serializaed into a dictionary
Dim lResult as SomeObject = new SomeObject(aObject)
return lResult ' lResult will be serialized as whatever type it is and will be deserialized by client making ajax call
End Function
' WCF
<OperationContract()>
<WebInvoke(RequestFormat:=ServiceModel.Web.WebMessageFormat.Json,
ResponseFormat:=ServiceModel.Web.WebMessageFormat.Json,
BodyStyle:=WebMessageBodyStyle.Wrapped)>
Function Test(aObject As Object) As Object
' object is serialized as an empty instance of Object
' not very useful
Dim lResult as SomeObject = new SomeObject(aObject) ' waste of time with useless object
return lResult ' even if lResult could be instantiated the client returns error 500 because
' WCF won't serialize SomeObject as Object
End Function几个月来,我一直在断断续续地研究这个问题,因为我在两个项目之间有时间。我没有尝试过让WCF做ASMX做的事情。有什么想法吗?
发布于 2011-11-24 12:25:31
在我看来,您可以为特定的接口契约创建WCF服务。
如果您只能指定任何类型的对象,那么就没有编程机制来验证管道的任何一端是否正确地实现了该接口。
我发现WCF在类序列化和反序列化方面通常比ASMX有更多的限制,但是从ASMX切换到WCF在稳定性、可维护性和生产力方面极大地改进了我们的应用程序。
话虽如此,没有理由仅仅因为WCF是WCF就切换到WCF。您需要准确地确定为什么您认为它对您的情况更好,如果是这样,那么您需要使用实际的类而不仅仅是对象来创建一些测试用例,以验证它是否满足您的需求。
需要考虑的一件事是:如果您在用Silverlight、WPF或WinForms编写的.Net应用程序中使用WCF服务,那么从长远来看,WCF将使您的工作变得容易得多,因为它使得在管道的两端共享相同的业务对象类代码成为可能。
使用来自comments的信息更新
实际上,您可以序列化抽象类,只要它们可以反序列化为具体的实现。您可以通过为要序列化的每个具体类的KnownType属性赋予抽象类属性来完成此操作。
主要的问题不是服务接口契约,而是DataContract在某些时候需要一个具体的类。This link描述了规则。
您可以创建一个从object继承的catchall类,并用要使用的类的已知类型进行修饰。
发布于 2011-11-30 09:37:27
我们添加了一个函数来返回所有类型,包括每个类型的列表( T),这些类型符合我们想要的标准-可能存储在缓存中的对象。只要我们用IsCacheableAttribute标记*.Core程序集中的ICacheable类型,它们就会在列表中返回,我们不需要一个难以维护的硬编码KnownType列表。我们还添加了属性d来保存数据,希望这对浏览器/客户端的安全性起到了与微软.d相同的作用。
Imports System.Reflection
Imports OurCompany.Cache
Imports OurApplication.Core
<DataContract(), KnownType("AllTypes")>
Public Class Data
Private Shared mCacheableType As Type = GetType(ICacheable)
Private Shared mIsCachedAttribute As Type = GetType(IsCacheableAttribute)
<DataMember()>
Public Property d As Object
Private Shared Function AllTypes() As IEnumerable(Of Type)
Return GetCacheableTypesFromAssembly(GetType(AssemblyKeyClass).Assembly)
End Function
Private Shared Function GetCacheableTypesFromAssembly(aAssembly As Assembly) As IEnumerable(Of Type)
Dim lTypes As List(Of Type) = aAssembly.GetTypes().Where(Function(t) IsCacheable(t)).ToList
Dim lTypes2 As List(Of Type) = New List(Of Type)
lTypes2.AddRange(lTypes)
For Each lType In lTypes2
Dim lListType As Type = GetType(List(Of )).MakeGenericType({lType})
lTypes.Add(lListType)
Next
Return lTypes
End Function
Private Shared Function IsCacheable(aType As Type) As Boolean
Dim lResult As Boolean = False
If aType.GetInterfaces.Contains(mCacheableType) Then
Dim lAttribute As Object() = aType.GetCustomAttributes(mIsCachedAttribute, True)
If lAttribute.Count = 1 Then
lResult = DirectCast(lAttribute(0), IsCacheableAttribute).Value
End If
End If
Return lResult
End Function
End Class下面是我们用来测试返回各种类型数据的IService方法。
<OperationContract()>
<WebInvoke(RequestFormat:=ServiceModel.Web.WebMessageFormat.Json,
ResponseFormat:=ServiceModel.Web.WebMessageFormat.Json,
BodyStyle:=WebMessageBodyStyle.Bare)>
Function Test() As Data至于将数据传递给服务,我们将坚持传递一个字符串并使用JavaScriptSerializer对其进行反序列化。这样,我们就保留了一些复杂类型所依赖的“未知对象到字典”的行为。
发布于 2011-12-02 05:32:22
较小的更改移除了与应用程序名称空间的耦合,并允许我们将该类用作基库集合的一部分。我们将数据转换为泛型类型。这肯定胜过成百上千次输入KnownType(GetType(YetAnotherClass)),然后每次我们向系统添加一个新的json可传输类。
<DataContract(), KnownType("AllTypes")>
Public NotInheritable Class Data(Of T)
Private Shared Function AllTypes() As IEnumerable(Of Type)
Return GetSerializableTypesFromAssembly(GetType(T).Assembly)
End Functionhttps://stackoverflow.com/questions/8251480
复制相似问题