⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 webservicerequestdispatcher.cs

📁 Microsoft Mobile Development Handbook的代码,有C#,VB,C++的
💻 CS
字号:
//===============================================================================
// Microsoft patterns & practices
// Mobile Client Software Factory - July 2006
//===============================================================================
// Copyright  Microsoft Corporation.  All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//===============================================================================
// The example companies, organizations, products, domain names,
// e-mail addresses, logos, people, places, and events depicted
// herein are fictitious.  No association with any real company,
// organization, product, domain name, email address, logo, person,
// places, or events is intended or should be inferred.
//===============================================================================

using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using Microsoft.Practices.Mobile.EndpointCatalog;
using System.Net;
using Microsoft.Practices.Mobile.DisconnectedAgent.Properties;

namespace Microsoft.Practices.Mobile.DisconnectedAgent
{
	/// <summary>
	/// Exception to wrap any exception thrown by return callback methods.
	/// </summary>
	public class ReturnCallbackException : Exception
	{
		/// <summary>
		/// Default constructor.
		/// </summary>
		/// <param name="message">Message for the exception.</param>
		/// <param name="innerException">Exception thrown by the return callback method.</param>
		public ReturnCallbackException(string message, Exception innerException)
			: base(message, innerException)
		{
		}
	}

	/// <summary>
	/// Default implementation of IRequestDispatcher.
	/// It's responsible for request dispatching regarding max retries, callbacks methods and ReturnCallbackException.
	/// It invokes the 
	/// </summary>
	public class WebServiceRequestDispatcher : IRequestDispatcher
	{
		private IProxyFactory onlineProxyFactory;

		/// <summary>
		/// This constructor sets the dispatcher to use a new WebServiceProxyFactory created using 
		/// the given catalog.
		/// </summary>
		/// <param name="catalog">
		///		IEndpointCatalog used to create a new WebServiceProxyFactory.
		///	</param>
		public WebServiceRequestDispatcher(IEndpointCatalog catalog)
		{
			onlineProxyFactory = (IProxyFactory) new WebServiceProxyFactory(catalog);
		}

		/// <summary>
		/// This constructor sets the dispatcher to use the given onlineProxyFactory.
		/// </summary>
		/// <param name="onlineProxyFactory">
		///		IProxyFactory used to create proxy objects.
		/// </param>
		public WebServiceRequestDispatcher(IProxyFactory onlineProxyFactory)
		{
			this.OnlineProxyFactory = onlineProxyFactory;
		}

		/// <summary>
		/// Get/Set the IProxyFactory used to create proxy objects.
		/// </summary>
		public IProxyFactory OnlineProxyFactory
		{
			get { return onlineProxyFactory; }
			set { onlineProxyFactory = value; }
		}
	
		/// <summary>
		/// This method dispatches the given request by invoking the corresponding method.
		/// </summary>
		/// <param name="request">Request to be dispatched</param>
		/// <param name="networkName">Current network name</param>
		/// <returns></returns>
		public virtual DispatchResult Dispatch(Request request, string networkName)
		{
			object onlineProxy = null;
			int retries = 0;
			DispatchResult? dispatchResult = null;

			try
			{
				onlineProxy = onlineProxyFactory.GetOnlineProxy(request, networkName);
			}
			catch
			{
				dispatchResult = DispatchResult.Failed;
			}

			while (dispatchResult == null)
			{
				Exception exception = null;

				try
				{
					retries++;
					object result = InvokeOnlineProxyMethod(onlineProxy, request);

					try
					{
						InvokeReturnCommand(onlineProxy, request, result);
					}
					catch (Exception ex)
					{
						if (ex is TargetInvocationException)
							throw new ReturnCallbackException(Resources.ExceptionOnReturnCallback + ex.Message, ex.InnerException);
						else
							throw new ReturnCallbackException(Resources.ExceptionOnReturnCallback + ex.Message, ex);
					}
					dispatchResult = DispatchResult.Succeeded;
				}

				catch (WebException ex)
				{
					switch (ex.Status)
					{
						//At server side should be the same as a failure
						case WebExceptionStatus.NameResolutionFailure:
						case WebExceptionStatus.ProxyNameResolutionFailure:
						case WebExceptionStatus.ProtocolError:
						case WebExceptionStatus.ServerProtocolViolation:
						case WebExceptionStatus.TrustFailure:
							exception = ex;
							break;

						//Otherwise should be handled out of the dispatcher.
						default:
							throw;
					}
				}

				catch (Exception ex)
				{
					exception = ex;
					if (ex is TargetInvocationException)
						exception = ex.InnerException;
				}

				if (exception != null)
				{
					try
					{
						//Invoke the exception callback
						switch (InvokeExceptionCommand(request, exception))
						{
							case OnExceptionAction.Dismiss:
								dispatchResult = DispatchResult.Failed;
								break;
							case OnExceptionAction.Retry:
								if (retries >= request.Behavior.MaxRetries)
									dispatchResult = DispatchResult.Failed;
								break;
						}
					}
					catch
					{
						dispatchResult = DispatchResult.Failed;
					}
				}
			}

			return (DispatchResult) dispatchResult;
		}

		virtual protected OnExceptionAction InvokeExceptionCommand(Request request, Exception realException)
		{
			if (request.Behavior.ExceptionCallback != null)
			{
				return (OnExceptionAction) request.Behavior.ExceptionCallback.Invoke(request, realException);
			}
			return OnExceptionAction.Dismiss;
		}

		virtual protected void InvokeReturnCommand(object onlineProxy, Request request, object result)
		{
			if (request.Behavior.ReturnCallback != null)
			{
				MethodInfo method = onlineProxy.GetType().GetMethod(request.MethodName);
				if (method.ReturnType != typeof(void))
					request.Behavior.ReturnCallback.Invoke(request, request.CallParameters, result);
				else
					request.Behavior.ReturnCallback.Invoke(request, request.CallParameters);
			}
		}

		virtual protected object InvokeOnlineProxyMethod(object onlineProxy, Request request)
		{
			MethodInfo method = onlineProxy.GetType().GetMethod(request.MethodName);
			object result = null;

			//Set the MessageID soapheader for Idempotency conforming WSAddressing
			PropertyInfo property = onlineProxy.GetType().GetProperty("MessageIDValue");
			if (property != null)
			{
				object reqId = Activator.CreateInstance(property.PropertyType);
				PropertyInfo textProperty = reqId.GetType().GetProperty("Text");
				textProperty.SetValue(reqId, new string[] { "uuid:" + request.Behavior.MessageId.ToString() }, null);
				property.SetValue(onlineProxy, reqId, null);
			}

			result = method.Invoke(onlineProxy, request.CallParameters);
			return result;
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -