Wednesday, April 4, 2012

ASP.NET + IIS + DNS Records = Sub Domain on the fly

Whenever any web portal provide hosted service, at that time publishing it through sub domain is the most convenient and preferable way. There are many such free hosted services are available on the internet. For e.g. blogger.com and wordpress.com for blog services. If you have noticed, in such portal, whenever user register for a service at that time it ask for a preferable sub domain, and upon choosing sub domain, service start instantly without waiting for DNS propagation compared to normal sub domain creation scenario.

Few days back one of my friend asked me how to achieve same with ASP.NET. So here we will see how we can achieve same with ASP.NET, IIS, and DNS tweaks. However this post is less about ASP.NET and more about IIS and DNS configuration except IIS Metabase entry automation through ASP.NET. Whole tutorial is divided in three parts: IIS setup, DNS Setup, and IIS Automation through ASP.NET

I have tested all below setup with IIS 7 on windows 7 and Windows Server 2008 Standard Edition.

IIS Setup

1) Create one website named domain.com in IIS and edit website binding to include domain.com and www.domain.com as host header.

This website will act as public site through which user can register and manage their account and services.

2) Create one more website named service.domain.com and host actual service application on this website. For e.g. if you are providing hosted blog service then host your blog application on this website.

DNS Setup

So far we are done with IIS setup. Now we need to configure DNS record. Open your domain control panel and go to DNS manager.

1) Add following A records for domain.com and www.domain.com which point to IIS server IP address.

domain.com  IN A XXX.XXX.XXX.XXX
www.domain.com  IN A XXX.XXX.XXX.XXX
service.domain.com IN A XXX.XXX.XXX.XXX

First two entries will ensure that whenever user browse domain.com or www.domain.com at that time it will be routed to IIS server and rest will be take care by IIS and it will serve public site.

Third entry in above is necessary for next step.

2) Now add following wildcard CNAME record.

*.domain.com  IN CNAME service.domain.com

Above wildcard entry ensure that any sub domain request for domain.com will be routed to server which is pointed by service.domain.com.

So we have setup DNS records to route any sub domain request to IIS server. But still we have not done :) Now try to browse any sub domain let say user1.domain.com it will shows an error “The connection was reset” instead “Server not found”. It means our sub domain requests are routed to IIS server but IIS does not know about requested domain.

In step 1 of IIS setup, we have edited website binding to include domain.com and www.domain.com as host header, by this way we can tell IIS that any request from domain.com and www.domain.com will be handled by this particular website. So whenever user browse domain.com or www.domain.com it is serving public website without any problem. While in case of sub domain it is showing error that “The connection was reset” this is because IIS does not found host header entry for requested domain in any websites.

So we need to add host header entry in service.domain.com website created in step 2 of IIS setup because service.domain.com is actual website which is going to serve hosted service application when it is browse from sub domain.

Below is the code to add host header entry programmatically in IIS. I could not find right permission for application pool so I have set LocalSystem as an Application Pool identity. However in real time deployment, we can also create console application for below code which can be invoked from ASP.NET.

private string GetWebSiteId(string serverName, string websiteName)
{
    string result = "-1";

    DirectoryEntry w3svc = new DirectoryEntry(string.Format("IIS://{0}/w3svc", serverName));

    foreach (DirectoryEntry site in w3svc.Children)
    {
        if (site.Properties["ServerComment"] != null)
        {
            if (site.Properties["ServerComment"].Value != null)
            {
                if (string.Compare(site.Properties["ServerComment"].Value.ToString(),
                                        websiteName, true) == 0)
                {
                    result = site.Name;
                    break;
                }
            }
        }
    }

    return result;
}
        
private void AddHostHeader(string hostHeader, string websiteID)
{
    DirectoryEntry site = new DirectoryEntry("IIS://localhost/w3svc/" + websiteID);
    PropertyValueCollection serverBindings = site.Properties["ServerBindings"];

    serverBindings.Add(hostHeader);

    Object[] newList = new Object[serverBindings.Count];
    serverBindings.CopyTo(newList, 0);

    site.Properties["ServerBindings"].Value = newList;
    site.CommitChanges();
}   

