📄 webservicerequestdispatcher.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 + -