Wednesday, 29 October 2014

My Take on Microsoft TechEd 2014 Australia

I had a chance to attend Microsoft TechEd 2014 in Sydney this week and here is my brief take on it:

Keynote Speaker
Scott Guthrie was there as keynote speaker. Of course, ASP.NET/.NET developers know him very well! I was excited to see him there.



Microsoft Azure lands in Australia
It was the biggest announcement of the conference with two local data centres in New South Wales and Victoria.

New Features in Microsoft Azure
Azure Marketplace, Azure RemoteApp, Application Insights, Web Jobs, Event Hubs, DocumentDB, Machine Learning, Azure Search, Web Jobs…

Internet of Things
It was about connected devices and development tools.

New Visual Studio + ALM
Latest versions of Visual Studio and TFS features, ASP.NET vNext preview, TFS Rest API, Application Insights.

Project "Orleans" 
Microsoft’s new framework for scalable cloud services using Actor pattern.

Microsoft Azure Document Database
A new schema-free and NoSQL document database.

Azure Mobile Services
Build mobile apps, using heterogeneous data sources, offline connectivity and synchronization , push notifications and authentication.

Application Insights for Visual Studio Online
Application Insights for Visual Studio Online lets you monitor your deployed live application.

Microsoft Release Management
A tool for automated simultaneous deployments.

Thursday, 19 December 2013

How to Restrict Access by IP in ASP.NET MVC and Azure

There are several ways to do this including using HTTP Modules here and here or creating an Action Filter in ASP.NET MVC like this.

They are all working and useful to be used based on your requirement. But there are some pros and cons with them in different situations. Consider that you need to filter the access to some sub-folders of your web application without making them as an IIS application, then the HTTP module method may not work for you any more or you may don’t want to hard code every single folder in your Action Filter.

The best practice to do it, if you are using IIS 7+, is to use ipSecurity configuration settings and you can use IP ranges and subnet masks out of the box with just simple steps to deny or allow the access. Some examples:

Allow all, but block specific IPs or networks
<security>

   <!-- this line allows everybody, except those listed below -->
   <ipSecurity allowUnlisted="true"> 

       <!-- removes all upstream restrictions -->
       <clear/>

       <!-- blocks the specific IP of 83.116.19.53  -->
       <add ipAddress="83.116.19.53"/>

       <!--blocks network 83.116.119.0 to 83.116.119.255-->
       <add ipAddress="83.116.119.0" subnetMask="255.255.255.0"/>

       <!--blocks network 83.116.0.0 to 83.116.255.255-->
       <add ipAddress="83.116.0.0" subnetMask="255.255.0.0"/>

       <!--blocks entire /8 network of 83.0.0.0 to 83.255.255.255-->
       <add ipAddress="83.0.0.0" subnetMask="255.0.0.0"/>

   </ipSecurity>
</security>

Deny all, but allow specific IPs or networks
<security>

    <!-- this line blocks everybody, except those listed below --> 
    <ipSecurity allowUnlisted="false"> 

       <!-- removes all upstream restrictions -->
       <clear/> 

       <!-- allow requests from the local machine -->
       <add ipAddress="127.0.0.1" allowed="true"/>

       <!--allow network 83.116.119.0 to 83.116.119.255-->
       <add ipAddress="83.116.119.0" subnetMask="255.255.255.0" allowed="true"/> 

       <!-- allow the specific IP of 83.116.19.53  --> 
       <add ipAddress="83.116.19.53" allowed="true"/>  

       <!--allow network 83.116.0.0 to 83.116.255.255-->
       <add ipAddress="83.116.0.0" subnetMask="255.255.0.0" allowed="true"/> 

       <!--allow entire /8 network of 83.0.0.0 to 83.255.255.255-->
       <add ipAddress="83.0.0.0" subnetMask="255.0.0.0" allowed="true"/> 

    </ipSecurity>

</security>


To do this on your local or on-premise IIS:

  1. You need to add this feature to your IIS here 
  2. Unlock the feature by running this command in your command prompt %windir%\system32\inetsrv\AppCmd.exe unlock config -section:system.webServer/security/ipSecurity
  3. Add proper configuration to your root web.config by using location tag or add new web.config for each folder you want to limit the access to it.

<location path="YOUR-FOLDER-PATH">

    <system.webServer>

      <security>

        <ipSecurity allowUnlisted="false">

          <clear/>

          <add ipAddress="1.*.*.*"/>

        </ipSecurity>

      </security>

    </system.webServer>

  </location>


The trick for ASP.NET MVC areas is that you need to use the virtual path or route for your folders or routes. For example, if you have an Admin area in your web application the MVC route for it will be /Admin and not Areas/Admin. So you might need to add two location settings to limit the access to your admin area like this:

