使用内存中对象创建WCF数据服务操作

时间:2012-08-24 10:58:22

标签: wcf wcf-data-services

我正在尝试使用内存中对象图创建WCF DataService。这意味着后端不是实体框架存储,而是驻留在内存中的一堆对象。

我正在尝试创建名为 GetUsersByName 的服务操作,该操作具有name的单个参数,并将匹配的用户作为IQueryable集合返回。

我按照文档添加了此操作的访问规则

config.SetServiceOperationAccessRule("GetUsersByName", ServiceOperationRights.All);

但是当调用 SetServiceOperationAccessRule 方法时,我在客户端上收到一个异常:

System.AggregateException was unhandled.

以下是我的控制台应用程序的完整代码

    using System;
    using System.ServiceModel;
    using System.ServiceModel.Web;
    using System.ServiceModel.Description;
    using System.Data.Services;
    using System.Data.Services.Common;
    using System.Collections.Generic;
    using System.Runtime.Serialization;
    using System.Collections.ObjectModel;
    using System.Linq;
    using System.Web;
    using System.Net.Http;
    using System.Net;
    using System.IO; 

    namespace WCF_OData
    {

        class Program
        {
            static void Main(string[] args)
            {
                string serviceAddress = "http://localhost:8080";
                Uri[] uriArray = { new Uri(serviceAddress) };
                Type serviceType = typeof(UserDataService);

                using (var host = new DataServiceHost(serviceType, uriArray)) {
                    host.Open();

                    var client = new HttpClient() { BaseAddress = new Uri(serviceAddress) };
                    Console.WriteLine("Client received: {0}", client.GetStringAsync("Users?$format=json").Result);

                    HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://localhost:8080");
                    request.Method = "GET";
                    request.Accept = @"application/json";

                    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                    {
                        Console.WriteLine(response.StatusCode);
                        Console.WriteLine(response.ContentType);
                        Console.WriteLine((new StreamReader(response.GetResponseStream())).ReadToEnd());
                    }

                    Console.WriteLine("Press any key to stop service");
                    Console.ReadKey();
                }

            }
        }

        [EnableJsonSupport]
        [ServiceBehavior(IncludeExceptionDetailInFaults = true)]   
        public class UserDataService : DataService<UserService> {
            public static void InitializeService(DataServiceConfiguration config)
            {
                config.SetEntitySetAccessRule("Users", EntitySetRights.All);
                config.SetServiceOperationAccessRule("GetUsersByName", ServiceOperationRights.All);

                config.UseVerboseErrors = true;

                config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
            }

        }

        public class UserService
        {
            private List<User> _List = new List<User>();

            public UserService()
            {
                _List.Add(new User() { ID = 1, UserName = "John Doe" });
                _List.Add(new User() { ID = 2, UserName = "Jane Doe" });
            }

            public IQueryable<User> Users
            {
                get
                {
                    HttpContext x = HttpContext.Current;
                    return _List.AsQueryable<User>();
                }
            }

            [OperationContract]
            [WebGet(UriTemplate="GetUsersByName")]
            public IQueryable<User> GetUsersByName(string name)
            {
                return new List<User>().AsQueryable(); 
            }
        }

        [DataServiceKey("ID")]
        public class User
        {
            public int ID { get; set; } 
            public string UserName { get; set; }
        }
    }

1 个答案:

答案 0 :(得分:1)

看起来这里有一些事情,所以这可能需要几次迭代才能完成。应该修复的第一个问题是服务操作。需要在继承自DataService的类上声明服务操作:"Service operations are methods added to the data service class that derives from DataService"。这是一个示例:

using System.Data.Entity;
using System.Data.Services;
using System.Data.Services.Common;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Web;

namespace Scratch.Web
{
    [ServiceBehavior(IncludeExceptionDetailInFaults = true)]
    public class ScratchService : DataService<ScratchEntityFrameworkContext>
    {
        static ScratchService()
        {
            Database.SetInitializer(new ScratchEntityFrameworkContextInitializer());
        }

        public static void InitializeService(DataServiceConfiguration config)
        {
            config.SetEntitySetAccessRule("*", EntitySetRights.All);
            config.SetServiceOperationAccessRule("*", ServiceOperationRights.AllRead);
            config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3;
            config.UseVerboseErrors = true;
        }

        [WebGet]
        public IQueryable<Product> FuzzySearch(string idStartsWith)
        {
            var context = new ScratchEntityFrameworkContext();
            return context.Products.ToList().Where(p => p.ID.ToString().StartsWith(idStartsWith)).AsQueryable();
        }
    }
}

然后,您应该可以从浏览器调用您的服务操作,其URL格式类似于以下内容:http://localhost:59803/ScratchService.svc/FuzzySearch()?idStartsWith='1'

我们可以先尝试在浏览器中运行此功能,然后查看是否仍然发生AggregateException?