和可以在客户端直接使用的查询对应,在服务端也有很多可以增强的功能
Service Operations
自己发布一些业务逻辑的处理
Service operations enable you to expose business logic in a data service, such as to implement validation logic, to apply role-based security, or to expose specialized querying capabilities.
具体要求如返回值、参数等参考MSDN,定义这些操作只要遵守这个要求即可
例子
实现自定义的条件查询
· http://localhost:12345/Northwind.svc/GetOrdersByCity?city='London'
· http://localhost:12345/Northwind.svc/GetOrdersByCity?city='London'&$top=2
[WebGet]
public IQueryable<Order> GetOrdersByCity(string city)
{
if (string.IsNullOrEmpty(city))
{
throw new ArgumentNullException("city",
"You must provide a value for the parameter'city'.");
}
// Get the ObjectContext that is the data source for the service.
NorthwindEntities context = this.CurrentDataSource;
try
{
var selectedOrders = from order in context.Orders.Include("Order_Details")
where order.Customer.City == city
select order;
return selectedOrders;
}
catch (Exception ex)
{
throw new ApplicationException("An error occured: {0}", ex);
}
}
Interceptors
拦截请求,这样可以加入自己的业务处理逻辑。目前系统预定义的有两个:
QueryInterceptor:由于限制查询的实体数据范围使用
ChangeInterceptor:修改实体时使用
WCF Data Services enables an application to intercept request messages so that you can add custom logic to an operation. You can use this custom logic to validate data in incoming messages. You can also use it to further restrict the scope of a query request, such as to insert a custom authorization policy on a per request basis.
Interception is performed by specially attributed methods in the data service. These methods are called by WCF Data Services at the appropriate point in message processing. Interceptors are defined on a per-entity set basis, and interceptor methods cannot accept parameters from the request like service operations can.
Query interceptor methods, which are called when processing an HTTP GET request, must return a lambda expression that determines whether an instance of the interceptor's entity set should be returned by the query results. This expression is used by the data service to further refine the requested operation.
例子
[QueryInterceptor("Orders")]
public Expression<Func<Order, bool>> OnQueryOrders()
{
// Filter the returned orders to only orders // that belong to a customer that is the current user.return o => o.Customer.ContactName ==
HttpContext.Current.User.Identity.Name;
}
[ChangeInterceptor("Products")]
public void OnChangeProducts(Product product, UpdateOperations operations)
{
if (operations == UpdateOperations.Add ||
operations == UpdateOperations.Change)
{
// Reject changes to discontinued products.if (product.Discontinued)
{
throw new DataServiceException(400,
"A discontinued product cannot be modified");
}
}
else if (operations == UpdateOperations.Delete)
{
// Block the delete and instead set the Discontinued flag.
throw new DataServiceException(400,
"Products cannot be deleted; instead set the Discontinued flag to 'true'");
}
}
Data Service Provider
应用中我们一般使用的是Entity Framework provider[edmx],从数据库生成模型或则从模型建立数据库都可以
由于Provider模型的强大功能,当然我们也可以自己实现一个Provider,如下例,是一个类实现的实例:
namespace DataServices
{
[DataServiceKey("Name")]
public class Inductee
{
public string Name { get; set; }
public bool Group { get; set; }
public int YearInducted { get; set; }
public List<Song> Songs { get; set; }
public static List<Inductee> MakeInducteeList()
{
return (new List<Inductee>()
{
new Inductee()
{
Name = "Rolling Stones",
Group = false,
YearInducted = 1990,
Songs = new List<Song>()
},
new Inductee()
{
Name = "Beatles",
Group = false,
YearInducted = 1986,
Songs = new List<Song>()
}
});
}
}
[DataServiceKey("SongTitle")]
public class Song
{
public string SongTitle { get; set; }
public static List<Song> MakeSongList()
{
return (new List<Song>()
{
new Song(){SongTitle="Satisfaction"},
new Song(){SongTitle="All you need is love"},
});
}
}
public class AssignInducteesToSongs
{
public static void Assign(List<Inductee> inductee, List<Song> songs)
{
inductee[0].Songs.Add(songs[0]);
inductee[1].Songs.Add(songs[1]);
}
}
/// <summary>
/// Summary description for MyDataModel
/// </summary>
public class MyDataModel
{
static List<Inductee> inductees;
static List<Song> songs;
static MyDataModel()
{
inductees = Inductee.MakeInducteeList();
songs = Song.MakeSongList();
AssignInducteesToSongs.Assign(inductees, songs);
}
public IQueryable<Inductee> Inductees
{
get
{
return inductees.AsQueryable();
}
}
public IQueryable<Song> Songs
{
get
{
return songs.AsQueryable();
}
}
}
//服务
[System.ServiceModel.ServiceBehavior(IncludeExceptionDetailInFaults = true)]
public class DemoOb : DataService<MyDataModel>
{
public static void InitializeService(DataServiceConfiguration config)
{
config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);
config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
}
}
这个服务发布后,就可以使用“WCF Data Services查询”的方法和客户端查询进行使用了。
该例子可以在http://dskit.codeplex.com 下载
Hosting
一般的服务承载在IIS中,以svc扩展名有IIS的HTTPHandler进行处理就行了
不过有时可能需要自己承载服务,此时就使用WCF的技术就行了
Using System.ServiceModel.Web;
WebServiceHost host = new WebServiceHost(typeof(SampleDataService));
host.Open();
其他的关于WCF的ABC只要在app.config中设置就行了