AddHostHeader("127.0.0.1:80:user1.domain.com", GetWebSiteId("localhost", "service.domain.com"));

Put it all together

Let take quick review of how this all work together. So whenever any new user is registered at that time it will choose sub domain and application will add host header entry in IIS for chosen sub domain. Afterwards whenever that sub domain is requested, it will be routed to IIS with the help of DNS records and IIS will forward that request to service.domain.com website because there is a host header entry for requested sub domain. And service.domain.com website will identify user based on requested domain with the help of Request.Url.Host and it will load appropriate settings i.e. theme, module, etc.

Bad sub domain request and 404 handling

It may happen someone may try to access sub domain which is not registered with any user. In this case it will shows an error that "The connection was reset" because there is no host header entry for requested sub domain. We can tweak IIS to shows 404 not found page.

Create one more website and give any proper name to it. Now edit website binding to include empty host name as displayed in below image. This will instruct IIS that if IIS could not find host header entry in any websites then that request should be routed to this website.

Testing all above together on local machine

I am sure after reading this tutorial, one big question from many readers would be how to test this on single local machine without any live domain or DNS setup in LAN. Yes we can do! We can add entry in %systemroot%\System32\drivers\etc\hosts file however we cannot specify A record and CNAME records in this file. But still we can add following entry in hosts file so we can test this on local machine.

127.0.0.1 domain.com
127.0.0.1 www.domain.com

# Add each sub domain entry manually below for testing purpose

127.0.0.1 user1.domain.com
127.0.0.1 user2.domain.com

For each sub domain we need to add manually in this file because there is no wildcard support in hosts file.

Hope this would be helpful.

Nandip Makwana

About Nandip Makwana

Nandip Makwana is the modern day geek and is passionate about digital world and web. He completed Masters in Computer Application in June 2011. Currently he is working as a Jr. Software Engineer. He has shown great promise and command over ASP.NET and technologies surrounding it during his academic years and professional life...continue reading


Monday, March 26, 2012

Request Validation Mode in ASP .NET 4.5

Today I was examining request validation mode in ASP.NET 4.5 and observed some interesting behavior while using it with server control. With ASP.NET 4.5, Request Validation Mode introduced two new features called deferred or lazy request validation and access to unvalidated data.

Before ASP.NET 4.5, request validation was triggered either for each and every request data in beginning phase of request processing or if it is disabled then it triggers for none of them. In ASP.NET 4.5, lazy request validation feature is introduced which ensure that only required request data are validated only when it is accessed by code. To enable lazy request validation set requestValidationMode attribute to 4.5 in httpRuntime element in web.config.

<httpRuntime requestValidationMode="4.5" />

Once we set request validation mode to 4.5, request validation will be triggered for only request data which is accessed by code and only when it is actually executed by code. For e.g. If Request.Form["comment"] is accessed within button click event then only comment field will be validated when button click event fire if user does not click on button then it will not validate.

Another new feature introduced in request validation is that access to unvalidated data. In previous version of ASP.NET it was not possible to bypass request validation for selected request data. It was possible to disable request validation but there was no mechanism to access unvalidated data when request validation is enable. To enable this ASP.NET 4.5 introduced a new Unvalidated property within HttpRequest class which give access to request data without triggering request validation. For e.g. Request.Unvalidated.Form["comment"] will return raw data entered by user without triggering request validation on comment field. To use unvalidated data, you must set request validation mode to 4.5 in web.config.

So this was all about new request validation mode introduced in ASP.NET 4.5. More information on this can be found here. In starting of post, I mentioned that I observed some interesting behavior while using it with server control. So observed behavior is as follow.

I have created new webform application which target 4.5 framework and configured web.config to use newly introduced request validation mode by setting requestValidationMode attribute to 4.5.

Afterward I placed one ASP.NET textbox control and button control on the page and pressed F5 to run application and I entered potentially harmful data in textbox for e.g. <b>ASP.NET 4.5</b> and clicking on button it throw an exception "A potentially dangerous Request.Form value was detected… " I was shocked as I did not expected this exception because I have set requestValidationMode to 4.5 and I have not accessed textbox anywhere in code still it was triggering request validation! To cross verify I updated ValidateRequest value to false in @page directive and it works fine.

