C# yield在WCF中的錯誤用法(一)
在定義API的時候,對于一些返回集合對象的方法,很多人喜歡將返回類型定義成IEnumerable<T>,這本沒有什么問題。這里要說的是另一個問題:對于返回類型為IEnumerable<T>的方法來說,我們可以使用yield return的方式來輸出返回集合的元素。但是如果我們不了解yield 關鍵字背后的實現(xiàn)機制,很有可能造成很大的問題。
這是一個WCF相關的問題,我想99%的人都有可能會犯這樣的錯誤——即使你對yield了解得非常透徹。閑話少說,我們通過一個簡單的實例來說明這個問題。我們定義了如下一個IDemoService接口作為服務契約,唯一的方法GetItems返回一個類型為IEnumerable<string>對象,并且具有唯一字符串參數(shù)category。
[ServiceContract]
public interface IDemoService
{
[OperationContract]
IEnumerable<string> GetItems(string category);
}
下面是實現(xiàn)了該契約接口的DemoService的實現(xiàn):GetItems方法返回一個包含3個字符串的集合,但是在返回之前我們需要對參數(shù)實施驗證。如果category參數(shù)提供的字符串為Null或者是空字符串,拋出一個FaultException異常并提示“Invalid Category”,這樣客戶端在輸入不合法參數(shù)的情況下可以得到錯誤消息。這樣的編程方式再正常不過了,不是嗎?
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";
}
}
可是正常并不意味著正確,客戶端其實根本無法得到服務端提供給它的錯誤消息,如下所示的是客戶端調(diào)用服務時指定一個空字符串參數(shù)情況下得到的錯誤。一個CommunicationException異常被拋出來,得到的錯誤消息為“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.”
這貌似和我們預期的效果不一樣,我們希望的是客戶端拋出一個FaultException,并提示“Invalid category”。這實際上就是因為“yield”在作祟,不相信的話可以將定義在DemoService的GetItems方法替換成如下的定義,即直接返回一個string[]對像。
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" };
}
}
再次運行我們的程序,這回可以得到我們期望的結果了。
有興趣的朋友可以思考一下為什么兩種貌似等效的方式為何會出現(xiàn)完全不同的結果,具體原因請看[下篇]。
相關文章
C# CAD SelectionFilter下TypedValue數(shù)組使用方式
這篇文章主要介紹了C# CAD SelectionFilter下TypedValue數(shù)組使用方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-02-02C#中Hashtable和Dictionary的區(qū)別與用法示例
由于 Hashtable 和 Dictionary 同時存在, 在使用場景上必然存在選擇性, 并不任何時刻都能相互替代。所以這篇文章主要給大家介紹了關于C#中Hashtable和Dictionary區(qū)別的相關資料,需要的朋友可以參考下2021-05-05C#實現(xiàn) Server-sent Events的步驟
這篇文章主要介紹了C#實現(xiàn) Server-sent Events的步驟,幫助大家更好的理解和使用c#,感興趣的朋友可以了解下2021-01-01