<location path="Admin">

    <system.webServer>

      <security>

        <ipSecurity allowUnlisted="false">

          <clear/>

          <add ipAddress="127.*.*.*"/>

          <add ipAddress="1.*.*.*"/>

          <add ipAddress="192.*.*.*"/>

        </ipSecurity>

      </security>

    </system.webServer>

  </location>

  <location path="Areas/Admin">

    <system.webServer>

      <security>

        <ipSecurity allowUnlisted="false">

          <clear/>

          <add ipAddress="127.*.*.*"/>

          <add ipAddress="1.*.*.*"/>

          <add ipAddress="192.*.*.*"/>

        </ipSecurity>

      </security>

    </system.webServer>

  </location>

Azure

It turns out that IIS7 doesn’t have the module or role installed for IP Security in Azure (or any Windows 2008 Server) by default. Therefore we must go ahead and install the module ourselves, before the application starts. The way to achieve this is to create a startup task. In this task, first you need to install “IPv4 Address and Domain Restrictions” feature and then Unlocking configuration for “IPv4 Address and Domain Restrictions feature.
To do this, create a new folder at the root level of your web role called startup and, within this folder, create a batch file called startup.cmd. Set the properties of this file to Copy Always to ensure that it will be deployed. In this file we are going to put some shell commands to make the Web Role installs the correct IIS module during its startup. Those commands are:

@echo off

@echo Installing "IPv4 Address and Domain Restrictions" feature

%windir%System32ServerManagerCmd.exe -install Web-IP-Security

@echo Unlocking configuration for "IPv4 Address and Domain Restrictions" feature

%windir%system32inetsrvAppCmd.exe unlock config -section:system.webServer/security/ipSecurity


Then go into the ServiceDefinition.csdef of your Web Role and add the startup task under WebRole tag like so:

<Startup>

<Task commandLine="startup\startup.cmd" executionContext="elevated" taskType="background" />

</Startup>


Note that this startup task type is background. This task would be independent from the Role itself. First, startup task will execute and immediately after the Role, and even when this task is not completed, the Role will start separately from the startup task. So if something goes wrong in the task, your web role won’t fail.
Now you can have the same web configuration as above to restrict the access to some folders.

Thursday, 12 September 2013

Why AOP Is Good For Your Health!

What Is AOP?

One important part of every well designed software application is its “Crosscutting concerns” something that we may call non-functional requirement. These functionalities are needed across many different layers, modules, classes within the application. Some examples are:

  • Logging
  • Instrumentation
  • Security
  • Error Handling
  • Caching
  • Validation

These concerns often cannot be cleanly decomposed from the rest of the system or core concerns in both the design and implementation, and can result in either code duplication, coupling between systems, or both.

Aspect-Oriented Programming (AOP) helps to separate crosscutting concerns from the core concerns, by putting them into a separate module so we can plug that module into the core whenever needed without cluttering the code.

Why It Is Good For Your/Application Health?

So why AOP is good for your health?! The short answer is: It helps you write less code and makes your life easier! So you can have more free time to spend on whatever you want e.g. going to the gym or something useful for your health or life!

Here is the longer and more technical answer:

  • The business logic source code is much easier to read and understand.
  • Reusable code means shorter development times and easier troubleshooting.
  • Developers can better focus on implementing the main business logic or core concerns.
  • Less-experienced developers won't have to learn to tackle these crosscutting concerns throughout their code.
  • The crosscutting code can be replaced or upgraded easier.
  • Many AOP tools and frameworks can be configured simply via configuration files without recompiling and redeploying the application which means easier maintenance. 
  • Separation of concerns means better unit testing and higher quality software.

As a developer, if you still believe that writing code having above qualities and possibilities makes your life easier (and healthier!), then continue reading to find out how to do AOP in .NET.

How to do AOP?

A common approach to implementing behaviours to address crosscutting concerns in your application is to use the decorator/proxy patterns. But, AOP is not just a decorator! If you have a small application with a few classes, then decorator/proxy combined with dependency injection does the job for you. But, for a bigger and more complicated application, it is recommended to use an AOP framework. For more information see this: aop vs decorator.
There are several AOP implementations in .NET Framework with different capabilities and pros and cons and reviewing all of them is beyond the scope of this post. So, I will introduce only two of them which I have used.

Postsharp

Postsharp is by SharpCrafters and it claims to be the most comprehensive aspect-oriented software available for .NET. It is not free or open source and its free version is limited.
PostSharp uses .NET attributes and does its work at build time after the compiler has generated the IL from your code to produce the final result using MSIL rewriting techniques.

