Linked In Twitter RSS

Request throttling in ASP.NET Web API

3. March 2012  · Comments (1)

 

Real world scenario

 

When you start to build real world REST API you will surely try to limit access to you API. You can limit number of concurrent requests by using http://www.iis.net/download/dynamiciprestrictions

or some other tools.

 

In this post I will try to limit access to my ASP.NET Web API by using my own code building my own custom DelegatingHandler.

 

What you will see here

 

In this code bellow is ThrottleRateHandler that will be used to limit number of calls to your API in hour. Also these same code will limit how many times you can call API in seconds.

These class is using code similar as StackOverflow has used for their throttle rate handler.

Also these code is based on Token authorization approach.

 

I will also use HTTPRuntime.Cache to implement this functionality. I plan for my real world REST API to use MemBase caching. So question for my readers: Is it smart to replace HTTPRuntime.Cache with MemBase later ?

 

Here is code for ThrottleRateHandler :

public class ThrottleRateHandler : DelegatingHandler
    {
        protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
        {
            string query = request.RequestUri.Query;
            string accessToken = HttpUtility.ParseQueryString(query).Get("accessToken");
            double seconds = Convert.ToDouble(WebConfigurationManager.AppSettings["throttleTimeoutForMethodCall"]);
            int numberRequests = Convert.ToInt32(WebConfigurationManager.AppSettings["tokenRequestsPerHour"]);

            if (accessToken != null)
            {
                var throttleKey = string.Format(
                    "{0}-{1}", request.RequestUri.AbsolutePath, accessToken);
                var tokenKey = accessToken;
                var allowExecute = false;

                if (HttpRuntime.Cache[throttleKey] == null)
                {
                    // this check was added for integration testing
                    if (!seconds.Equals(0.0))
                    {
                        HttpRuntime.Cache.Add(
                            throttleKey,
                            true,
                            null,
                            DateTime.Now.AddSeconds(seconds),
                            Cache.NoSlidingExpiration,
                            CacheItemPriority.Low,
                            null);
                    }

                    allowExecute = true;
                }

                if (allowExecute)
                {
                    var hit = (HitInfo)(HttpRuntime.Cache[tokenKey] jQuery152020203585348297026_1330795835814 new HitInfo());

                    if (hit.Hits > numberRequests)
                    {
                        allowExecute = false;
                    }
                    else
                    {
                        hit.Hits++;
                    }

                    if (hit.Hits == 1)
                    {
                        HttpRuntime.Cache.Add(
                            tokenKey,
                            hit,
                            null,
                            DateTime.Now.AddMinutes(60),
                            Cache.NoSlidingExpiration,
                            CacheItemPriority.AboveNormal,
                            null);
                    }

                    if (!allowExecute)
                    {
                        return this.ReturnException(string.Format("You can call API {0} times per hour", numberRequests));
                    }
                }
                else
                {
                   return this.ReturnException(string.Format("You can call API every {0} seconds", seconds));
                }
            }
            else
            {
                var response = new HttpResponseMessage
                {
                    Content =
                        new StringContent("You must supply valid token to access method!"),
                    StatusCode = HttpStatusCode.Unauthorized
                };
                return Task<HttpResponseMessage>.Factory.StartNew(() => response);
            }

            return base.SendAsync(request, cancellationToken);
        }

        private Task<HttpResponseMessage> ReturnException(string message)
        {
            var response = new HttpResponseMessage
            {
                Content = new StringContent(message),
                StatusCode = HttpStatusCode.Conflict
            };
            return Task<HttpResponseMessage>.Factory.StartNew(() => response);
        }

        public class HitInfo
        {
            public HitInfo()
            {
                Hits = 1;
            }

            public string Token { get; set; }
            public int Hits { get; set; }
        }
    }

ASP.NET Web API Authorization using Tokens

3. March 2012  · Comments (11)

 

Planning real world REST API

 

When you try to plan how to build real world REST API like other major players like Facebook or Foursquare have you will soon realize that all major players use OAuth 2.0 .

ASP.NET Web API comes with support for authorize attribute and that’s nice, but for real world API I want to support token based approach.

 

OAuth 2.0 Server

 

For supporting token based approach  you must have some kind of server that will issue tokens. Building token server can be complex and most major players have implemented OAuth 2.0 server based on draft 10 OAuth documentation.

