WCF 数据契约和多态性
这就是我想做的。这(理论上)应该非常简单。
假设我有一个包含以下代码(基本功能)的 WCF 服务:
<DataContract()>
Public Class BaseObj
<DataMember()>
Public ID As Integer
End Class
<DataContract()>
Public Class TestObj1
Inherits BaseObj
Public Sub New(ByVal idval As Integer)
ID = idval
End Sub
End Class
<DataContract()>
Public Class TestObj2
Inherits BaseObj
Public Sub New(ByVal idval As Integer)
ID = idval
End Sub
<DataMember()>
Public DoNotShow As String = "fail"
End Class
这是我要编写的代码:
<WebInvoke(Method:="GET", ResponseFormat:=WebMessageFormat.Json, UriTemplate:="Test?reqReportID={reqReportID}")>
Public Function GetCollection(ByVal reqReportID As Integer) As List(Of BaseObj)
Dim myObjs as New List(Of BaseObj)
myObjs.add(new TestObj1(1))
myObjs.add(new TestObj2(2))
return myObjs
End Function
我希望 JSON 响应看起来完全像这样: [{"ID":1},{" ID":2}]
现在,我当前的代码返回一个空响应(没有抛出错误,没有传递任何信息)。我可以通过这样做来让它返回一些东西:
<DataContract(), KnownType(GetType(TestObj1)), KnownType(GetType(TestObj2))>
Public Class BaseObj
<DataMember()>
Public ID As Integer
End Class
但是,响应向 JSON 对象添加了“__type”,并且还向 JSON 对象添加了“DoNotShow”(这不是一件好事)。
这里的问题是我不想传递每个对象唯一的信息。我只想要通过基类为每个对象所共有的信息。我无能为力改变它,除非我遗漏了一些东西,否则 WCF 的作者在创建它时似乎对 OO 编程有一种非常粗鄙的看法。
如果您对 SO 有任何见解,我们将不胜感激。
Here's what I want to do. This should (theoretically) be very simple.
Say I have a WCF service with the following code (bare bones functionality):
<DataContract()>
Public Class BaseObj
<DataMember()>
Public ID As Integer
End Class
<DataContract()>
Public Class TestObj1
Inherits BaseObj
Public Sub New(ByVal idval As Integer)
ID = idval
End Sub
End Class
<DataContract()>
Public Class TestObj2
Inherits BaseObj
Public Sub New(ByVal idval As Integer)
ID = idval
End Sub
<DataMember()>
Public DoNotShow As String = "fail"
End Class
Here is the code I want to write:
<WebInvoke(Method:="GET", ResponseFormat:=WebMessageFormat.Json, UriTemplate:="Test?reqReportID={reqReportID}")>
Public Function GetCollection(ByVal reqReportID As Integer) As List(Of BaseObj)
Dim myObjs as New List(Of BaseObj)
myObjs.add(new TestObj1(1))
myObjs.add(new TestObj2(2))
return myObjs
End Function
I want the JSON response to look exactly like this: [{"ID":1},{"ID":2}]
Now the code that I have currently returns an empty response (no error thrown, no information passed). I can get it to return something by doing this:
<DataContract(), KnownType(GetType(TestObj1)), KnownType(GetType(TestObj2))>
Public Class BaseObj
<DataMember()>
Public ID As Integer
End Class
However the response adds a "__type" to the JSON object, and also adds "DoNotShow" to the JSON object (not a good thing).
The problem here is that I do not want to pass information that is unique to each object. I only want information that is common to each object through the base class. Nothing I can do will change it, and unless I am missing something, it seems as though the authors of WCF had a very bassackwards view of OO programming when they created this.
Any insight you here at SO might have would be greatly appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
出于好奇,为什么这很重要?通过您给出的示例,我不确定我是否理解了它的重要性。
我立即想到的一个选择是从 TestObj1 继承 TestObj2。然后我会去掉knowntype(gettype(testobj2))。
如果您想动态添加已知类型,那么您应该自己调用 datacontractjsonserializer。
http://msdn.microsoft.com/en -us/library/system.runtime.serialization.json.datacontractjsonserializer.aspx
编辑:这将在客户端产生两个 TestObj1 对象。不确定您是否想要这种行为。
Out of curiosity, why does it matter? With the example you gave I'm not sure I'm following the why it's important.
One option I have off of the top of my head is to inherit TestObj2 from TestObj1. Then I would take off the knowntype(gettype(testobj2)).
If you want to dynamically add known types then you should call the datacontractjsonserializer yourself.
http://msdn.microsoft.com/en-us/library/system.runtime.serialization.json.datacontractjsonserializer.aspx
Edit: this will result in two TestObj1 objects on the client side. Not sure if you want that behavior.
如果您的集合仅输入到 BaseObj,我认为序列化程序不可能生成您正在寻找的 JSON。
如果它只是生成
[{"ID":1},{"ID":2}]
,则接收者无法区分类型。另一端如何确定第一个对象的类型为 TestObj1 而第二个对象的类型为 TestObj2?If your collection is only typed to BaseObj I don't think it's possible for the serializer to produce the JSON you are looking for.
If it were to simply produce
[{"ID":1},{"ID":2}]
, there is no way for the recipient to distinguish between the types. How would the other end determine that the first object is of type TestObj1 but the second object is of type TestObj2?