The good thing about Postsharp is it is only a compile time thing and there won’t be performance penalty at runtime. The bad thing is, it is tied to your current compiler version and build configuration (i.e. 32 or 64 bits) and sometimes it slows down you to use for example the newer version of Visual Studio and you need to wait for a newer version of Postsharp or pay for an upgrade. And of course, there is a significant hit with compilation time in bigger applications.

Unity Interception

As said before, a common approach to implementing behaviours to address crosscutting concerns in your application is to use the decorator pattern. Instead of wiring the decorators up manually, you could use the Unity container to do it for you.
Unity is one of the Enterprise Library application blocks. Unity is essentially a DI container with additional support for an interception mechanism through which you can make your classes a bit more aspect-oriented.
Unity uses the Interception design pattern to dynamically create a proxy object that it inserts between the client and the target object.

The good thing about Unity Interception is that it could be configured through configuration files using matching rules, call handlers and interceptors and in comparison to Postsharp, you don’t need to add attributes to your methods or classes and of course it is from Microsoft and it is free as part of the Enterprise Library. The bad thing could be its runtime nature that can have a small performance cost.

Monday, 20 May 2013

Command and Query Responsibility Segregation (CQRS)

Recently, I needed to design a new application with a non-functional requirement to have a good performance in searches and viewing the page results. So, it was mostly about the "Read".
I have been using Domain Driven Design or DDD for transactional applications for a while and my feeling was that this is not what I need this time exactly.
The main reason was the complicated domain models with several child objects and collections and so many mappings from database to the domain model and then to DTOs and finally to view models.
Domain models are the heart of any DDD applications, and I needed DTOs for my distributed fa├žade and them view models for the MVC part.
The answer for my new application was CQRS or Command Query Responsibility Segregation pattern:
"At its heart it is a simple notion that you can use a different model to update information than the model you use to read information."
Martin Fowler
Please note that it is not against DDD while you still need or can use DDD with it. When we say "CQRS" this often means: "CQRS Principle" + "Message-driven architecture with commands, events and queries" + "Domain-Driven Design Methodology".

I am not going to define it here or show you different diagrams or different aspects of it in this post. Instead, the main purpose of this post is to share some good sources that I have used to learn it and implement it into a way that worked for my application.

CQRS by Martin Fowler

CQRS Starting Page : This is a very complete reference page for CQRS by Rinat Abdullin which you can find sample implementations too.

Top 10 Reasons to do CQRS

CQRS Journey: This is from Microsoft patterns & practices

Clarified CQRS

Introduction to CQRS: a good article and easy to understand

DDD/CQRS:  A discussion group on Google

I am sure that you can find better sources, but these are what I liked :)

Happy CQRS!

Monday, 21 January 2013

ASP.NET MVC Model Binding for Base Classes

In ASP.NET MVC, sometimes there is a need to have several model classes inheriting from a base model class. When all child classes share a common property from the base class, then it is useful to use model binders to bind a value to the shared properties.

Using ASP.NET MVC 4.0, in below snippets, the ProfileModelBase is the base class for AboutModel and BasicInfoModel classes.
    public class ProfileModelBase
    {
        public string UserName { get; set; }
    }

    public class AboutModel : ProfileModelBase
    {
        public string About { get; set; }
    }

    public class BasicInfoModel : ProfileModelBase
    {
        public DateTime Birthday { get; set; }

        public string FirstName { get; set; }

        public string LastName { get; set; }
    }

One solution to do the "Don't Repeat Yourself (DRY)" for above code is to use a model binder to assign a value to the UserName property using below code:

    public class ProfileModelBinder : DefaultModelBinder
    {
        protected override void OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            var userProfileBase = bindingContext.Model as ProfileModelBase;
            if (userProfileBase != null)
            {
                userProfileBase.UserName = controllerContext.HttpContext.User.Identity.Name;
            }

            base.OnModelUpdated(controllerContext, bindingContext);
        }
    }

In above code, I am using OnModelUpdate event to set the value of the UserName property. Using this model binder, our model classes will be:

    [ModelBinder(typeof(ProfileModelBinder))]
    public class AboutModel : ProfileModelBase
    {
        public string About { get; set; }
    }

    [ModelBinder(typeof(ProfileModelBinder))]
    public class BasicInfoModel : ProfileModelBase
    {
        public DateTime Birthday { get; set; }

        public string FirstName { get; set; }

        public string LastName { get; set; }
    }

That's it! No more repeating code.

Enjoy model binding!

Thursday, 26 July 2012

ObjectDataSource Ignores Culture Information When Updating

"When using a business object with the ObjectDataSource control, culture information seems to be ignored when property values are extracted from the TextBox control generated by a BoundField. The same is true when a TemplateField is used." from here.
And, yes it is true. I encountered this problem when I was working on a page using FormView and ObjectDataSource to grab some values including a date value into the database. I used jQuery Datepicker to tie it to my date text box and because the website will be used in Australia, then I changed the date format of Datepicker to Australian format which is dd/MM/yyyy (in .NET) like this:


