2011-11-24 7 views
1

두 개의 실험적인 웹 서비스가 있습니다. 하나는 .net 웹 응용 프로그램에 포함 된 asmx입니다. 다른 하나는 웹 응용 프로그램에서 호출되는 WCF 서비스 라이브러리입니다.asmx json serialization 대 ​​wcf json serialization

asmx는 기본적으로 필요한 모든 것을 수행하지만, asmx 서비스를 만지작 거리다가 기대하는 것 이외에는 WCF가 더 좋을 것이라고 생각합니다.

예를 들어, 같은 방법이 각각 다르게 작동 : 내가 프로젝트 사이의 시간을 가지고

' 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의 기능을 수행하도록 만든 것이 아닙니다. 어떤 아이디어?

답변

1

내가 보는 방법은 특정 인터페이스 계약에 따라 WCF 서비스를 만드는 것입니다.

어떤 유형의 객체라도 지정할 수있는 경우 파이프의 양쪽 끝이 해당 인터페이스를 올바르게 구현했는지 확인하는 프로그래밍 방식이 없습니다.

WCF가 클래스 직렬화 및 비 직렬화와 관련하여 일반적으로 ASMX보다 훨씬 제한적이지만 ASMX에서 WCF로 전환하면 안정성, 유지 관리 가능성 및 생산성면에서 엄청나게 향상되었습니다.

그렇다고해서 WCF이기 때문에 WCF로 전환 할 이유가 없습니다. 자신의 상황에 맞는 이유가 무엇이라고 생각 하는지를 정확하게 확인해야합니다. 그렇다면 실제로 필요한 것만을 사용하는 대신 실제 클래스를 사용하여 테스트 케이스를 만들어 사용자의 요구를 충족하는지 확인해야합니다.

한 가지 생각해야 할 사항 : Silverlight, WPF 또는 WinForms로 작성된 자신의 .NET 응용 프로그램에서 WCF 서비스를 사용하는 경우 WCF를 사용하면 장기적으로 훨씬 쉽게 작업을 수행 할 수 있습니다. 파이프 양 끝에 동일한 비즈니스 오브젝트 클래스 코드를 공유하십시오. 그들은 구체적인 구현 직렬화 복원 될 수

사실 주석에서 정보와

업데이트, 당신은 한 추상 클래스를 직렬화 할 수 있습니다. 직렬화하려는 각 구체적인 클래스에 대해 KnownType 특성을 가진 추상 클래스를 지정하여이 작업을 수행 할 수 있습니다.

주요 문제는 서비스 인터페이스 계약이 아니며 특정 시점에서 구체적인 클래스가 필요한 것은 DataContract입니다. This link은 규칙을 설명합니다.

개체에서 상속 받고 사용하려는 클래스에 대해 알려진 유형으로 장식 된 포괄적 인 클래스를 만들 수 있습니다.

+0

감사합니다. 수정 됨. –

+0

우리는 ajax/json을 사용하여 웹 브라우저에서 서비스와 상호 작용합니다. 여러 가지 이유로 WCF와 함께 가고 싶지만 객체를 전달할 수 있어야합니다. 그것은 여전히 ​​명백한 계약입니다. WCF는 Object가 아닌 추상 조상을 전달하려는 경우에도 작동하지 않습니다. –

+1

@MarkLauter : 사실, 구체적인 구현으로 직렬화 해제 될 수있는 한 추상 클래스를 직렬화 할 수 있습니다. 직렬화하려는 각 구체적인 클래스에 대해 KnownType 특성을 가진 추상 클래스를 지정하여이 작업을 수행 할 수 있습니다. 주요 문제는 서비스 인터페이스 계약이 아니라 특정 시점에서 구체적인 클래스가 필요한 DataContract입니다. 이 링크는 규칙을 설명합니다. http://msdn.microsoft.com/en-us/library/ms733127.aspx. 당신은 객체로부터 상속받은 catchall 클래스를 만들 수 있고 사용하고자하는 클래스에 대해 알려진 타입으로 꾸며져 있습니다. –

1

우리는 원하는 유형 (우리 캐시에 저장 될 수있는 객체)에 맞는 각 유형의 List (T)를 포함하여 모든 유형을 반환하는 함수를 추가했습니다. IsCacheableAttribute를 사용하여 * .Core 어셈블리의 ICacheable 유형에 태그를 지정하는 경우 목록에 반환되므로 하드 코딩 된 KnownType 목록을 유지 관리 할 필요가 없습니다. 또한 d 속성을 추가하여 데이터를 보관합니다. 이는 Microsoft .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 

데이터를 서비스에 전달하는 경우 String을 전달하고 JavaScriptSerializer를 사용하여 역 직렬화하도록합니다. 이 방법으로 우리는 일부 복잡한 유형에 대해 "사전에 알려지지 않은 객체"동작을 유지합니다.

+0

이후 우리는 사전 동작에 대한 객체를 포기하고 알려진 유형 아이디어를 사용하여 복잡한 유형을 올바르게 전달할 수 있습니다. –

0

사소한 변경은 응용 프로그램 네임 스페이스에 대한 연결을 제거하고이 클래스를 기본 라이브러리 모음의 일부로 사용할 수 있도록합니다. 우리는 데이터를 일반적인 유형으로 변환했습니다. 이것은 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 Function