-----------版本控制策略;必須支持向后兼容;----就是當服務端發生改變,但客戶端未更新會不會發生錯誤;
一旦契約發布,若要契約發生變化,如何不影響客戶端使用;
----wsdl:契約;
服務契約的變化--對客戶端的影響:
操作簽名的增加 (無影響,默認缺省值)
操作簽名的刪除(無影響,默認被忽略掉)
增加新的操作(無影響,客戶端不知道)
刪除操作、修改參數類型、修改返回值(報錯)
---
數據契約的變化??? 對客戶端的影響
添加non-required?? 無影響;
添加新的required?? 會報錯;
刪除 non-required? 不會報錯 但會丟失;
刪除required??????? 會報錯;
修改數據類型;????? 如果類型兼容,會產生未知異常,否則報錯;
?
?
解決版本兼容性;
----Iextensibledataobject是將冗雜的數據進行臨時的保存;
?public class DataUser:IExtensibleDataObject
{
?????? private ExtensionDataObject obj;
?????? public ExtensionDataObject ExtensionData
?????? {
?????????? get
?????????? {
?????????????? return obj;
?????? ????}
?????????? set
?????????? {
?????????????? obj = value;
?????????? }
?????? }
}
?
----數據契約序列化器;測試新舊版本兼容;
1.using System.Runtime.Serialization;
2.????????? Person p = new Person();
??????????? p.Name = "郭澤峰";
??????????? DataContractSerializer ds = new DataContractSerializer(typeof(Person));
??????????? FileStream fs = new FileStream("cc.xml", FileMode.Create);
??????????? ds.WriteObject(fs, p);
??????????? fs.Close();
? public partial class Form1 : Form
??? {
??????? public Form1()
??????? {
??????????? InitializeComponent();
??????? }
??????? private void button1_Click(object sender, EventArgs e)
??????? {
??????????? Person1 p = new Person1();
??????????? p.Name = "d";
??????????? p.Id = 123;
??????????? DataContractSerializer ds = new DataContractSerializer(typeof(Person1));
??????????? FileStream fs = new FileStream("cc.xml", FileMode.Create);
??????????? ds.WriteObject(fs, p);
??????????? fs.Close();
??????? }
??????? private void button2_Click(object sender, EventArgs e)
??????? {
??????????? //新版本到舊版本
??????????? DataContractSerializer ds = new DataContractSerializer(typeof(Person));
??????????? FileStream fs = new FileStream("cc.xml",FileMode.Open);
??????????? XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(fs,new XmlDictionaryReaderQuotas());
??????????? Person per = (Person)ds.ReadObject(reader, false);
??????????? MessageBox.Show(per.Name);
??????????? fs.Close();
??????????? //舊版本到新版本
??????????? per.Name = "hhhhh";
??????????? DataContractSerializer dss = new DataContractSerializer(typeof(Person1));
??????????? FileStream fss = new FileStream("cc.xml", FileMode.Create);
??????????? ds.WriteObject(fss, per);
??????????? fss.Close();
??????? }
??? }
3.這樣就把對象生成xml文件了;
?
-----------可擴展數據對象:
namespace wcf1
{
??? [DataContract(Name="Person", Namespace="wcf1")]
??? public? class Person:IExtensibleDataObject
??? {
??????? [DataMember]
??????? public string Name {get;set;}
??????? private ExtensionDataObject obj;
??????? public ExtensionDataObject ExtensionData
??????? {
??????????? get
??????????? {
??????????????? return obj;
??????????? }
??????????? set
??????????? {
??????????????? obj = value;
??????????? }
??????? }
??? }
??? [DataContract(Name = "Person", Namespace = "wcf1")]
??? public class Person1 : IExtensibleDataObject
??? {
??????? [DataMember]
??????? public string Name { get; set; }
??????? [DataMember]
??????? public int Id { get; set; }
??????? private ExtensionDataObject obj;
??????? public ExtensionDataObject ExtensionData
??????? {
??????????? get
??????????? {
??????????????? return obj;
??????????? }
??????????? set
??????????? {
??????????????? obj = value;
??????????? }
??????? }
??? }
}
-----這樣就可以實現新就版本的交互了;當然也有害處,若新版本增加了1mb數據,當提交給舊版本時,這1mb相當于沒有用途;加重了負載;
--以上是可擴展數據對象;
禁止使用可擴展數據對象:
<behaviors >
???????????????????????????????????? <serviceBehaviors>
?????????????????????????????????????????????? <behavior name="aa">
??????????????????????????????????????????????????????? <dataContractSerializer ignoreExtensionDataObject="true"/>
?????????????????????????????????????????????? </behavior>
???????????????????????????????????? </serviceBehaviors>
</behaviors>
后者是:
? [ServiceBehavior( IgnoreExtensionDataObject=true)]
??? public? class Person:IExtensibleDataObject
------版本控制策略:
1.嚴格的版本控制,一旦改動重新生成,但是不實用;
2.使用的版本策略:向后或向前的兼容性;
保存未知元素和容忍缺失元素以至于可以兼容,單參數變化就不行了;
-------
1.添加操作,不用升級版本;
2.刪除操作,升級版本;
3.添加了新的參數,不用升級,會默認缺省值;
?
4.參數發生了變化,升級版本;
5.刪除了參數:不用升級版本;
----數據契約:
1.新添加成員,不用升級;
2.刪除成員,不用升級;(多余的被忽略)
3.數據類型,名稱發生變化,需要升級;
---
wcf缺省提供版本相容性支持;
------------------------------------------------------剖出異常:
1.所有異常都被序列化為soap faults; (soap 1.1和soap1.2格式)
2.soap1.2
?? Code:必須;可以是規范定義的代碼
?? Reason:必須,錯誤字符串的解釋信息
?? Role:可選;描述錯誤源的URI;
?? Detail:可選,提供錯誤的body信息;
?? Node:可選;描述產生錯誤的節點URI;
3. isoneway=true;標記后客戶端并不能捕捉異常,而響應式則捕捉
4. 是否包含敏感信息;
兩種方式:
1.在wcf服務中標記:
[ServiceBehaviorAttribute(IncluedeExceptionDetailsInFaults=true)]
puFaultblic class service:Iservice
{
}
2.web配置節點中的behavior里配置:<serviceDebug includeExceptionDetailInFaults="true">
5.剖出類型有三種:FaultException\FaultException<T>\MesssageFault:
? (1)
? throw new FaultException("");
??throw new FaultException(new FaultReason(""));
? throw new FaultException(new FaultReason(""),FaultCode.CreateSenderFaultCode(null));
? (2) FaultException<T>,不利于互操作,
? 錯誤契約:[faultContract(typeof())]
T:必須是數據契約或是可序列化類型;也可以是clr特有的異常(不利于互操作)云因如果客戶端是java,和。net定義異常不一樣,容易出現錯誤;T:為數據契約,更好的互操作;
在契約接口的每個聲明操作上添加標簽;將錯誤信息對象化;//---案例:
throw new FaultException<InvalidOperationException>(new InvalidOperationException(""), "", FaultCode.CreateSenderFaultCode(null));
public interface IReturnuser
???? {
???????? [OperationContract(IsOneWay = true)]
???????? [FaultContract(typeof(CusError))]
???????? void Return
???? }
(3) MessageFaults
MessageFault mfault = MessageFault.CreateFault(FaultCode.CreateSenderFaultCode(null), new FaultReason("錯誤"), new InvalidOperationException("an error occurred"), null, "", "");
FaultException fe = FaultException.CreateFault(mfault,typeof(InvalidOperationException));
throw fe;
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