We hope that Microsoft will provide us with their own OAuth 2.0 server for free in final version of ASP.NET MVC 4.

Meanwhile I will just assume that you already have your own OAuth 2.0 server.

 

Building ActionFilterAttribute

 

I have solved my problem with authorization by implementing RequireAuthorize ActionFilterAttribute. This attribute also have scope property. Scope property is used for limiting access to your REST API.

 

You just need to decorate controllers or actions in controllers with this attribute and optionally set required scope for accessing these actions.

 

Here is RequireAuthorizeAtribute:

public class RequireAuthorization : ActionFilterAttribute
    {
        public string Scope { get; set; }

        public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
        {
            string[] scope = null;
            if (!string.IsNullOrEmpty(Scope))
            {
                scope = Scope.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries);
            }

            string query = actionContext.Request.RequestUri.Query;
            string accessToken = HttpUtility.ParseQueryString(query).Get("accessToken");

            // we first check for valid token
            if (accessToken != null)
            {
                IAccessTokenValidator accessTokenValidator = new AccessTokenValidator();
                bool validToken = accessTokenValidator.ValidateToken(accessToken, scope);

                if (!validToken)
                {
                    var response = new HttpResponseMessage
                    {
                        Content =
                            new StringContent("This token is not valid, please refresh token or obtain valid token!"),
                        StatusCode = HttpStatusCode.Unauthorized
                    };
                    throw new HttpResponseException(response);
                }
            }
            else
            {
                var response = new HttpResponseMessage
                {
                    Content =
                        new StringContent("You must supply valid token to access method!"),
                    StatusCode = HttpStatusCode.Unauthorized
                };
                throw new HttpResponseException(response);
            }

            base.OnActionExecuting(actionContext);
        }
    }



And here is AccessTokenValidator class:

public class AccessTokenValidator : IAccessTokenValidator
    {
        public bool ValidateToken(string token, string[] scope)
        {
            // replace this logic with dataBase access to table with tokens
            if (token != "someToken")
            {
                return false;
            }
            return true;
        }
    }

Force JSON DelegatingHandler for ASP.NET Web API

3. March 2012  · Comments (0)

 

Building real world REST API-s

 

When you decide to build real world REST API-s like Facebook or Foursquare and many others have you must think on lot of things such as security, scoping, throttling and similar.

One of the first thing you will encounter is need to support various media formats such as JSON, XML, PNG … in easy way.

ASP.NET Web API support JSON and XML formats out of the box and provide us with easy way to support any custom mediaType format.

I will try to provide you with series of posts in which I will try to explain how I have created real world REST API using ASP.NET Web API.

 

Common ways to enforce custom format

 

There are several ways to enforce custom format in REST API :

1) You can pass mediaType in request header .

2) You can pass mediaType in URI using following syntax : http://api.mySite.com/v1/contacts/1/JSON

3) You can pass mediaType in URI using following syntax : http://api.mySite.com/v1/contacts/1.JSON

4) You can pass mediaType in URI using following syntax : http://api.mySite.com/v1/contacts/1?mediaType=JSON

 

 

My preferred solution using ASP.NET Web API

 

First approach – I will support 

In REST API you will sure want to support first approach in which user passes mediaType in request header.

Second approach – I will not support

For second approach things are little difficult .

To support this way you will probably need to change routes like this where you pass optional parameter ext for mediaType extension :

config.Routes.MapHttpRoute(
                "Default", 
                "{controller}/{id}/{ext}", 
                new { id = RouteParameter.Optional, ext = RouteParameter.Optional } 
            );

Problem with this approach is that your code will only work for URI like this where you try to get particular contact with id 1 in JSON format:

http://api.mySite.com/v1/contacts/1/JSON

When you try to get all contacts in JSON format using URI like this it will fail:

http://api.mySite.com/v1/contacts/JSON

Instead of trying to get all contacts in that format in will try to find contact which has id with value “JSON” .

One possible way to resolve this is to have two controllers for same model. One called ContactController another ContactsController.

I just don’t prefer this solution. If you know any other solution to resolve this feel free to comment. You can read more about this in this sites :

http://codebetter.com/glennblock/2012/02/28/why-are-there-2-controllers-in-the-asp-net-web-api-contactmanager-example-rest-has-nothing-to-with-it-2/

http://wekeroad.com/2012/02/28/someone-save-us-from-rest/

Third approach – I will not support

