当ResponseFormat:= WebMessageFormat.Json并尝试序列化接口时发生错误(未返回任何数据) [英] Error (no data returned) when ResponseFormat:=WebMessageFormat.Json and attempting to serialize an Interface

查看:252
本文介绍了当ResponseFormat:= WebMessageFormat.Json并尝试序列化接口时发生错误(未返回任何数据)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尝试从WCF服务返回JSON数据时遇到问题.我已将问题归结为ResponseFormat:= WebMessageFormat.JSON,但无法取得任何进一步的进展.  

 

我希望我的服务的返回类型成为接口,以便对我的应用程序的响应有更多的控制.  

我知道返回接口需要在对象上使用ServiceKnownType并需要KnowsType,以便它们可以正确地序列化.我有一个工作示例,但是,当添加一个具有从iList继承的类的属性时,情况会变糟.  服务不返回任何内容.我已经通过Fiddler确认了响应的内容长度为0.但是,如果我将ResponseFormat切换为WebMessageFormat.XML,它将正常工作并返回所有对象.  我已经包括了很多 我认为有必要的代码(可能还有更多).  如果需要其他帮助,请告诉我.

任何见识都会受到赞赏.

 

代码注释:

如果在TestResult类的Values属性上注释掉DataMember属性,您将看到返回JSON时代码可以完美工作.

如果将Values属性的返回类型更改为TestCollection而不是ITestCollection,则它也可以正常工作.  

 

安迪(Andy S.)

 

< code>

 

服务界面"

 

 

< ServiceContract()> _

公共 接口 IPortalCoreService

    < OperationContract()> _

    < WebGet(UriTemplate:= " GetTest" ,ResponseFormat:= WebMessageFormat.Json,BodyStyle:= WebMessageBodyStyle.Bare)> _

     < ServiceKnownType( GetType (TestResult))> _

    函数 GetTest() As ITestResult

结束 界面

 

 

服务等级"

 

公共 PortalCoreService

    实施 IPortalCoreService

     公共 函数 GetTest() As ITestResult 实现 IPortalCoreService.GetTest

        Dim retVal As ITestResult = 新建 TestResult

        返回 retVal

    结束 功能

结束

 

 

'接口

 

公共 接口 ITestCollection

    继承 IList( Of ITest)

结束 界面

 

公共 接口 ITest

    属性 A() As 字符串

结束 界面

 

公共 接口 ITestResult

    属性 Values() As ITestCollection

    属性 Values1() As IList( Of ITest)

    属性 T() As ITest

结束 界面

 

 

班级"

 

公共 TestCollection

    继承列表( Of ITest)

    实施 ITestCollection

结束

 

 

< DataContract()> _

公共 测试

    实施 ITest

 

 

    < DataMember()> _

    公共 属性 A() As 字符串 实现 ITest.A

        获取

            返回 "A"

        结束 获取

        设置( ByVal As 字符串)

 

        结束 设置

    结束 属性

结束

 

< DataContract(),KnownType( GetType (Test)),KnownType( GetType (TestCollection))> _

公共 TestResult

    实施 ITestResult

    私有 _values As TestCollection

    公共 Sub ()

        _values = 新建 TestCollection()

        对于 i = 0 3

            _values.Add(新建测试)

        下一个

    结束 Sub

 

    < DataMember()> _

    公共 属性 TestObj() As ITest 实施 ITestResult.T

        获取

            返回 新建 Test()

        结束 获取

        设置( ByVal As ITest)

        结束 设置

    结束 属性

 

    < DataMember()> _

    公共 属性 Values() As ITestCollection 实施 ITestResult.Values

        获取

            返回 _values

        结束 获取

        设置( ByVal As ITestCollection)

        结束 设置

    结束 属性

 

    < DataMember()> _

    公共 属性 Values1() As IList( Of ITest) 实施 ITestResult.Values1

        获取

            返回 _values

        结束 获取

        设置( ByVal As IList( Of ITest))

        结束 设置

    结束 属性

结束

 

 

</code>

解决方案

更新:我发现该错误发生在System.Runtime.Serialization中. Json.XmlObjectSerializerWriteContextComplexJson.VerifyObjectCompatibilityWithInterface方法.

 如果我将WebMessageFormat切换为XML,则可以正常工作.  这是JSON序列化程序中的错误吗?

 

发生System.Runtime.Serialization.SerializationException

  Message ="'HealthMEDX.Core.Home.TestCollection'是一个收集类型,当分配给未实现IEnumerable的接口类型('HealthMEDX.Core.Home.ITestCollection'时,无法序列化. )"

   Source ="System.ServiceModel.Web"

  StackTrace:

      在System.Runtime.Serialization.Json.XmlObjectSerializerWriteContextComplexJson.VerifyObjectCompatibilityWithInterface(DataContract合同,对象图,类型为clarifiedType)

   InnerException: 



