一区二区三区欧美日韩-一区二区三区欧美-一区二区三区免费在线视频-一区二区三区免费在线观看-久久精品店-久久精品第一页

歡迎您光臨深圳塔燈網(wǎng)絡科技有限公司!
電話圖標 余先生:13699882642

網(wǎng)站百科

為您解碼網(wǎng)站建設的點點滴滴

[WCF REST] 解決資源并發(fā)修改的一個有效的手段:條件更新(Conditional Update)

發(fā)表日期:2019-09 文章編輯:小燈 瀏覽次數(shù):1948

HTTP為條件更新提供了相應的報頭,我們按照分析條件獲取的方式來分析條件更新在HTTP請求/回復過程中的實現(xiàn)??蛻舳说谝淮蜗蚍斩税l(fā)起針對某個資源的請求,服務端除了將資源數(shù)據(jù)作為回復消息主體返回之外,會將與資源關聯(lián)并且能夠可以用于對其進行對等性判斷的某個值作為回復的ETag報頭,這與條件獲取時一致的。

客戶端通過回復獲得請求的資源和ETag報頭值。對于資源修改操作,客戶端直接針對獲取的資源進行相應的修改,并將修改后的資源以HTTP請求的方式向服務端提交;對于資源刪除操作,則可以指定被刪除資源的唯一標識直接向服務端發(fā)送刪除的請求。而之前獲取的ETag指將會作為請求消息的If-Match報頭。

服務端接收到資源修改/刪除請求后先獲取到現(xiàn)有的資源的ETag值,并將此值與請求消息的If-Match報頭值進行比較。如果兩者不一致,則表明試圖被修改/刪除的資源已經(jīng)被修改了,在這種情況下會直接回復一個HTTP狀態(tài)為“412 (Precondition Failed)”的空消息。條件更新同時支持針對PUT、POST和DELETE這三種方法的HTTP請求。

二、WebOperationContext與條件更新

服務端進行條件更新檢測,以及客戶端對If-Match請求報頭的設置都可以通過當前的WebOperationContext來完成。如下面的代碼片斷所示,表示入棧請求上下文的IncomingWebRequestContext類型具有如下四個CheckConditionalUpdate方法重載用于進行添加更新檢測。

 1: public class IncomingWebRequestContext
 2: {
 3: //其他成員
 4: public void CheckConditionalUpdate(Guid entityTag);
 5: public void CheckConditionalUpdate(int entityTag);
 6: public void CheckConditionalUpdate(long entityTag);
 7: public void CheckConditionalUpdate(string entityTag);
 8: }

實現(xiàn)在CheckConditionalUpdate方法中的條件更新檢測具有這樣的邏輯:對于HTTP方法為PUT的請求,如果If-Match報頭值不為“*”,則直接拋出HTTP狀態(tài)為PreconditionFailed的WebFaultException異常;對于HTTP方法為POST和DELETE的請求來說,如果If-Match報頭值為“*”或者包含指定的entityTag則驗證通過,否則同樣則直接拋出HTTP狀態(tài)為PreconditionFailed的WebFaultException異常。

表示出棧請求上下文的OutgoingWebRequestContext類型具有如下一個IfMatch屬性,客戶端可以通過該屬性對請求消息的If-Match報頭進行設置。

 1: public class OutgoingWebRequestContext
 2: {
 3: //其他成員
 4: public string IfMatch { get; set; }
 5: }

三、實例演示:通過條件更新解決對相同資源的并發(fā)修改

我們同樣通過對EmployeesService進行相應的改造來模擬如何通過添加更新實現(xiàn)對相同資源的并發(fā)操作問題,這次我們修改的是用于獲取指定ID員工信息的Get操作和用于修改員工信息的Update操作。Get操作在返回與指定員工ID匹配的Employee對象之前我們將該對象的哈希碼作為了回復消息的ETag報頭(Employee類型重寫了GetHashCode方法)。

 1: public class EmployeesService : IEmployees
 2: {
 3: //其他成員
 4: public Employee Get(string id)
 5: {
 6: Employee employee = employees.FirstOrDefault(e => e.Id == id);
 7: if (null == employee)
 8: {
 9: throw new WebFaultException(HttpStatusCode.NotFound);
10: }
11: WebOperationContext.Current.OutgoingResponse.SetETag(employee.GetHashCode());
12: return employee;
13: }
14: public void Update(Employee employee)
15: {
16: var existing = employees.FirstOrDefault(e => e.Id == employee.Id);
17: if (null == existing)
18: {
19: throw new WebFaultException(HttpStatusCode.NotFound);
20: }
21: //模擬并發(fā)修改
22: existing.Name += Guid.NewGuid().ToString();
23:? 
24: WebOperationContext.Current.IncomingRequest.CheckConditionalUpdate(existing.GetHashCode());
25: employees.Remove(existing);
26: employees.Add(employee);
27: WebOperationContext.Current.OutgoingResponse.SetETag(employee.GetHashCode());
28:? 
29: }
30: }

Update方法中我們通過手工修改相應員工的Name屬性的方式來模擬針對相同員工信息的并發(fā)修改。在真正實施修改之前調用當前IncomingWebRequestContext的CheckConditionalUpdate方法進行條件更新檢測,而作為參數(shù)傳入的ETag值為代表目前員工的Employee對象的哈希碼。方法的最后我們對回復消息的ETag報頭作了更新。