You may be wondering why it is so nice and clean? I don’t like dots in URI in that way. You cannot parse that QueryString safely to get that extensions behind dot.

You can try do something like this :

requestString.EndsWith(".JSON")

But then you will get another wall. In this version of ASP.NET Web API when you try to change Request.RequestUriinside DelegatingHandlers method SendAsync and pass changed RequestUri to base, ASP.NET Web API still try to goto old RequestUri. It seams like routing is performed before DelegatingHandler…So if we try to get mediaType in DelegatingHandler from RequestUri :

http://api.mySite.com/v1/contacts/1.JSON

then substring URI to become:

http://api.mySite.com/v1/contacts/1

and pass new RequestUri to base we will not be successful.

Fourth approach – I will support

I have choose to support fourth approach. For using this approach you will need to add this line of code in GlobalAsax.cs :

config.MessageHandlers.Add(new UriFormatExtensionMessageHandler());

Here is my code for UriFormatExtensionMessageHandler :

public class UriFormatExtensionMessageHandler : DelegatingHandler
   {    
       private bool shouldForceJson;
       private bool sholudForceXml;
       public void CheckFormats(HttpRequestMessage request)
       {
           // uri must contain mediaType parameter to enforce that media type
           string query = request.RequestUri.Query;
           string mediaType = HttpUtility.ParseQueryString(query).Get("mediaType");
           if (mediaType != null)
           {
               switch (mediaType)
               {
                   case "JSON":
                       shouldForceJson = true;
                       break;
                   case "XML":
                       sholudForceXml = true;
                       break;
               }
           }
       }

protected override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, 
System.Threading.CancellationToken cancellationToken)
       {
           CheckFormats(request);
           if (shouldForceJson)
           {
               // clear the accept and replace it to use JSON.
               request.Headers.Accept.Clear();
               request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
               shouldForceJson = false;
           }

           if (sholudForceXml)
           {
               request.Headers.Accept.Clear();
               request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));
               sholudForceXml = false;
           }
             
           return base.SendAsync(request, cancellationToken);
       }
   }

UPDATE :

For fourth approach Microsoft has provided solution in this version of WebApi.You should you code bellow :

config.Formatters.JsonFormatter.MediaTypeMappings.Add(
              new QueryStringMapping("mediaType", "json", "application/json"));

            config.Formatters.XmlFormatter.MediaTypeMappings.Add(
               new QueryStringMapping("mediaType", "xml", "application/xml"));
 

Blog Redesign

7. October 2011  · Comments (1)

 

Blog design revamped

 

I have decided after long period of not blogging to start over again and best thing you can do for fresh start is to redesign your blog. My choice this time is light background instead of dark background. It seams at least for me that is easier to read and focus on content on light backgrounds. This is tiny screenshot how my old blog looked like :

 

clip_image001

 

I have also tried to incorporate minimalistic approach but I don’t know if I have succeeded.

Because I am not designer I have hired designer to do all work for me. You will be able to contact him soon if you want by link in bottom of page “Designed by…” that I will insert in few days.

 

Migrate old content to new design

 

I have decided to not migrate old blog content to new design. What I am mean by migrate is to change “Syntax highlighting” for code, reposition pictures, content and insert missing H1,H2 headers for some posts and similar.

Because this is fresh start I want to start fresh and not go back to old content.

 

My writing focus

 

My old readers probably are aware that my focus was Silverlight and .NET development. I will continue to have focus on Silverlight because Silverlight probably will remain best technology for development intranet browser applications for long time.

I will also have strong focus on Kinect, Azure, Windows Phone and Win 8 development.

I have worked on some projects that involve these technologies and I will try to write about things I have learned on this blog.

 

Your comments?

 

What do you think about my new blog design and choice of my writing focus ?

Virtualization in Silverlight 4 RC

31. March 2010  · Comments (0)
Here is my new article about Virtualization in Silverlight 4 RC.

WPF Validation using Validation Application Block Part 2 – Client side

24. March 2010  · Comments (10)

This is second part of my article where I talk about Validation in WPF using Entlib Validation Application Block. First part of my article is located on this location : http://blog.developers.ba/post/2009/07/07/WPF-Validation-using-Validation-Application-Block-41-Part-1-e28093-Server-side.aspx

There are many articles about client side validation in WPF. Most of these articles are similar and use implementation of IDataErrorInfo interface on Model class.

