OData Programming Cookbook for .NET Developers
上QQ阅读APP看书,第一时间看更新

Accessing ASP.NET context data in WCF Data Service

OData protocol is naturally based on HTTP and other web standards. OData services built with WCF Data Service are often hosted in an ASP.NET web application. Therefore, it is quite possible that a WCF Data Service is deployed side-by-side with many other web resources, such as ASP.NET web pages, ASMX web services, and HTTP handlers. ASP.NET web pages can access many ASP.NET runtime specific context data such as session states, client user info, application states, cache, and HTTP request headers. Is this also possible for WCF Data Services (hosted in ASP.NET web applications)?

Well, this can be easily achieved with the current WCF Data Service programming model. In this recipe, we will introduce how to access ASP.NET context data in WCF Data Service code.

Getting ready

In this recipe, we will create a WCF Data Service, which will expose the session states and HTTP client user headers (of the ASP.NET host web application) as entity sets to the service callers. Also, to make the service code simple and clear, we will use custom CLR types instead of a ADO.NET Entity Framework data model as the service data source.

The source code for this recipe can be found in the \ch01\WebContextDataServiceSln\ directory.

How to do it...

  1. Create a new ASP.NET Empty Web Application.
  2. Define the custom classes, which will be used as entity types and data context type of the sample WCF Data Service.

    The following is the complete definition of the ClientInfoEntity and SessionItemEntity entity types in this sample:

    [DataServiceEntity]
    [DataServiceKey("ID")]
    public class ClientInfoEntity
    {
    public int ID { get; set; }
    public string IPAddress { get; set; }
    public string UserAgent { get; set; }
    public bool Authenticated { get; set; }
    }
    [DataServiceEntity]
    [DataServiceKey("KeyName")]
    public class SessionItemEntity
    {
    public string KeyName { get; set; }
    public string TypeName { get; set; }
    }
    

    The following WebContextEntityContainer class is used as the service data context (the container of the two sample entity sets):

    public class WebContextEntityContainer
    {
    public IQueryable<SessionItemEntity> SessionItems {
    get
    {
    var items = new List<SessionItemEntity>();
    foreach (string key in HttpContext.Current.Session.Keys)
    {
    var item = new SessionItemEntity()
    {
    KeyName = key,
    TypeName = HttpContext.Current.Session[key]. GetType().FullName
    };
    items.Add(item);
    }
    return items.AsQueryable();
    }
    }
    public IQueryable<ClientInfoEntity> ClientInfos {
    get
    {
    var req = HttpContext.Current.Request;
    var clientInfo = new ClientInfoEntity()
    {
    ID = 1,
    Authenticated = req.IsAuthenticated,
    IPAddress = req.UserHostAddress,
    UserAgent = req.UserAgent
    };
    return new ClientInfoEntity[]{clientInfo}.AsQueryable();
    }
    }
    }
    
  3. Create a new WCF Data Service and use the WebContextEntityContainer class as a data source (see the following code snippet).
    public class ContextInfoDataService : DataService< WebContextEntityContainer >
    {
    ..
    }
    
  4. Launch the service in the web browser and query the two entity sets, which return data specific to the current ASP.NET context.

    We can access the SessionItems and ClientInfos entity sets through the following URI addresses:

    • http://[server]:[port]/ContextInfoDataService.svc/SessionItems
    • http://[server]:[port]/ContextInfoDataService.svc/ClientInfos

    The following screenshot shows the query output of the first (also the only) entity instance from the ClientInfos entity set:

How to do it...

How it works...

The WCF Service programming model provides built-in support for service code to access ASP.NET context data in case the service is hosted in an ASP.NET web application. Since WCF Data Service is a special implementation of WCF Service, accessing ASP.NET context data in WCF Data Service code is naturally supported too. Actually, whenever a new WCF Data Service is created in Visual Studio (within an ASP.NET web project), the IDE will automatically enable the ASP.NET Compatibility mode (see the following screenshot) in the web.config file, which is necessary for WCF Service (also WCF Data Service) to access ASP.NET context data of the hosting web application.

How it works...

For demonstration purposes, our sample ASP.NET web application also contains a simple ASP.NET web page, which will help in generating some test session states data (see the following InitSession page class).

public partial class InitSession : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (Session.Count == 0)
{
Session.Add("string item", "some text");
Session.Add("int item", 120);
Session.Add("boolean item", true);
Session.Add("date item", DateTime.Now);
Session.Add("array item", new int[]{1,2,3});
}
}
}

See also

  • Using custom data objects as the data source of WCF Data Service recipe