C# yield在WCF中的錯(cuò)誤用法(一)
在定義API的時(shí)候,對(duì)于一些返回集合對(duì)象的方法,很多人喜歡將返回類型定義成IEnumerable<T>,這本沒有什么問題。這里要說的是另一個(gè)問題:對(duì)于返回類型為IEnumerable<T>的方法來說,我們可以使用yield return的方式來輸出返回集合的元素。但是如果我們不了解yield 關(guān)鍵字背后的實(shí)現(xiàn)機(jī)制,很有可能造成很大的問題。
這是一個(gè)WCF相關(guān)的問題,我想99%的人都有可能會(huì)犯這樣的錯(cuò)誤——即使你對(duì)yield了解得非常透徹。閑話少說,我們通過一個(gè)簡單的實(shí)例來說明這個(gè)問題。我們定義了如下一個(gè)IDemoService接口作為服務(wù)契約,唯一的方法GetItems返回一個(gè)類型為IEnumerable<string>對(duì)象,并且具有唯一字符串參數(shù)category。
[ServiceContract]
public interface IDemoService
{
[OperationContract]
IEnumerable<string> GetItems(string category);
}
下面是實(shí)現(xiàn)了該契約接口的DemoService的實(shí)現(xiàn):GetItems方法返回一個(gè)包含3個(gè)字符串的集合,但是在返回之前我們需要對(duì)參數(shù)實(shí)施驗(yàn)證。如果category參數(shù)提供的字符串為Null或者是空字符串,拋出一個(gè)FaultException異常并提示“Invalid Category”,這樣客戶端在輸入不合法參數(shù)的情況下可以得到錯(cuò)誤消息。這樣的編程方式再正常不過了,不是嗎?
public class DemoService : IDemoService
{
public IEnumerable<string> GetItems(string categoty)
{
if (string.IsNullOrEmpty(categoty))
{
throw new FaultException("Invalid category");
}
yield return "Foo";
yield return "Bar";
yield return "Baz";
}
}
可是正常并不意味著正確,客戶端其實(shí)根本無法得到服務(wù)端提供給它的錯(cuò)誤消息,如下所示的是客戶端調(diào)用服務(wù)時(shí)指定一個(gè)空字符串參數(shù)情況下得到的錯(cuò)誤。一個(gè)CommunicationException異常被拋出來,得到的錯(cuò)誤消息為“An error occurred while receiving the HTTP response to http://127.0.0.1:3721/demoservice. This could be due to the service endpoint binding not using the HTTP protocol. This could also be due to an HTTP request context being aborted by the server (possibly due to the service shutting down). See server logs for more details.”
這貌似和我們預(yù)期的效果不一樣,我們希望的是客戶端拋出一個(gè)FaultException,并提示“Invalid category”。這實(shí)際上就是因?yàn)椤皔ield”在作祟,不相信的話可以將定義在DemoService的GetItems方法替換成如下的定義,即直接返回一個(gè)string[]對(duì)像。
public class DemoService : IDemoService
{
public IEnumerable<string> GetItems(string categoty)
{
if (string.IsNullOrEmpty(categoty))
{
throw new FaultException("Invalid category");
}
return new string[] { "Foo", "Bar", "Baz" };
}
}
再次運(yùn)行我們的程序,這回可以得到我們期望的結(jié)果了。
有興趣的朋友可以思考一下為什么兩種貌似等效的方式為何會(huì)出現(xiàn)完全不同的結(jié)果,具體原因請(qǐng)看[下篇]。
相關(guān)文章
c#實(shí)現(xiàn)數(shù)據(jù)庫事務(wù)示例分享
這篇文章主要介紹了c#執(zhí)行多條sql更新語句實(shí)現(xiàn)數(shù)據(jù)庫事務(wù)的示例,大家參考使用吧2014-01-01C# CAD SelectionFilter下TypedValue數(shù)組使用方式
這篇文章主要介紹了C# CAD SelectionFilter下TypedValue數(shù)組使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-02-02C#中Hashtable和Dictionary的區(qū)別與用法示例
由于 Hashtable 和 Dictionary 同時(shí)存在, 在使用場(chǎng)景上必然存在選擇性, 并不任何時(shí)刻都能相互替代。所以這篇文章主要給大家介紹了關(guān)于C#中Hashtable和Dictionary區(qū)別的相關(guān)資料,需要的朋友可以參考下2021-05-05C#實(shí)現(xiàn) Server-sent Events的步驟
這篇文章主要介紹了C#實(shí)現(xiàn) Server-sent Events的步驟,幫助大家更好的理解和使用c#,感興趣的朋友可以了解下2021-01-01C#生成不重復(fù)隨機(jī)數(shù)列表實(shí)例
C#生成不重復(fù)隨機(jī)數(shù)列表實(shí)例的代碼,需要的朋友可以參考一下2013-02-02C#中List轉(zhuǎn)IList的實(shí)現(xiàn)
本文主要介紹了C#中List轉(zhuǎn)IList的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07