I have use some methods  already described in other articles just to show you how easy it is to implement client side validation in WPF using VAB.

I have model class called Customer where I have implemented IDataErrorInfo. Code looks like this :

public string Error
{
get {
StringBuilder error = new StringBuilder();
ValidationResults results = Validation.ValidateFromAttributes<Customer>(this);
foreach (ValidationResult result in results)
{
error.AppendLine(result.Message);
}
return error.ToString() ;
}
}
public string this[string columnName]
{
get {
ValidationResults results = Validation.ValidateFromAttributes<Customer>(this);
foreach (ValidationResult result in results)
{
if (result.Key == columnName)
{
return result.Message;
}
}
return string.Empty;
}
}

I have called ValidateFromAttributes method of Validation class that exists in VAB to get collection of ValidationResults. It is easy as that.

In Application.Resources of my WPF application I have defined some textbox error template and style to use when validation error is occurred. For this I have borrowed some code from other articles to save on time writing templates and styles.

And final in xaml on textboxes I have added following code where I have turn on Validation and defined witch error template to use :

<TextBox x:Name="txtFirstName"  Grid.Column="1"  TextWrapping="Wrap" 
Text="{Binding FirstName, ValidatesOnDataErrors=True}" Validation.ErrorTemplate="{StaticResource TextBoxErrorTemplate}" />

References :

http://msdn.microsoft.com/en-us/magazine/cc700358.aspx

http://www.eggheadcafe.com/tutorials/aspnet/f726cd7d-cfcc-43c3-85d8-2afc75e7a08a/wpf-input-validation-with.aspx

Here is updated code in VS2010RC :ValidationServiceWCF.rar

WCF net.tcp protocol in Silverlight 4

11. December 2009  · Comments (0)
Here is my new article about WCF net.tcp protocol in Silverlight 4  link

Skinning and Styling Silverlight Controls

11. November 2009  · Comments (0)

I have a new article on about skinning and styling Silverlight Controls on Silverlightshow. Check it out on link

Unit testing Facade pattern

31. October 2009  · Comments (6)

The facade pattern is commonly used software engineering design pattern. His purpose is to provide simplified interface to a larger body of code.

It has several good uses:

- Make a software library easier to use and understand, since the facade has convenient methods for common tasks.
- Make code that uses the library more readable, for the same reason.
- Reduce dependencies of outside code on the inner workings of a library, since most code uses the facade, thus allowing more flexibility in developing the system.
- Wrap a poorly-designed collection of APIs with a single well-designed API (as per task needs).

Importance of this Design pattern we cannot underestimate.

In unit testing one of good practice is to put our dependencies in constructor of class. Facade pattern class however cannot have dependencies in constructor because it increase complexity of code.

In this blog post I will show you how to unit test facade pattern.

If I have 2 classes : EmailLogger and DatabaseLogger  and these two classes have same porpoise to Log same data.

These two classes have dependencies on another classes.

I want to have one class that I will call Logger with one method called Log that will be Facade for these two classes.

Class EmailLogger looks like this :

public class EmailLogger:ILogger
{
private readonly IEmailProxy _emailProxy;
public EmailLogger(IEmailProxy emailProxy)
{
_emailProxy = emailProxy;
}
public void Log(string message)
{
if(_emailProxy!=null)
{
_emailProxy.SendEmail(message);
}
else
{
throw new ArgumentNullException("_emailProxy");
}
}
}

 

This class have dependency on another class called EmailProxy and accepts interface IEmailProxy in constructor.

Class DatabaseLogger looks similar to EmailLogger :

 

public class DatabaseLogger:ILogger
{
private readonly IDatabaseMechanism _databaseMechanism;
public DatabaseLogger(IDatabaseMechanism databaseMechanism)
{
_databaseMechanism = databaseMechanism;
}
public void Log(string message)
{
if(_databaseMechanism!=null)
{
_databaseMechanism.SendLogToDatabase(message);
}
else
{
throw new ArgumentNullException("_databaseMechanism");
}
}
}

 

This class have dependency on class called DatabaseMechanism and accepts another interface IDatabaseMechanism in constructor.

And finally we have class called Logger that will be Facade for these two classes .

In this example I will use singleton implementation Unity container and Rhino Mocks.

 