我們通過手工創(chuàng)建HTTP請求的方式對上述的兩個服務操作進行調用。如下面的代碼片斷所示,我們首先通過創(chuàng)建的HttpWebRequest對象調用Get操作獲得ID為001的員工信息并將其打印出來。然后創(chuàng)建調用Update操作的HttpWebRequest,并對HTTP方法(POST)和內容類型(application/xml)進行了相應的設置。我們之前針對員工獲取請求得到ETag報頭和員工數(shù)據(jù)作為本次請求的If-Match報頭和主體。如果調用GetResponse方法拋出WebException異常,并且其回復狀態(tài)為PreconditionFailed,則表明試圖修改的員工信息已被另一個用戶修改過了,所以我么打印“服務端數(shù)據(jù)已發(fā)生變化”字樣。

 1: Uri address = new Uri("http://127.0.0.1:3721/employees/001");
 2: var request = (HttpWebRequest)HttpWebRequest.Create(address);
 3: request.Method = "GET";
 4: var response = (HttpWebResponse)request.GetResponse();
 5: string employee;
 6: using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
 7: {
 8: employee = reader.ReadToEnd();
 9: Console.WriteLine("獲取員工信息:");
10: Console.WriteLine(employee + "\n");
11: }
12: try
13: {
14: address = new Uri("http://127.0.0.1:3721/employees/");
15: request = (HttpWebRequest)HttpWebRequest.Create(address);
16: request.Method = "POST";
17: request.ContentType = "application/xml";
18: byte[] buffer = Encoding.UTF8.GetBytes(employee);
19: request.GetRequestStream().Write(Encoding.UTF8.GetBytes(employee), 0, buffer.Length);
20: request.Headers.Add(HttpRequestHeader.IfMatch, response.Headers[HttpResponseHeader.ETag]);
21: Console.WriteLine("修改員工信息:");
22: request.GetResponse();
23: }
24: catch (WebException ex)
25: {
26: response = ex.Response as HttpWebResponse;
27: if (null == response)
28: {
29: throw;
30: }
31: if (response.StatusCode == HttpStatusCode.PreconditionFailed)
32: {
33: Console.WriteLine("服務端數(shù)據(jù)已發(fā)生變化");
34: }
35: else
36: {
37: throw;
38: }
39: }

在服務成功寄宿的情況下調用這段程序會在控制臺上輸出如下的結果。由于并發(fā)錯誤的發(fā)生,員工信息其實并沒有被真正修改。

 1: 獲取員工信息:
 2: <Employee xmlns="http://www.artech.com/" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><Department>開發(fā)部</Department><Grade>G7</Grade><Id>001</Id><Name>張三</Name></Employee>
 3:? 
 4: 修改員工信息:
 5: 服務端數(shù)據(jù)已發(fā)生變化

本頁內容由塔燈網(wǎng)絡科技有限公司通過網(wǎng)絡收集編輯所得,所有資料僅供用戶學習參考,本站不擁有所有權,如您認為本網(wǎng)頁中由涉嫌抄襲的內容,請及時與我們聯(lián)系,并提供相關證據(jù),工作人員會在5工作日內聯(lián)系您,一經(jīng)查實,本站立刻刪除侵權內容。本文鏈接:http://www.junxiaosheng.cn/19703.html
相關開發(fā)語言
 八年  行業(yè)經(jīng)驗

多一份參考,總有益處

聯(lián)系深圳網(wǎng)站公司塔燈網(wǎng)絡,免費獲得網(wǎng)站建設方案及報價

咨詢相關問題或預約面談,可以通過以下方式與我們聯(lián)系

業(yè)務熱線:余經(jīng)理:13699882642

Copyright ? 2013-2018 Tadeng NetWork Technology Co., LTD. All Rights Reserved.    

  • QQ咨詢
  • 在線咨詢
  • 官方微信
  • 聯(lián)系電話
    座機0755-29185426
    手機13699882642
  • 預約上門
  • 返回頂部
主站蜘蛛池模板: 欧美高清videos 360p| 甜性涩爱下载| 最近的中文字幕2019国语| 日本xxxx96| 嫩草欧美曰韩国产大片| 韩国hd高清xxx| 国产精品亚洲精品日韩电影| 99riav9 精品香蕉免费大视频| 亚洲午夜性春猛交XXXX| 日韩亚洲不卡在线视频| 女教师公车痴汉在线播放| 韩国电影久久| 红番阁免费观看| 韩国成人理伦片免费播放| 国产免费人成在线视频有码 | 国产亚洲精品在浅麻豆| 大胸美女被C得嗷嗷叫动态图| xxxx88| 综合激情区视频一区视频二区| 一本色道久久综合一区| 亚洲色欲色欲WWW在线丝| 亚洲视频国产在线精品| 亚洲乱码高清午夜理论电影| 亚洲无线码一区在线观看| 野花日本大全免费观看3中文版 | 久久成人永久免费播放| 好想被狂躁A片免费久99| 九九这里有精品| 美女被爆插| 十分钟免费视频大全在线| 无遮掩H黄纯肉动漫在线观看星| 午夜福利体验免费体验区| 亚洲精品视频在线播放| 7777色鬼xxxx欧美色夫| gay吊粗大双龙| 国产亚洲视频在线| 妹妹的第一次有点紧| 人人做人人干| 伊人大香线蕉影院在线播放| 俺来也俺去也视频久久| 国产一区私人高清影院|