首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >asmx json序列化与wcf json序列化

asmx json序列化与wcf json序列化
EN

Stack Overflow用户
提问于 2011-11-24 10:11:58
回答 3查看 1.2K关注 0票数 1

我有两个实验性的web服务。一种是包含在.net web应用程序中的asmx。另一个是从web应用程序调用的WCF服务库。

asmx基本上做了我需要的所有事情,但我认为WCF会更好,除了在摆弄了asmx服务之后,它没有做我所期望的任何事情。

例如,相同的方法在每个方法中的行为都不同:

代码语言:javascript
复制
' 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做的事情。有什么想法吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 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类,并用要使用的类的已知类型进行修饰。

票数 1
EN

Stack Overflow用户

发布于 2011-11-30 09:37:27

我们添加了一个函数来返回所有类型,包括每个类型的列表( T),这些类型符合我们想要的标准-可能存储在缓存中的对象。只要我们用IsCacheableAttribute标记*.Core程序集中的ICacheable类型,它们就会在列表中返回,我们不需要一个难以维护的硬编码KnownType列表。我们还添加了属性d来保存数据,希望这对浏览器/客户端的安全性起到了与微软.d相同的作用。

代码语言:javascript
复制
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方法。

代码语言:javascript
复制
<OperationContract()>
<WebInvoke(RequestFormat:=ServiceModel.Web.WebMessageFormat.Json,
           ResponseFormat:=ServiceModel.Web.WebMessageFormat.Json,
           BodyStyle:=WebMessageBodyStyle.Bare)>
Function Test() As Data

至于将数据传递给服务,我们将坚持传递一个字符串并使用JavaScriptSerializer对其进行反序列化。这样,我们就保留了一些复杂类型所依赖的“未知对象到字典”的行为。

票数 1
EN

Stack Overflow用户

发布于 2011-12-02 05:32:22

较小的更改移除了与应用程序名称空间的耦合,并允许我们将该类用作基库集合的一部分。我们将数据转换为泛型类型。这肯定胜过成百上千次输入KnownType(GetType(YetAnotherClass)),然后每次我们向系统添加一个新的json可传输类。

代码语言:javascript
复制
<DataContract(), KnownType("AllTypes")>
Public NotInheritable Class Data(Of T)

    Private Shared Function AllTypes() As IEnumerable(Of Type)
        Return GetSerializableTypesFromAssembly(GetType(T).Assembly)
    End Function
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8251480

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档