public class Logger:ILogger
{
private readonly ILogger _emailLogger;
private readonly ILogger _databaseLogger;
public Logger()
{
IContainer container = new UnityContainer();
_emailLogger = container.Resolve<ILogger>("EmailLogger");
_databaseLogger = container.Resolve<ILogger>("DatabaseLogger");
}
public void Log(string message)
{
if(_emailLogger!=null)
{
_emailLogger.Log(message);
}
else
{
throw new ArgumentNullException("_emailLogger");
}
if (_databaseLogger != null)
{
_databaseLogger.Log(message);
}
else
{
throw new ArgumentNullException("_databaseLogger");
}
}
}

 

And of course we need to have some registration in container in some BootStraper class :

 

public static class BootStraper
{
public static void SetUp()
{
IContainer container = UnityContainer.Instance();
container.RegisterType<IEmailProxy,EmailProxy>();
container.RegisterType<IDatabaseMechanism,DatabaseMechanism>();
container.RegisterType<ILogger,EmailLogger>("EmailLogger");
container.RegisterType<ILogger,DatabaseLogger>("DatabaseLogger");
}
}

 

Consuming this class is simple :

 

public class Consume
{
public void ConsumeLogger()
{
Bootstraper.SetUp();
ILogger logger=new Logger();
logger.Log("Some message");
}
}

 

Code is simple and understandable and we don’t need to use any container to call this class . If someone reference your dll it can use your code without any container registration or resolve . You just call  method in that class and he not see container calls and deeper logic inside this Facade class.

And finally test is very simple too :

 

[TestClass]
public class LoggerTests
{
private readonly ILogger _emailLogger;
private readonly ILogger _databaseLogger;
private readonly IContainer _container;
public LoggerTests()
{
_container = UnityContainer.Instance();
_emailLogger = MockRepository.GenerateMock<ILogger>();
_databaseLogger = MockRepository.GenerateMock<ILogger>();
_container.RegisterInstance<ILogger>("EmailLogger", _emailLogger);
_container.RegisterInstance<ILogger>("DatabaseLogger", _databaseLogger);
}
[TestMethod]
public void Log_AcceptCorrectArgs_CallsEmailLoggerLog()
{
//arrange
ILogger logger = new Logger();
//act
logger.Log("Something");
ILogger emailLogger = _container.Resolve<ILogger>("EmailLogger");
//assert
emailLogger.AssertWasCalled(x => x.Log("Something"));
}
}

 

We register instance of mock objects EmailLogger and DataBaseLogger in Container and resolve later in test to ensure that correct method of mock object is called.

I hope this will help you in some of your projects.

Silverlight 3 FireStarter LiveMeeting Event September 17th

8. September 2009  · Comments (0)

This summer’s biggest blockbuster technology event is coming to Redmond, WA on the 17th of September. 

Register to attend the Silverlight-3 FireStarter event on Thursday, the 17th of September. We have a stellar speaker line up from the Microsoft roster. We will have Scott Guthrie keynote the event followed by presentations from Tim Heuer, Brad Abrams, Karl Shifflett and others...

 At this event we will focus on three areas:

 What’s latest and greatest in with the latest release of Silverlight

 What’s happening in the world of Expression 3, and

 Give you a run down on .NET RIA Services, Toolkit, etc. 

 

Time

Session

Speaker

8:45 – 9:00 AM

Event Kick off

Mithun Dhar

9:00 – 10:00 AM

Keynote

Scott Guthrie

10:00 – 11:00 AM

Key Silverlight Scenarios

Tim Heuer

11:00 – 11:15 AM

Break

 

11:15 AM – 12:15 PM

Expression 3 Overview (Includes Behaviors)

Adam Kinney

12:15 – 1:00 PM

Lunch Break (Provided by Microsoft)

 

1:00 – 1:30 PM

Sketch Flow

Janete Perez

1:30 – 2:30 PM

Toolkit & Controls

Justin Angel/Shawn Oster

2:30 – 3:30 PM

RIA Services

Brad Abrams

3:30 – 3:45 PM

Break

 

3:45 – 4:30 PM

Building Silverlight UIs with XAML Power toys

Karl Shifflett

4:30 – 5:00 PM

Q & A Panel

All Speakers

 

Registrations:

Source:
http://blogs.msdn.com/mithund/archive/2009/08/12/silverlight-3-firestarter-thursday-september-17th-2009-attend-redmond-wa-or-online-must-register.aspx