WCF 之 已知类型(KnownType)

  已知类型(Known types)允许在服务契约中使用多态的行为,在服务操作中暴露基本类型。
将已知类型(known types)相关到基本类型(基类类型)自身;特定操作;整个服务契约
采用属性声明或者配置的方式来实现

1、[KnownType]: 相关到基本类型(基类类型)自身

[DataContract(Namespace ="htttp://www.cnblogs.com/Charlesliu")]
[KnownType(typeof(GigInfo))]
[KnownType(typeof(PhotoLink))]
[KnownType(typeof(MP3Link))]
public class LinkItem
[DataContract(Namespace ="htttp://www.cnblogs.com/Charlesliu")]
public class GigInfo: LinkItem
[DataContract(Namespace ="htttp://www.cnblogs.com/Charlesliu")]
public class PhotoLink: LinkItem
[DataContract(Namespace ="htttp://www.cnblogs.com/Charlesliu")]
public class MP3Link: LinkItem

2、[ServiceKnownType]: 相关到整个服务契约

[ServiceContract(Name = "GigManagerContract", Namespace ="http://www.cnblogs.com/Charlesliu")]
[ServiceKnownType(typeof(GigInfo))]
[ServiceKnownType(typeof(PhotoLink))]
[ServiceKnownType(typeof(MP3Link))]
public interface IGigManagerService
{
    [OperationContract]
    void SaveLink(LinkItem item);
    [OperationContract]
    LinkItem GetLink(string id);
}

3、[ServiceKnownType]: 相关到特定操作

[ServiceContract(Name = "GigManagerContract", Namespace ="http://www.cnblogs.com/Charlesliu")]
public interface IGigManagerService
{
    [OperationContract]
    [ServiceKnownType(typeof(GigInfo))]
    void SaveGig(LinkItem item);
    [OperationContract]
    [ServiceKnownType(typeof(GigInfo))]
    LinkItem GetGig(string id);
}

  下面看一个具体的Demo,然后根据代码讲解:

  

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;

namespace ContentTypes
{
    [DataContract(Namespace = "http://www.cnblogs.com/Charlesliu")]
    public enum LinkItemCategories
    {
        [EnumMember]
        Gig,
        [EnumMember]
        MP3,
        [EnumMember]
        Photo
    }

    [DataContract(Name = "LinkItem_Contract", Namespace = "http://www.cnblogs.com/Charlesliu")]
    [KnownType(typeof(GigInfo))]
    [KnownType(typeof(PhotoLink))]
    [KnownType(typeof(MP3Link))]
    public class LinkItem
    {
        private long m_id;
        private string m_title;
        private string m_description;
        private DateTime m_dateStart;
        private DateTime m_dateEnd;
        private string m_url;
        private LinkItemCategories m_category;

        [DataMember(Name = "Id_Contract", IsRequired = false, Order = 0)]
        public long Id
        {
            get { return m_id; }
            set { m_id = value; }
        }

        [DataMember(Name = "Title_Contract", IsRequired = true, Order = 1)]
        public string Title
        {
            get { return m_title; }
            set { m_title = value; }
        }

        [DataMember(Name = "Description_Contract", IsRequired = true, Order = 2)]
        public string Description
        {
            get { return m_description; }
            set { m_description = value; }
        }

        [DataMember(Name = "DateStart_Contract", IsRequired = true, Order = 3)]
        public DateTime DateStart
        {
            get { return m_dateStart; }
            set { m_dateStart = value; }
        }

        [DataMember(Name = "DateEnd_Contract", IsRequired = false, Order = 4)]
        public DateTime DateEnd
        {
            get { return m_dateEnd; }
            set { m_dateEnd = value; }
        }

        [DataMember(Name = "Url_Contract", IsRequired = false, Order = 5)]
        public string Url
        {
            get { return m_url; }
            set { m_url = value; }
        }

        [DataMember(Name = "Category_Contract", IsRequired = false, Order = 6)]
        public LinkItemCategories Category
        {
            get { return m_category; }
            set { m_category = value; }
        }
    }

    [DataContract(Namespace = "http://www.cnblogs.com/Charlesliu")]
    public class GigInfo : LinkItem
    {
        public GigInfo()
        {
            this.Category = LinkItemCategories.Gig;
        }
    }

    [DataContract(Namespace = "http://www.cnblogs.com/Charlesliu")]
    public class MP3Link : LinkItem
    {
        public MP3Link()
        {
            this.Category = LinkItemCategories.MP3;
        }
    }

    [DataContract(Namespace = "http://www.cnblogs.com/Charlesliu")]
    public class PhotoLink : LinkItem
    {
        public PhotoLink()
        {
            this.Category = LinkItemCategories.Photo;
        }
    }
}

  enum类型可以用[EnumMember]标记,本例中如果不加[KnownType]的相关标记,那么在客户端是看不到子类型的。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using ContentTypes;

namespace WcfServiceLibraryDemo
{
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
    public class GigManagerService : IGigManagerService
    {
private LinkItem m_linkItem; #region IGigManager Members public void SaveGig(LinkItem item) { m_linkItem = item; } public LinkItem GetGig() { return m_linkItem; } #endregion } }
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using ContentTypes;

namespace WcfServiceLibraryDemo
{
    [ServiceContract(Name = "GigManagerServiceContract", Namespace = "http://www.cnblogs.com/Charlesliu", SessionMode = SessionMode.Required)]
    public interface IGigManagerService
    {
        [OperationContract(Name = "SaveGig", Action = "http://www.cnblogs.com/Charlesliu/GigManagerServiceContract/SaveGig", 
      ReplyAction = "http://www.cnblogs.com/Charlesliu/GigManagerServiceContract/SaveGigResponse")] void SaveGig(LinkItem item); [OperationContract(Name = "GetGig", Action = "http://www.cnblogs.com/Charlesliu/GigManagerServiceContract/GetGig",
      ReplyAction = "http://www.cnblogs.com/Charlesliu/GigManagerServiceContract/GetGigResponse")] LinkItem GetGig(); } }
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using WinTest.MyServiceReference;

namespace WinTest
{
    public partial class Form1 : Form
    {
        MyServiceReference.GigManagerServiceContractClient m_proxy = new WinTest.MyServiceReference.GigManagerServiceContractClient();

        public Form1()
        {
            InitializeComponent();
        }

        private void cmdSave_Click(object sender, EventArgs e)
        {
            MP3Link item = new MP3Link();

            item.Id_Contract = int.Parse(this.txtId.Text);
            item.Title_Contract = this.txtTitle.Text;
            item.Description_Contract = this.txtDescription.Text;
            item.DateStart_Contract = this.dtpStart.Value;
            item.DateEnd_Contract = this.dtpEnd.Value;
            item.Url_Contract = this.txtUrl.Text;

            m_proxy.SaveGig(item);
        }

        private void cmdGet_Click(object sender, EventArgs e)
        {
            MP3Link item = (MP3Link)m_proxy.GetGig();
            if (item != null)
            {
                this.txtId.Text = item.Id_Contract.ToString();
                this.txtTitle.Text = item.Title_Contract;
                this.txtDescription.Text = item.Description_Contract;

                if (item.DateStart_Contract != DateTime.MinValue)
                    this.dtpStart.Value = item.DateStart_Contract;
                if (item.DateEnd_Contract != DateTime.MinValue)
                    this.dtpEnd.Value = item.DateEnd_Contract;

                this.txtUrl.Text = item.Url_Contract;
            }
        }
    }
}

  客户端用的是MP3Link这个类,通过[KnownType]实现了WCF的多态。

原文地址:https://www.cnblogs.com/xinaixia/p/5780166.html