OpenLightGroup Blog

rss

Blogs from OpenLightGroup.net


Calling OData From A Normal ASP.NET Page

 

image

OData is basically like web services but better because you do not have to keep updating your service end points. For example, if you expose a Customer entity (table) as a web service, you have to create a service end point such as GetCustomer(int CustomerID). When the consumers of your web service want to search for Customers by last name you have to add a new service end point.

With OData you only need to expose the Customer entity and practically all possible ways the consumers need to access the data is automatically taken care of.

Recently at work I advocated exposing a collection of data that the enterprise needed as OData. In this case I would be a consumer and I really wanted the flexibility OData provides. The question was asked as to how to secure it? I showed the code from this article: Simple Example To Secure WCF Data Service OData Methods. The problem with that example is that the consumer is a Silverlight control and most of the consumers are using standard ASP.NET web pages. I then showed them this article: A Full CRUD LightSwitch JQuery Mobile Application. The problem with that article is that it is inside LightSwitch and I am the only one using LightSwitch (so far Smile).

I looked for a simple example showing how to call OData from a normal ASP.NET page and could not find one, so I decided to make one.

The Service

image

We start with the service. You can download the code at the end of this blog, and you can play with it live at: http://odatasample.adefwebserver.com/. To understand how it works see the article: Simple Example To Secure WCF Data Service OData Methods.

When you use the dropdown to change users, a Forms Authentication cookie is created for the web browser. The Silverlight client automatically uses that cookie when making requests.

It you close the web browser and try to go directly to the service: http://odatasample.adefwebserver.com/Service.svc/SampleCustomerData you wont get any data:

image

If you go to the main page and use the dropdown to log in and then hit the service again, you will see data:

image

The code to protect the service is simple code that checks to see if you are logged in and what your username is and filters the data to only show the data that matches your user name:

    public IQueryable SampleCustomerData
    {
        get
        {
            // Ensure user is authenticated
            if (HttpContext.Current.User.Identity.IsAuthenticated)
            {
                // Get the current user
                string strUser = 
                    Convert.ToString(HttpContext.Current.User.Identity.Name);
                // Filter results
                var result =
                    _sampleCustomerRecordList.Where(x => x.CustomerID == strUser).ToList();
                // Return results
                return result.AsQueryable();
            }
            else
            {
                // Not Authenticated
                var result = new List();
                return result.AsQueryable();
            }
        }
    }

 

The difference between seeing data and not seeing data is based on what is returned by HttpContext.Current.User.Identity.Name and that is determined by the Forms authentication cookie.

Create A Forms Auth Ticket So You Can Create A Cookie

image

I added a page to the project called CreateCookie.aspx using the following code:

    protected void Page_Load(object sender, EventArgs e)
    {
        if (
            (Request.QueryString["UserName"] == "UserOne") 
            && (Request.QueryString["Password"] == "password")
            )
        {
            // Create cookie and return it
            FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1,
                "UserOne",
                DateTime.Now,
                DateTime.Now.AddDays(30),
                false,
                "Role One",
                FormsAuthentication.FormsCookiePath);
            // Encrypt the ticket.
            string encTicket = FormsAuthentication.Encrypt(ticket);
            // Create the cookie.
            Response.Write(encTicket);
            Response.End();
        }
    }

 

When you call the page with the proper username and password it returns the Forms Auth Ticket that you can use to create a valid cookie.

The Client

image

Now let’s look at the sample client code.

The first thing we do is add a service reference to the OData service at:

http://odatasample.adefwebserver.com/Service.svc (you cannot browse only to the .svc file in your web browser, but you can add a service reference to it)

When we click on the Get Cookie button we get a Forms Auth Ticket (cookie) using this code:

    protected void btnGetCookie_Click(object sender, EventArgs e)
    {
        string strBaseURL = String.Format(@"{0}/{1}", 
            txtODataServiceURL.Text, 
                @"CreateCookie.aspx?UserName=UserOne&Password=password");
        HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(strBaseURL);
        myRequest.Method = "GET";
        WebResponse myResponse = myRequest.GetResponse();
        StreamReader sr = 
            new StreamReader(myResponse.GetResponseStream(), System.Text.Encoding.UTF8);
        string result = sr.ReadToEnd();
        sr.Close();
        myResponse.Close();
        lblCookie.Text = String.Format("{0}", result);
    }

image

Once we have the Forms Auth Ticket, we can call the OData service using the following code:

    protected void btnCallOData_Click(object sender, EventArgs e)
    {
        string strBaseURL = txtODataServiceURL.Text;
        // Create DataContext
        ODataServiceReference.SampleDataSource objSampleDataSource =
            new ODataServiceReference.SampleDataSource(
                new Uri(string.Format(@"{0}/Service.svc/", strBaseURL)));
        // An event handler that will run when the call is being sent
        // We do this so we can add the cookie
        objSampleDataSource.SendingRequest += objSampleDataSource_SendingRequest;
        // Query OData source
        var result = from CustomerData in objSampleDataSource.SampleCustomerData
                     select CustomerData;
        // Bind the data to te DataGrid
        gvDataGrid.DataSource = result;
        gvDataGrid.DataBind();
    }
    void objSampleDataSource_SendingRequest(object sender, 
        System.Data.Services.Client.SendingRequestEventArgs e)
    {
        // Create a Cookie
        Cookie objCookie = new Cookie();
        // Set the values
        objCookie.Domain = txtODataServiceURL.Text.Replace(@"http://", "");
        objCookie.Expires = DateTime.Now.AddMinutes(20);
        objCookie.HttpOnly = false;
        objCookie.Name = ".ASPXAUTH";
        objCookie.Path = @"/";
        objCookie.Secure = false;
        objCookie.Value = lblCookie.Text; // The Forms Auth Ticket
        // Create a Cookie container and put the Cookie inside
        ((HttpWebRequest)e.Request).CookieContainer = new CookieContainer();
        ((HttpWebRequest)e.Request).CookieContainer.Add(objCookie);
    }

More Information

OData and Authentication

Download Code

ODataClientNew.zip

ODataSampleNew.zip





Comments are closed.