我正在尝试使用内存中对象图创建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; }
}
}
答案 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?