被一個WCF問題卡住好一陣子。

在專案開發過程中,我測試了WinForm Call WCF傳回DataTable的做法,卻一直得到一個錯誤訊息。
(註: DataTable序列化後體積頗為可觀,在網路上傳輸並不是有效率的做法,我用WCF直接傳回DataTable是在開發初期先驗證可行性,打算後續再做效能改良。這傳說中黑董事長"先研究不傷身體,再講求效能"的開發理念!!)

"An error occurred while receiving the HTTP response to httq://localhost/MyWCFSvc/WCFDataHelper.svc. 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."

由這個訊息研判,我高度懷疑跟WCF設定成使用Windows認證有關,查了許久,看起來我IIS端的設定沒有問題(上回使用相同設定就成功),WinForm也加了身份宣告如下:
client = new MyWCF.WCFDataHelperClient();
clisnt.ClientCredentials.Windows.ClientCredential =
    new NetworkCredential("myServer\\demo", "****");

當密碼故意給錯時,會傳回不一樣的訊息:

The HTTP request is unauthorized with client authentication scheme 'Negotiate'. The authentication header received from the server was 'Negotiate,NTLM'.

這樣推估起來,那個錯誤是在身份認證完成後才傳回的。

一籌莫展之際,回歸最原始的方法,建立對照組。我另外建一個WCF,再把Method一個一個加上去。開始有些新發現:

  1. 走Windows認證呼叫WCF傳回"HelloWorld"的測試是OK的。表示不是Windows認證問題。
  2. 加了一個傳回Dictionary<string, string>的Method,也順利得到結果。(小插曲,發現VS2008在WinForm app.config加入的WCF Client binding maxBufferSize/maxReceivedMessageSize屬性太小,只有64KB,我很大氣地放大到16MB)
  3. 加入傳回DataTable的Method。噹! 踢到鐵板,傳回一開始那個HTTP Error訊息。

DataTable有什麼特別呢? 在腦中快速翻日記,想起一件事,之前用DataTable.WriteXml時,若未設TableName會得到"Cannot serialize the DataTable. DataTable name is not set."的錯誤訊息。在WCF傳回DataTable,肯定也經過序列化,極有可能是凶手就躲在裡面。

為DataTable加上TableName,糾纏多時的宿疾,就這麼不藥而瘉。

【心得】要使用WCF傳送DataTable時,請記得加上TableName。不過,無法序列化為什麼要傳回彷彿WCF不存在的錯誤訊息,實在是太機車了,劣劣劣劣。


Comments

# by cocoman

试试传回DataSet

# by evakey

真巧,昨天幫同事解決 Web Service 的問題,也是沒設 TableName 的異常,錯誤訊息一樣不明確

Post a comment