To continue with my experiment, i have reverted ValidateRequest value to again true in @page directive and added one HTML textbox control and entered same <b>ASP.NET 4.5</b> data into HTML textbox and clicked on button and it works fine because request validation mode was set to 4.5 and I have not accessed HTML textbox anywhere in the code. It was perfectly running fine with HTML textbox. Again to cross verify I updated request validation mode to 2.0 in web.config. and entered same potentially harmful data <b>ASP.NET 4.5</b> into HTML textbox and clicking on button it throw request validation exception "A potentially dangerous Request.Form value was detected… " this exception was expected because request validation mode was set to 2.0. Moving forward in my experiment, I again updated request validation mode to 4.5 in web.config and in button click event I accessed HTML textbox value with Request.Form["Text1"] and as expected after entering <b>ASP.NET 4.5</b> when clicked button it throw same exception because we accessed HTML textbox through code while request validation mode was set to 4.5.

So in short, what I observed is that while we have configured application to use request validation mode 4.5 at that time server control request validation triggers even if we have not accessed it anywhere in code. But the same thing does not apply to plain HTML control.

One more and last scenario to test. Again I added one more HTML textbox with runat server attribute and entered same data <b>ASP.NET 4.5</b> into this textbox and clicking on button again I shocked because it throw same exception even if request validation mode was set to 4.5 and I have not accessed it anywhere in code. But what I concluded is that it was due to runat server attribute because earlier we noticed same behavior with ASP.NET server textbox.

But still I was curious to know why request validation mode 4.5 is triggering request validation for server control. To dig more on it I examined stack trace for ASP.NET textbox and HTML textbox with runat server and what I observed is as follow.

Request validation exception generated by ASP.NET textbox

Request validation exception generated by HTML text with runat server

In above both stack trace, we can observe that along with server control lifecycle there is a call to Page.ProcessPostData method in stack trace and as name suggest that method might be processing posted data for server control only(as for HTML control request validation is not triggered so!) and as request validation mode 4.5 say it will trigger only when posted request data is accessed so this method might be accessing request data for server control and exception is thrown due to that access. I am not sure exactly that this is the only reason but it can be.

So what’s solution?

So what’s solution for this scenario? Whether it should validate server control or not while using request validation mode 4.5 and not accessing it through code? Ideally as per my personal view it should not validate server control because whether it is server control or plain HTML control, for client both are pure HTML controls and when requesting back to server it is the part of request data without differentiating that it is generated from ASP.NET server control or not.

Technically also it should not validate because when we set ValidateRequest value to false in @page directive at that time it is not validating server control so in this case also it should not validate server control during control lifecycle.

Textbox.Text and access to unvalidated data

So one more question is that while using request validation mode 4.5 at that time if user access Textbox.Text property then it should trigger request validation or not? Again as per my personal view and ideally it should because Textbox.Text property is exposing request data only so it should trigger request validation exception if it found potentially harmful data.

So now next question is that how to make access to unvalidated data through ASP.NET textbox? For that there can be new property called Textbox.UnValidatedText or something similar.

Any input on above is greatly appreciated.

UPDATE: 26-Mar-12

Today itself I came across a post which illustrates use of Control.ValidateRequestMode property introduced in ASP.NET 4.5. I could not find any detail about this newly introduced property in the release note till I am updating this post. So I missed to consider it and might be my oversight :) so stay tuned to next post till that happy debugging ;)

NOTE: All view expressed here is my own personal and it is not of Microsoft or my current or previous employers.

Nandip Makwana

About Nandip Makwana

Nandip Makwana is the modern day geek and is passionate about digital world and web. He completed Masters in Computer Application in June 2011. Currently he is working as a Jr. Software Engineer. He has shown great promise and command over ASP.NET and technologies surrounding it during his academic years and professional life...continue reading


Friday, March 23, 2012

IIS 8.0 Dynamic IP Address & Domains Restrictions

Yesterday, I attended session on IIS 8.0 on TechEd India 2012 Live. It was very interesting and informative. There are lots of enhancement in IIS 8.0 from IIS 7.0 right from application initialization to configuration, access restrictions, expanding CPU throttling, Non Uniform Memory Access (NUMA) hardware support, server name indication(SNI) and centralize SSL support for scalability and manageability and many other. Here I am going to post on Dynamic IP & Domains Restrictions feature which is introduced in IIS 8.0

Before IIS 8.0, server administrators could allow or deny access for specific IP address or range of IP addresses. But still finding IP address which cause mass attack was tedious task for server administrator as it involve analyzing IIS log periodically and manually add it to deny list if it found new IP address...

A solution to above problem is that instead of blocking IP based on addresses, we should block IP based on its activity. For e.g. maximum no of concurrent request, total no of request over a period of time, etc. Yes this is where IIS 8.0 and Dynamic IP Addresses & Domains Restrictions come in picture. Dynamic IP Addresses & Domains Restrictions feature of IIS 8.0 enable administrators to block IP based on its activity.

Blocking access based on no of requests in IIS 8.0

Open IIS manager and navigate to website for which you want to configure and click on IP Address and Domain Restrictions feature.

Now click on Edit Dynamic Restriction Settings... link in action pane on right side bar.

Clicking on it will open dialog box which allows you to configure dynamic IP blocking. There are two options available to block IP based on his activity.

1) Maximum no of concurrent requests

This setting ensures that if concurrent requests of any IP address exceed than configured limit then IIS will not serve that request and it will deny.

2) Maximum no of requests over a period of time

This setting ensures that if any IP address sends more requests than allowed limit within specified time then IIS will not serve that request and it will deny. For e.g. as shown in above image if any IP will send more than 20 requests within 200 milliseconds then IIS will deny to serve request.

Response behavior while denying requests

To configure response behavior while denying any requests in IIS 8, click on Edit Feature Settings... link in action pane on right side bar.

In below image we can see available deny action type while denying any requests. These are Unauthorized, Forbidden, Not Found, and Abort. Based on this settings IIS will send response with respective HTTP status code.

Dynamic IP restrictions and Proxy

Many clients are accessing websites through one or more proxy server; in this case it may happen IIS could get same IP in all requests even though it is requested by different client. To address this situation, we can configure IIS 8 to check x-forwarded-for HTTP header. To enable this simply check Enable Proxy Mode checkbox as displayed in following image.

So in nutshell, we can say that Dynamic IP address and domain restrictions feature of IIS 8 adds security improvements to the website by blocking mass requests from one client.

Nandip Makwana

About Nandip Makwana

Nandip Makwana is the modern day geek and is passionate about digital world and web. He completed Masters in Computer Application in June 2011. Currently he is working as a Jr. Software Engineer. He has shown great promise and command over ASP.NET and technologies surrounding it during his academic years and professional life...continue reading


Thursday, March 22, 2012

OData service with ASP .NET Web API

This post is part of ASP .NET MVC 4 Article Series.

With the release of ASP.NET Web API, Microsoft has unified programming model for building HTTP services which can target various range of client including mobile and tablet devices. Moreover WCF Web API is also now ASP.NET Web API.

In previous post we have seen what is ASP.NET Web API and why we should use it. In this post we will see how to build OData services with ASP.NET Web API.

What is OData service?

The OData (Open Data Protocol) is a Web protocol for querying and updating data. OData enable you to develop a service that can be accessed and queried by URI conventions. Consumer can query, filter, sort data by forming standard URI. More information on URI conventions can be found here.

ASP.NET Web API and OData

Building OData services with ASP.NET Web API is quite easier than WCF Data service. We can create OData service by simply returning IQueryable<T> from API Controller action method. Once action method return IQueryable<T>, we can consume it by following OData URI conventions. Following code snippet shows action method which return IQueryable<T>.

public IQueryable<Blog> GetBlogList()
{
    return new List<Blog>
    {
        new Blog {Id=1, Author="Nandip Makwana", TotalPost=50},
        new Blog {Id=2, Author="Jalpesh Vadgama", TotalPost=300},
        new Blog {Id=3, Author="Dhananjay Kumar", TotalPost=500}
    }.AsQueryable();
}

We can clearly see that it is quite easier to build OData services with ASP.NET Web API. Now let consume this OData service by entering api/blog in browser. As you can see it returns all the three records. Now enter api/blog?$orderby=author in browser, result are now sorted on Author field see following image.

Now enter api/blog?$filter=author eq ’Nandip Makwana’ as you can see in following image, service has returned only one record which satisfy filter criteria.

More information on URI conventions can be found here.

Hope this post would be helpful.

Nandip Makwana

About Nandip Makwana

Nandip Makwana is the modern day geek and is passionate about digital world and web. He completed Masters in Computer Application in June 2011. Currently he is working as a Jr. Software Engineer. He has shown great promise and command over ASP.NET and technologies surrounding it during his academic years and professional life...continue reading


Wednesday, February 29, 2012

ASP .NET Web API in ASP .NET MVC 4 Beta

This post is part of ASP .NET MVC 4 Article Series.

With the release of ASP.NET MVC 4 beta, Microsoft shipped ASP.NET Web API within ASP.NET MVC. Developers who are familiar with WCF Web API, might know that WCF Web API is now ASP.NET Web API. However it’s a whole separate topic to discuss but here we will see how we can utilize ASP.NET Web API with ASP.NET MVC application.

Why Use ASP.NET Web API

Before ASP.NET Web API, whenever ASP.NET MVC applications requires to expose data in form of service, either for internal application usage via AJAX call or for external consumer, it return it with JSONResult from controller and it was working perfectly but with the introduction of ASP.NET Web API, it is even easier to build HTTP services around the standard HTTP method. So whenever applications require to build API services, we can put whole API implementation in separate class. By this way we can encapsulate API implementation in separate class and we can keep controller class clean and now it is only responsible to deal with view. Apart from code separation, by putting API implementation in separate class, we can also utilize below mentioned great feature of ASP.NET Web API without single line of extra code!

Full list of feature can be found here in release note. I am going to quote few of them here which I like most.

Modern HTTP programming model: we can directly access and manipulate HTTP request and response within Web API through strongly typed classes.

Full support for routes: ASP.NET Web API also support full fledged routing including route parameters, constrains.

Content negotiation: This is one of the great features which I like most. Web API will return data based on requesting client. Based on requesting client capabilities, it will choose right data format to send back to client. We will see more on this later in this post.

Model binding and validation: With model binding, we can extract data from HTTP request and can populate .NET object from it. So we can directly use that object within Web API.

Apart from above feature it also support action filter, dependency resolver, etc.

To examine ASP.NET Web API in action, let start by creating new Web API project in ASP.NET MVC 4.

Open Global.asax file and examine RegisterRoutes method. Here you will find route mapping for Web API as below. As we have seen earlier that Web API support full fledged routing.

routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional }
);

One more thing if you have noticed in DefaultApi route mapping is that it is just mapping API controller name and optional parameter id. We are not mapping action as in Default route mapping. This is because as we have seen earlier that Web API is built around standard HTTP method, so it will choose and execute appropriate method from API controller based on HTTP request method (i.e. GET, POST, etc.) and optional route parameters combination. So if you are requesting API with GET method then Web API framework will look for method which start with Get… and matches route parameters with method parameters and based on these combinations, it will execute appropriate method from API controller. Web API project include one same API controller named ValuesController.cs. All API controller must derived from ApiController class. Open ValuesController.cs, here you can see implementation for HTTP Get, Post, Put and Delete method. As you can see in sample controller if we call /api/values with Get method then it is mapped to Get() and if we call /api/values/5 with Get method then it is mapped to Get(int id). This is because as we seen earlier that it will choose appropriate method based on HTTP request method and optional route parameters combination.

Content negotiation in action

As I told earlier that I am more interested in Content negotiation feature which choose return data format based on requesting client. Here we will examine it with three different scenarios.

