WCF类型和ServiceKnowType之间的差异
本文关键字:之间 ServiceKnowType 类型 WCF | 更新日期: 2023-09-27 18:26:13
考虑以下两个数据契约:
[DataContract]
public class Item
{
[DataMember]
public int X;
}
[DataContract]
public class SubItem : Item
{
[DataMember]
public int Y;
}
在以下服务合同中使用这两个数据合同有什么区别。
[ServiceContract]
public interface IInterface
{
[OperationContract]
[ServiceKnownType(typeof(SubItem))]
void Save(Item i);
}
[ServiceContract]
public interface IInterface
{
[OperationContract]
void Save(SubItem i);
}
第一个可以用SubItem以外的项的子类调用吗?如果是,那么ServiceKnownType的含义是什么?
在第一种情况下使用时,假设SubItem
继承自Item
,则当Web服务公开其WSDL时,您会告诉Web服务考虑SubItem
类型的反序列化,因为它可能被用作Item
参数(多态性主体)的参数,否则,即使DataMemberAttribute
在客户端对类型进行了反序列化,接收方端点也将无法将SubItem作为方法的参数进行传递。
应用了ServiceKnownType
的Note
,即使SubItem
没有用DataMember
属性标记,该类也将被序列化
这里是的一个例子
服务端
using System.Runtime.Serialization;
using System.ServiceModel;
namespace WcfService1
{
[ServiceContract]
public interface IService1
{
[OperationContract]
[ServiceKnownType(typeof(SubItem))] // try to comment this and uncomment GetDataUsingDataContract
Item GetData(int value);
//[OperationContract] //here try to comment/uncomment and see if the subitem was deserialized at client side the operation on server side will not be executed
//Item GetDataUsingDataContract(SubItem item);
//// TODO: Add your service operations here
}
// Use a data contract as illustrated in the sample below to add composite types to service operations.
[DataContract]
public class Item
{
bool boolValue = true;
string stringValue = "Hello ";
[DataMember]
public bool BoolValue
{
get { return boolValue; }
set { boolValue = value; }
}
[DataMember]
public string StringValue
{
get { return stringValue; }
set { stringValue = value; }
}
}
//[DataContract]
public class SubItem:Item
{
private string _subItemVersion;
//[DataMember]
public string SubItemToStringValueVersion { get { return _subItemVersion; } set { _subItemVersion = value; } }
}
}
客户端
static void Main(string[] args)
{
Service1Client service1Client = new Service1Client();
var result = service1Client.GetData(5);
if (result is SubItem)
{
}
}
是的,可以调用第一个,但如果实际类型对服务未知,则只能使用Item类型中的成员。
在这种情况下,ServiceKnownType对服务器没有任何用途/意义,因为它既没有用于参数也没有用于返回类型。
例如,如果Save操作将返回一个Item,而实际项是一个子项,则它将把结果序列化为一个子项。这就是ServiceKnownType属性的作用。
第一个Save方法只能用Item或SubIteminstance调用,但第二个方法只接受SubItem ServiceKnownTypeAttribute的目的是指定反序列化过程中应考虑的类型。有关更多信息,请参阅数据协定已知类型和ServiceKnownTypeAttribute类
在以下服务契约中使用这两个数据契约有什么区别?使用第一个,您可以传入类型为Item或SubItem的对象,因为SubItem公开为KnowType。在第二个中,您只能传递SubItem类型的项。
第一个可以用SubItem以外的项的子类调用吗?如果是,那么ServiceKnownType的含义是什么?否,不能用SubItem以外的项的子类调用它。要做到这一点,您必须将其作为KnownType公开。