<script type="text/javascript">
    $(document).ready(function () {
        $('#DateTextBoxID').datepicker({ dateFormat: "dd/mm/yy" });
    });
</script>

Then, happily added below setting to my web.config file to change the culture to en-AU.


    <globalization culture="en-AU" uiCulture="en-AU"/>

When, I clicked the update button of my FormView I got error.

The problem was that my entered value for the date field was 27/07/2012 and if you pars it in US date formatting which is (MM/dd/yyyy) of course we don't have 27th month! If I had entered 12/07/2012 then everything seems working except that the date was wrong into the database.
Ok, this was the problem and you can find some workarounds for this "bug" at above link under Workarounds tab. I chose to add update and insert parameters for that date field to my ObjectDataSource as below:


    <InsertParameters>
        <asp:Parameter Name="DateField" Type="DateTime" />
    </InsertParameters>
    <UpdateParameters>
        <asp:Parameter Name="DateField" Type="DateTime" />
    </UpdateParameters>


By adding these parameters, ObjectDataSource will use your globalization settings and it did the job for me.

Happy Globalization!

Thursday, 5 July 2012

How I Modernized My Error Logging by ELMAH

In one of my ASP.NET applications, I didn't have enough time to add a better error logging mechanism, so I ended up with this:

protected void Application_Error(object sender, EventArgs e)
{
    IPrincipal principal = Thread.CurrentPrincipal;
    var err = "Error Caught in MyApplication\n" +
            "Error in: " + Request.Url +
            "\r\nUsername: " + principal.Identity.Name +
            "\r\nError Message:" + objErr.Message +
            "\r\nStack Trace:" + objErr.StackTrace;
    SendMail(
        "from@example.com",
        "to@example.com",
        String.Format("Exception @{0}"DateTime.Now),
        err);
}

And of course having my custom error settings and pages in the web.config:
      <customErrors defaultRedirect="GenericErrorPage.aspx"
        mode="RemoteOnly" xdt:Transform="Replace">
        <error statusCode="404" redirect="FileNotFound.aspx" />
      </customErrors>

Actually, it did the job for me and I was receiving emails from the above code into my inbox whenever there was any unhandled exception in that application. The problem with this approach is that it is not configurable and I was receiving so many emails into my inbox even for 404 error code which is Http file not found error. In addition, I needed to store the exceptions somewhere i.e. in a database easy and without any coding, so I will be able to generate some reports out of it later.

ELMAH

ELMAH (Error Logging Modules and Handlers for ASP.NET) is the right and fast answer for this need. Actually, it has been there for years. First, you need to install ELMAH into your web project from nuget running this command in your Package Manager Console in Visual Studio:
Install-Package elmah

This command will do almost everything for you specially your web.config settings. To test it, just point to below URL to generate a test exception in your web application.
http://YourLocalWebSiteUrl/elmah.axd/test

Then point to http://YourLocalwebSiteUrl/elmah.axd to see the ELMAH output.

If you can see ELMAH output, then it is working for your in-memory logs. Now, you need to make it to store logs into your SQL Server database (or any other db that it supports). To set up ELMAH to save logs to SQL Server, you need to create the error log source data table and stored procedures in your database by 
running a DBML script from:
http://code.google.com/p/elmah/downloads/detail?name=ELMAH-1.2-db-SQLServer.sql

The web.config settings for database logging is:

<errorLog type="Elmah.SqlErrorLog, Elmah" 
          applicationName="YourApp"
          connectionStringName="YourConnectionStringName" />

Notice to the applicationName property in above settings which is useful when you are using a centralized database to log errors for all of your web applications.To add email notifications all you need is:
 <errorMail from="from@example.com"
            to="to@example.com"
            subject="Unhandled Exception in My Application"
            priority="High"
            async="true"
            smtpPort="25"
            smtpServer="YourSMTPServer"
            useSsl="false"
            noYsod="false" />

If you want to filter some errors like 404 error, so ELMAH won't log them or send email then:

<errorFilter>
  <test>
    <or>
      <and>
        <equal binding="HttpStatusCode" value="404" type="Int32" />
      </and>
    </or>
  </test>
</errorFilter>    

If you want ELMAH to log 404 errors, but does not send emails for this type of error:
<errorFilter>
  <test>
    <or>
      <and>
        <equal binding="HttpStatusCode" value="404" type="Int32" />
        <regex binding="FilterSourceType.Name" pattern="ErrorMailModule" />
      </and>
    </or>
  </test>
</errorFilter>

Resources