【问题标题】:Implementing RequestWrapper for RESTful WCF service为 RESTful WCF 服务实现 RequestWrapper
【发布时间】:2012-04-26 18:22:27
【问题描述】:

我编写了一个名为 RequestWrapper 的简单对象,其中包含单一类型的方法:

TResult WrapRequest<TResult>(Func<TResult> action)

它使用try..catch 包装任何操作、错误处理、日志记录、数据库连接、事务(提交和回滚)等。

目前我这样使用它:(示例,不是生产代码)

return RequestWrapper.WrapRequest(() =>
{
    Topic entity = GetRepository<Topic>().Find(uid);

    if (entity == null)
        throw new EntityNotFoundException("Topic not found.");

    return new Topic
    {
        Name = entity.Name,
        Posts = entity.Posts.Select(x => new Post
        {
            Body = x.Body,
        }).ToList()
    };
});

我只是封装了我的 RESTful Web 服务的每个方法(使用 WCF 和 WebHttpBinding)。

我的问题是:我应该如何实现自动为我包装的行为?有可能吗?

【问题讨论】:

    标签: wcf rest wrapper webhttpbinding


    【解决方案1】:

    您可以使用自定义的IOperationInvoker,它包装了原始的,可以满足您的需要。下面的代码显示了一个示例实现,您可以在http://blogs.msdn.com/b/carlosfigueira/archive/2011/05/17/wcf-extensibility-ioperationinvoker.aspx 找到有关调用程序的更多信息。

    public class StackOverflow_10156890
    {
        [ServiceContract]
        public interface ITest
        {
            [WebGet]
            [WrappedOperationBehavior]
            string Echo(string text);
            [WebInvoke(BodyStyle = WebMessageBodyStyle.WrappedRequest)]
            [WrappedOperationBehavior]
            int Divide(int x, int y);
        }
        public class Service : ITest
        {
            public string Echo(string text)
            {
                return text;
            }
            public int Divide(int x, int y)
            {
                return x / y;
            }
        }
        class RequestWrapperOperationInvoker : IOperationInvoker
        {
            IOperationInvoker originalInvoker;
    
            public RequestWrapperOperationInvoker(IOperationInvoker originalInvoker)
            {
                this.originalInvoker = originalInvoker;
            }
    
            public object[] AllocateInputs()
            {
                return this.originalInvoker.AllocateInputs();
            }
    
            public object Invoke(object instance, object[] inputs, out object[] outputs)
            {
                Console.WriteLine("Do initialization, etc. here");
                object result = null;
                try
                {
                    result = this.originalInvoker.Invoke(instance, inputs, out outputs);
                }
                catch (Exception e)
                {
                    Console.WriteLine("Log exception: {0}: {1}", e.GetType().FullName, e.Message);
                    result = null;
                    outputs = null;
                }
                finally
                {
                    Console.WriteLine("Do finalization, etc. here");
                }
    
                return result;
            }
    
            public IAsyncResult InvokeBegin(object instance, object[] inputs, AsyncCallback callback, object state)
            {
                throw new NotSupportedException("Only synchronous operations supported");
            }
    
            public object InvokeEnd(object instance, out object[] outputs, IAsyncResult result)
            {
                throw new NotSupportedException("Only synchronous operations supported");
            }
    
            public bool IsSynchronous
            {
                get { return true; }
            }
        }
        class WrappedOperationBehaviorAttribute : Attribute, IOperationBehavior
        {
            public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters)
            {
            }
    
            public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation)
            {
            }
    
            public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
            {
                dispatchOperation.Invoker = new RequestWrapperOperationInvoker(dispatchOperation.Invoker);
            }
    
            public void Validate(OperationDescription operationDescription)
            {
            }
        }
        public static void Test()
        {
            string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
            ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
            var endpoint = host.AddServiceEndpoint(typeof(ITest), new WebHttpBinding(), "");
            endpoint.Behaviors.Add(new WebHttpBehavior());
            host.Open();
            Console.WriteLine("Host opened");
    
            WebClient c = new WebClient();
            Console.WriteLine(c.DownloadString(baseAddress + "/Echo?text=Hello%20world"));
    
            c = new WebClient();
            c.Headers[HttpRequestHeader.ContentType] = "application/json";
            Console.WriteLine(c.UploadString(baseAddress + "/Divide", "{\"x\":12,\"y\":0}"));
    
            Console.Write("Press ENTER to close the host");
            Console.ReadLine();
            host.Close();
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2012-07-16
      • 2014-05-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-11
      • 1970-01-01
      相关资源
      最近更新 更多