1) Invoke /api/values with browser You should get response in XML format as displayed in below image. This is due to Accept request header as highlighted in below image.

2) Invoke /api/values with XHR Request (i.e. Ajax request) to invoke API with XHR put following JavaScript code into index.cshtml and examine request and response header in firebug or IE developer tools.

$(document).ready(function () {
    $.ajax({
        url: "/api/values",
        success: function () {
            alert('Web API Content Negotiation demo');
        }
    });
});

As we can see if Accept request header is */* and it is requested with XMLHttpRequest(XHR) then return type is application/json.

3) Invoke /api/values with XHR Request and datatype xml (i.e. Ajax request) to invoke API with XHR and XML as datatype put following JavaScript code into index.cshtml and examine request and response header

$(document).ready(function () {
    $.ajax({
        url: "/api/values",
        dataType: 'xml',
        success: function () {
            alert('Web API Content Negotiation demo');
        }
    });
});

Based on above observation we can conclude following for content negotiation in Web API.

  • Web API look for Accept request header and based on its value, it choose appropriate return data format.
  • If Web API found Accept request header with */* then it will look for X-Requested-With header and if its value is XMLHttpRequest then it will choose JSON as a return type.

Hope this would be helpful. Stay tuned for more post on MVC4 and vNext.

Nandip Makwana

About Nandip Makwana

Nandip Makwana is the modern day geek and is passionate about digital world and web. He completed Masters in Computer Application in June 2011. Currently he is working as a Jr. Software Engineer. He has shown great promise and command over ASP.NET and technologies surrounding it during his academic years and professional life...continue reading


Friday, February 17, 2012

ASP.NET MVC 4 Beta Overview

This post is part of ASP .NET MVC 4 Article Series.

Yesterday Microsoft announced ASP.NET MVC 4 Beta released on the road to ASP.NET MVC 4. Beta release included some great new feature in addition to ASP.NET MVC 4 developer preview. Here we will take quick overview of whats new included in ASP.NET MVC 4 Beta release.

Software Requirements and Installation

The ASP.NET MVC 4 beta requires PowerShell 2.0 and Visual Studio 2010 with SP 1 or Visual Web Developer Express 2010 with SP 1.

Before installing ASP.NET MVC 4 beta, you must uninstall any previously installed version of ASP.NET MVC 4 and .NET Framework 4.5 Developer Preview as ASP.NET MVC 4 beta is not compatible with .NET Framework 4.5 Developer Preview.

ASP.NET MVC 4 beta can be installed and run along with ASP.NET MVC 3.

Download ASP.NET MVC 4 beta

ASP.NET MVC 4 beta can be installed via web platform installer from here http://www.asp.net/mvc/mvc4 or it can be installed via standalone installer which can be downloaded from http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=28942

ASP.NET Web API

One great feature in ASP.NET MVC 4 beta is inclusion of ASP.NET Web API. Building HTTP services with ASP.NET MVC requires a lot of work. With the inclusion of ASP.NET Web API in ASP.NET MVC, one can build HTTP services within ASP.NET MVC application. ASP.NET Web API also supports for Routes. You will see more information and walkthrough in upcoming post meanwhile you can explore more on ASP.NET Web API here on ASP.NET MVC 4 beta release note or Jon Galloway’s post on ASP.NET MVC 4 beta release.

ASP.NET Single Page Application

With ASP.NET MVC 4 beta, Microsoft also included ASP.NET Single Page Application (SPA). ASP.NET SPA enables developer to build better end to end application with client side JavaScript interaction. Some of the JavaScript libraries used are history.js, knockout.js, upshot.js, etc. Although as mentioned in ASP.NET MVC 4 beta release note this is experimental feature.

Hope this would be helpful.

Nandip Makwana

About Nandip Makwana

Nandip Makwana is the modern day geek and is passionate about digital world and web. He completed Masters in Computer Application in June 2011. Currently he is working as a Jr. Software Engineer. He has shown great promise and command over ASP.NET and technologies surrounding it during his academic years and professional life...continue reading


Related Posts Plugin for WordPress, Blogger...