I have am having an issue when attempting to return JSON data from a WCF Service.  I have tracked the issue down to the ResponseFormat:=WebMessageFormat.JSON, but I am unable to make any further progress.  

 

I am wanting the return types of my service to be an interface so that I have a little more control over the responses that are coming to my application.  

I know that returning an interface requires the ServiceKnownType and requires KnowsType on the objects so that they can serialize properly.  I have an example working, however, when add a property with a class that inherits from iList things go bad.  The service returns nothing.  I have confirmed via Fiddler that the content-length of the response is 0.  However if I switch the ResponseFormat to WebMessageFormat.XML it works fine and all objects are returned.  I have included as much code (and probably more) as I think is necessary.  If something else is needed, let me know. 

Any insight is greatly appreciated.

 

Code Notes:

If you comment out the DataMember Attribute on the Values property in TestResult class you will see that the code works perfectly when returning JSON. 

If you change the return Type of the Values Property to be TestCollection instead of ITestCollection it works as well.  

 

Andy S.

 

<code>

 

'Service Interface

 

 

<ServiceContract()> _

Public Interface IPortalCoreService

    <OperationContract()> _

    <WebGet(UriTemplate:="GetTest", ResponseFormat:=WebMessageFormat.Json, BodyStyle:=WebMessageBodyStyle.Bare)> _

     <ServiceKnownType(GetType(TestResult))> _

    Function GetTest() As ITestResult

End Interface

 

 

'Service Class

 

Public Class PortalCoreService

    Implements IPortalCoreService

    Public Function GetTest() As ITestResult Implements IPortalCoreService.GetTest

        Dim retVal As ITestResult = New TestResult

        Return retVal

    End Function

End Class

 

 

'Interfaces

 

Public Interface ITestCollection

    Inherits IList(Of ITest)

End Interface

 

Public Interface ITest

    Property A() As String

End Interface

 

Public Interface ITestResult

    Property Values() As ITestCollection

    Property Values1() As IList(Of ITest)

    Property T() As ITest

End Interface

 

 

'Classes

 

Public Class TestCollection

    Inherits List(Of ITest)

    Implements ITestCollection

End Class

 

 

<DataContract()> _

Public Class Test

    Implements ITest

 

 

    <DataMember()> _

    Public Property A() As String Implements ITest.A

        Get

            Return "A"

        End Get

        Set(ByVal value As String)

 

        End Set

    End Property

End Class

 

<DataContract(), KnownType(GetType(Test)), KnownType(GetType(TestCollection))> _

Public Class TestResult

    Implements ITestResult

    Private _values As TestCollection

    Public Sub New()

        _values = New TestCollection()

        For i = 0 To 3

            _values.Add(New Test)

        Next

    End Sub

 

    <DataMember()> _

    Public Property TestObj() As ITest Implements ITestResult.T

        Get

            Return New Test()

        End Get

        Set(ByVal value As ITest)

        End Set

    End Property

 

    <DataMember()> _

    Public Property Values() As ITestCollection Implements ITestResult.Values

        Get

            Return _values

        End Get

        Set(ByVal value As ITestCollection)

        End Set

    End Property

 

    <DataMember()> _

    Public Property Values1() As IList(Of ITest) Implements ITestResult.Values1

        Get

            Return _values

        End Get

        Set(ByVal value As IList(Of ITest))

        End Set

    End Property

End Class

 

 

</code>

解决方案

Update: I have found that the error is occurring in the System.Runtime.Serialization.Json.XmlObjectSerializerWriteContextComplexJson.VerifyObjectCompatibilityWithInterface method.

 If I switch the WebMessageFormat to XML then it works fine.  Is this a bug in the JSON Serializer?

 

System.Runtime.Serialization.SerializationException occurred

  Message="'HealthMEDX.Core.Home.TestCollection' is a collection type and cannot be serialized when assigned to an interface type that does not implement IEnumerable ('HealthMEDX.Core.Home.ITestCollection'.)"

  Source="System.ServiceModel.Web"

  StackTrace:

       at System.Runtime.Serialization.Json.XmlObjectSerializerWriteContextComplexJson.VerifyObjectCompatibilityWithInterface(DataContract contract, Object graph, Type declaredType)

  InnerException: 



这篇关于当ResponseFormat:= WebMessageFormat.Json并尝试序列化接口时发生错误(未返回任何数据)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