1. 程式人生 > 其它 >學會WCF之試錯法——客戶端呼叫基礎

學會WCF之試錯法——客戶端呼叫基礎

1當客戶端呼叫未返回結果時,服務不可用(網路連線中斷,服務關閉,服務崩潰等)

客戶端丟擲異常

異常型別:CommunicationException

InnerException:

Message:

接收對 http://localhost/S 的 HTTP 響應時發生錯誤。這可能是由於服務終結點繫結未使用 HTTP 協議造成的。這還可能是由於伺服器中止了 HTTP 請求上下文(可能由於服務關閉)所致。有關詳細資訊,請參見伺服器日誌。

Stacktrace:

Server stack trace:

在 System.ServiceModel.Channels.HttpChannelUtilities.ProcessGetResponseWebException(WebException webException, HttpWebRequest request, HttpAbortReason abortReason)

在 System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)

在 System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)

在 System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)

在 System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)

在 System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)

在 System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

Exception rethrown at [0]:

在 System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)

在 System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)

在 Client.IService.GetData(Int32 value)

在 Client.ServiceClient.GetData(Int32 value) 位置 e:projgxz_myselfWCF_Find_ErrorClientServiceProxy.cs:行號 52

在 Client.ServiceProxy.GetData(Int32 value) 位置 e:projgxz_myselfWCF_Find_ErrorClientServiceProxy.cs:行號 19

在 Client.Program.Main(String[] args) 位置 e:projgxz_myselfWCF_Find_ErrorClientProgram.cs:行號 17

2 服務地址與元資料訪問地址

伺服器A(192.168.107.13)上部署服務,服務端終結點配置為:http://localhost/S,元資料檢索URI配置為http://localhost/S

在客戶端(192.168.20.104)上訪問A的服務,檢視元資料。客戶端瀏覽器輸入網址:http://192.168.107.13/S

輸出頁面為:

點選頁面連結:無法訪問到A機器服務的元素據,這是合理的因為localhost代表本機的ip,此刻操作是在客戶端的機器上,而不在伺服器上;客戶端的機器上並沒有這個服務,所以服務端終結點配置為:http://localhost/S,元資料檢索URI配置為http://192.168.107.13/S

當服務端終結點和元資料訪問地址不統一時,服務端通訊物件無法開啟。

3對比無法獲得異常真實原因的兩種用法

服務端方法:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Reentrant)]
    public class Service : IService
    {
        public string GetData(int value)
        {
            return string.Format("You entered: {0}", value);
        }
}

客戶端代理:

public class ServiceProxy
    {
        public string GetData(int value)
        {
            string ret = null;
            ServiceClient client = null;
            try
            {
                client = new ServiceClient();
                ret = client.GetData(value);
                client.Close();
            }
            catch
            {
                if (client != null)
                {
                    client.Abort();
                }
                throw;
            }
            return ret;
        }
}

[ServiceContractAttribute(ConfigurationName = "IService")]
    public interface IService
    {

        [System.ServiceModel.OperationContractAttribute(Action = "http://tempuri.org/IService/GetData", ReplyAction = "http://tempuri.org/IService/GetDataResponse")]
        string GetData(int value);
}

public class ServiceClient : System.ServiceModel.ClientBase<IService>, IService
    {

        public ServiceClient()
        {
        }

        public string GetData(int value)
        {
            return base.Channel.GetData(value);
        }
}

客戶端呼叫:

方式一

直接呼叫ServiceClient,呼叫資料返回後關閉客戶端。

static void Main(string[] args)
{
            try
            {
          ServiceClient clients = new ServiceClient();
                clients.GetData(1);
          clients.Close();
            }
            catch (Exception ex)
            {
                clients.Abort();
            }
}

方式二:

在Main方法中將下面的程式碼用try...catch包起來。

                ServiceProxy proxy = new ServiceProxy();
                proxy.GetData(1);

方式三:

在Main方法中將下面的程式碼用try...catch包起來。

 using (ServiceClient client = new ServiceClient())
        {
                    client.GetData(1);
                }

方法一和方法二可以返回真實的原因,而方法三不能,他們的區別在於,方法三在客戶端捕獲異常之前關閉了客戶端物件,而其他兩種方式則是在獲得異常資訊後才關閉客戶端物件的,所以由上面的測試又可得出WCF客戶端程式中慎用using。