Enforce latest IE version even if the site is added to Compatability Mode

In your web.config under the system.webserver tag add the following header to enforce for all the pages

<system.webServer>
<httpProtocol>
<customHeaders>
<add name=”X-UA-Compatible” value=”IE=Edge,chrome=1″ />
</customHeaders>
</httpProtocol>

…….

or you can also add a meta tag on specific page under the <head> but that would be a per page change

<meta http-equiv=”X-UA-Compatible” content=”IE=edge”> 

For details check:

http://stackoverflow.com/questions/6771258/whats-the-difference-if-meta-http-equiv-x-ua-compatible-content-ie-edge-e

Advertisements

Sign and remove .net assembly by strong name

Before strong name signing an assembly, we need to generate a public/private key pair, and obviously the dot NET Framework SDK provides tools for assigning a cryptographic signature to any built assembly. This includes the Strong Name tool “sn.exe” which will help us in building the key pair we need.

The first step in strong name signing is generating a key pair. The “sn.exe” tool is located in “C:Program FilesMicrosoft Visual Studio 8SDKv2.0Bin” and is a command line based tool, so start Microsoft CMD and use this command to generate a new key pair:

Sn –k MyKeyPair.snk

This way, we obtain a random key pair (MyKeyPair.snk) which contains both private and public key. We can of course extract the public key from the key pair obtained and place it in a separate file, but we will not enter in details on this since our main goal is to demonstrate that strong name must not be considered as a protection because of how weak it is!

Well, now by using MyKeyPair.snk, we will sign an assembly. There are several ways to do it: either by adding the correct custom attribute to your AssemblyInfo.vb or AssemblyInfo.cs source:

C#
[assembly: AssemblyKeyFile(@”….MyKeyPair.snk”)]

VB.NET
<Assembly: AssemblyKeyFile(“….MyKeyPair.snk”)>

Or directly through Microsoft Visual Studio IDE via project’s properties – click on signing tab, check “Sign the assembly” then browse to the .snk file:

By building your project, you get a strong name signed assembly.

Determining if an Assembly is Strongly Named or Not

There are several approaches applicable to determine if an assembly has a strong name or not. I’ll show you some of them. The first one uses the same tool that helped us in generating our key pair file: the sn.exe tool.

For this, we run it using the following command: sn –vf MyAssembly.exe (or MyAssembly.dll)

Source

Add SQL user to a role via TSQL

Came across with a situation where a database was in standby mode (secondary server) and the SQL user with which I was trying to access had no access on the database.

The database was not allowing to change anything with regards to configuration from Management Studio so eventually had to add the user in sysadmin from the following TSQL:

— myUser being added to role sysadmin

–SELECT * FROM master..syslogins

EXEC master..sp_addsrvrolemember @loginame = N’myUser’, @rolename = N’sysadmin’

GO

Timeout Error

1. Adjust your application’s run-time execution timeout parameter

http://msdn.microsoft.com/en-us/library/vstudio/e1f13641(v=vs.100).aspx

executionTimeout

Optional Int32 attribute.

Specifies the maximum number of seconds that a request is allowed to execute before being automatically shut down by ASP.NET.

This time-out applies only if the debug attribute in the compilation element is False. Therefore, if the debug attribute is True, you do not have to set this attribute to a large value in order to avoid application shutdown while you are debugging.

The default is 110 seconds.

Note In the .NET Framework 1.0 and 1.1, the default is 90 seconds.

2. Set the Microsoft SQL Server Query timeout value if you are using Microsoft SQL Server or a command timeout in case of stored procedure

http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.commandtimeout.aspx

This property is the cumulative time-out (for all network packets that are read during the invocation of a method) for all network reads during command execution or processing of the results. A time-out can still occur after the first row is returned, and does not include user processing time, only network read time.

Things that can trigger an Application Pool recycle

http://blogs.msdn.com/b/tess/archive/2006/08/02/asp-net-case-study-lost-session-variables-and-appdomain-recycles.aspx

Why does an application domain recycle?

 An application domain will unload when any one of the following occurs:

 

  • Machine.Config, Web.Config or Global.asax are modified
  • The bin directory or its contents is modified
  • The number of re-compilations (aspx, ascx or asax) exceeds the limit specified by the <compilation numRecompilesBeforeAppRestart=/> setting in machine.config or web.config  (by default this is set to 15)
  • The physical path of the virtual directory is modified
  • The CAS policy is modified
  • The web service is restarted
  • (2.0 only) Application Sub-Directories are deleted (see Todd’s blog http://blogs.msdn.com/toddca/archive/2006/07/17/668412.aspx for more info)

Specific Issues:

  • Unexpected config or bin directory changes
  • Web site updates while the web server is under moderate to heavy load
  • Re-compilations

Change Connection String Dynamically in Telerik

Telerik Reporting can resolve and work with named connection strings provided in the application configuration file (web.config or app.config). Thus providing the required connection string with the same name in the application configuration file should be enough for most of the scenarios. Still if this is not applicable for your scenario and you have to provide the connection strings in runtime you can use the following example:

C#

class ReportConnectionStringManager
{
    readonly string connectionString;
 
    public ReportConnectionStringManager(string connectionString)
    {
        this.connectionString = connectionString;
    }
 
    public ReportSource UpdateReportSource(ReportSource sourceReportSource)
    {
        if (sourceReportSource is UriReportSource)
        {
            var uriReportSource = (UriReportSource)sourceReportSource;
            var reportInstance = DeserializeReport(uriReportSource);
            ValidateReportSource(uriReportSource.Uri);
            this.SetConnectionString(reportInstance);
            return CreateInstanceReportSource(reportInstance, uriReportSource);
        }
 
        if (sourceReportSource is XmlReportSource)
        {
            var xml = (XmlReportSource)sourceReportSource;
            ValidateReportSource(xml.Xml);
            var reportInstance = this.DeserializeReport(xml);
            this.SetConnectionString(reportInstance);
            return CreateInstanceReportSource(reportInstance, xml);
        }
 
        if (sourceReportSource is InstanceReportSource)
        {
            var instanceReportSource = (InstanceReportSource)sourceReportSource;
            this.SetConnectionString((ReportItemBase)instanceReportSource.ReportDocument);
            return instanceReportSource;
        }
 
        if (sourceReportSource is TypeReportSource)
        {
            var typeReportSource = (TypeReportSource)sourceReportSource;
            var typeName = typeReportSource.TypeName;
            ValidateReportSource(typeName);
            var reportType = Type.GetType(typeName);
            var reportInstance = (Report)Activator.CreateInstance(reportType);
            this.SetConnectionString((ReportItemBase)reportInstance);
            return CreateInstanceReportSource(reportInstance, typeReportSource);
        }
 
        throw new NotImplementedException("Handler for the used ReportSource type is not implemented.");
    }
 
    ReportSource CreateInstanceReportSource(IReportDocument report, ReportSource originalReportSource)
    {
        var instanceReportSource = new InstanceReportSource { ReportDocument = report };
        instanceReportSource.Parameters.AddRange(originalReportSource.Parameters);
        return instanceReportSource;
    }
 
    void ValidateReportSource(string value)
    {
        if (value.Trim().StartsWith("="))
        {
            throw new InvalidOperationException("Expressions for ReportSource are not supported when changing the connection string dynamically");
        }
    }
 
 
    Report DeserializeReport(UriReportSource uriReportSource)
    {
        var settings = new System.Xml.XmlReaderSettings();
        settings.IgnoreWhitespace = true;
        using (var xmlReader = System.Xml.XmlReader.Create(uriReportSource.Uri, settings))
        {
            var xmlSerializer = new Telerik.Reporting.XmlSerialization.ReportXmlSerializer();
            var report = (Telerik.Reporting.Report)xmlSerializer.Deserialize(xmlReader);
            return report;
        }
    }
 
    Report DeserializeReport(XmlReportSource xmlReportSource)
    {
        var settings = new System.Xml.XmlReaderSettings();
        settings.IgnoreWhitespace = true;
        var textReader = new System.IO.StringReader(xmlReportSource.Xml);
        using (var xmlReader = System.Xml.XmlReader.Create(textReader, settings))
        {
            var xmlSerializer = new Telerik.Reporting.XmlSerialization.ReportXmlSerializer();
            var report = (Telerik.Reporting.Report)xmlSerializer.Deserialize(xmlReader);
            return report;
        }
    }
 
    void SetConnectionString(ReportItemBase reportItemBase)
    {
        if (reportItemBase.Items.Count < 1)
            return;
 
        if (reportItemBase is Report)
        {
            var report = (Report)reportItemBase;
 
            if (report.DataSource is SqlDataSource)
            {
                var sqlDataSource = (SqlDataSource)report.DataSource;
                sqlDataSource.ConnectionString = connectionString;
            }
            foreach (var parameter in report.ReportParameters)
            {
                if (parameter.AvailableValues.DataSource is SqlDataSource)
                {
                    var sqlDataSource = (SqlDataSource)parameter.AvailableValues.DataSource;
                    sqlDataSource.ConnectionString = connectionString;
                }
            }
        }
 
        foreach (var item in reportItemBase.Items)
        {
            //recursively set the connection string to the items from the Items collection
            SetConnectionString(item);
 
            //set the drillthrough report connection strings
            var drillThroughAction = item.Action as NavigateToReportAction;
            if (null != drillThroughAction)
            {
                var updatedReportInstance =this.UpdateReportSource(drillThroughAction.ReportSource);
                drillThroughAction.ReportSource = updatedReportInstance;
            }
 
            if (item is SubReport)
            {
                var subReport = (SubReport)item;
                subReport.ReportSource = this.UpdateReportSource(subReport.ReportSource);
                continue;
            }
 
            //Covers all data items(Crosstab, Table, List, Graph, Map and Chart)
            if (item is DataItem)
            {
                var dataItem = (DataItem)item;
                if (dataItem.DataSource is SqlDataSource)
                {
                    var sqlDataSource = (SqlDataSource)dataItem.DataSource;
                    sqlDataSource.ConnectionString = connectionString;
                    continue;
                }
            }
 
        }
    }
}

VB.NET

Imports Telerik.Reporting
 
Class ReportConnectionStringManager
    ReadOnly connectionString As String
 
    Public Sub New(connectionString As String)
        Me.connectionString = connectionString
    End Sub
 
    Public Function UpdateReportSource(sourceReportSource As ReportSource) As ReportSource
        If TypeOf sourceReportSource Is UriReportSource Then
            Dim uriReportSource = DirectCast(sourceReportSource, UriReportSource)
            Dim reportInstance = DeserializeReport(uriReportSource)
            ValidateReportSource(uriReportSource.Uri)
            Me.SetConnectionString(reportInstance)
            Return CreateInstanceReportSource(reportInstance, uriReportSource)
        End If
 
        If TypeOf sourceReportSource Is XmlReportSource Then
            Dim xml = DirectCast(sourceReportSource, XmlReportSource)
            ValidateReportSource(xml.Xml)
            Dim reportInstance = Me.DeserializeReport(xml)
            Me.SetConnectionString(reportInstance)
            Return CreateInstanceReportSource(reportInstance, xml)
        End If
 
        If TypeOf sourceReportSource Is InstanceReportSource Then
            Dim instanceReportSource = DirectCast(sourceReportSource, InstanceReportSource)
            Me.SetConnectionString(DirectCast(instanceReportSource.ReportDocument, ReportItemBase))
            Return instanceReportSource
        End If
 
        If TypeOf sourceReportSource Is TypeReportSource Then
            Dim typeReportSource = DirectCast(sourceReportSource, TypeReportSource)
            Dim typeName = typeReportSource.TypeName
            ValidateReportSource(typeName)
            Dim reportType = Type.[GetType](typeName)
            Dim reportInstance = DirectCast(Activator.CreateInstance(reportType), Report)
            Me.SetConnectionString(DirectCast(reportInstance, ReportItemBase))
            Return CreateInstanceReportSource(reportInstance, typeReportSource)
        End If
 
        Throw New NotImplementedException("Handler for the used ReportSource type is not implemented.")
    End Function
 
    Private Function CreateInstanceReportSource(report As IReportDocument, originalReportSourceAs ReportSource) As ReportSource
        Dim instanceReportSource = New InstanceReportSource() With { _
             .ReportDocument = report _
        }
        InstanceReportSource.Parameters.AddRange(originalReportSource.Parameters)
        Return InstanceReportSource
    End Function
 
    Public Sub ValidateReportSource(value As String)
        If value.Trim().StartsWith("=") Then
            Throw New InvalidOperationException("Expressions for ReportSource are not supported when changing the connection string dynamically")
        End If
    End Sub
 
 
    Public Function DeserializeReport(uriReportSource As UriReportSource) As Report
        Dim settings = New System.Xml.XmlReaderSettings()
        settings.IgnoreWhitespace = True
        Using xmlReader = System.Xml.XmlReader.Create(uriReportSource.Uri, settings)
            Dim xmlSerializer = New Telerik.Reporting.XmlSerialization.ReportXmlSerializer()
            Dim report = DirectCast(xmlSerializer.Deserialize(xmlReader), Telerik.Reporting.Report)
            Return report
        End Using
    End Function
 
    Public Function DeserializeReport(xmlReportSource As XmlReportSource) As Report
        Dim settings = New System.Xml.XmlReaderSettings()
        settings.IgnoreWhitespace = True
        Dim textReader = New System.IO.StringReader(xmlReportSource.Xml)
        Using xmlReader = System.Xml.XmlReader.Create(textReader, settings)
            Dim xmlSerializer = New Telerik.Reporting.XmlSerialization.ReportXmlSerializer()
            Dim report = DirectCast(xmlSerializer.Deserialize(xmlReader), Telerik.Reporting.Report)
            Return report
        End Using
    End Function
 
    Public Sub SetConnectionString(reportItemBase As ReportItemBase)
        If reportItemBase.Items.Count < 1 Then
            Return
        End If
 
        If TypeOf reportItemBase Is Report Then
            Dim report = DirectCast(reportItemBase, Report)
 
            If TypeOf report.DataSource Is SqlDataSource Then
                Dim sqlDataSource = DirectCast(report.DataSource, SqlDataSource)
                sqlDataSource.ConnectionString = connectionString
            End If
            For Each parameter As Telerik.Reporting.ReportParameter In report.ReportParameters
                If TypeOf parameter.AvailableValues.DataSource Is SqlDataSource Then
                    Dim sqlDataSource = DirectCast(parameter.AvailableValues.DataSource, SqlDataSource)
                    sqlDataSource.ConnectionString = connectionString
                End If
            Next
        End If
 
        For Each item As Telerik.Reporting.ReportItemBase In reportItemBase.Items
            'recursively set the connection string to the items from the Items collection
            SetConnectionString(item)
 
            'set the drillthrough report connection strings
            Dim drillThroughAction = TryCast(item.Action, NavigateToReportAction)
            If drillThroughAction IsNot Nothing Then
                Dim updatedReportInstance =Me.UpdateReportSource(drillThroughAction.ReportSource)
                drillThroughAction.ReportSource = updatedReportInstance
            End If
 
            If TypeOf item Is SubReport Then
                Dim subReport = DirectCast(item, SubReport)
                subReport.ReportSource = Me.UpdateReportSource(subReport.ReportSource)
                Continue For
            End If
 
            'Covers all data items(Crosstab, Table, List, Graph, Map and Chart)
            If TypeOf item Is DataItem Then
                Dim dataItem = DirectCast(item, DataItem)
                If TypeOf dataItem.DataSource Is SqlDataSource Then
                    Dim sqlDataSource = DirectCast(dataItem.DataSource, SqlDataSource)
                    sqlDataSource.ConnectionString = connectionString
                    Continue For
                End If
 
            End If
        Next
    End Sub
End Class

 
In order to set the connection strings at run-time you have to instantiate the ReportConnectionStringManager with the new connection string you want to use. Then you have invoke the UpdateReportSource with a ReportSource. This method returns an updated ReportSource with the new connection string. The updated ReportSource then can be used for ReportViewer.ReportSource or for ReportProcessor. For example check out the following check out the following sample:

C#

var connectionString = "Data Source=(local);Initial Catalog=AdventureWorks;Integrated Security=SSPI";
var connectionStringHandler = new ReportConnectionStringManager(connectionString);
var sourceReportSource = new UriReportSource { Uri = "Employee Sales Summary.trdx" };
//var sourceReportSource = new InstanceReportSource { ReportDocument = new EmployeeSalesSummary() };
var reportSource = connectionStringHandler.UpdateReportSource(sourceReportSource);
this.reportViewer1.ReportSource = reportSource;
this.reportViewer1.RefreshReport();

VB.NET

Dim connectionString = "Data Source=(local)\SQLEXPRESS;Initial Catalog=AdventureWorks;Integrated Security=SSPI"
    Dim connectionStringHandler = New ReportConnectionStringManager(connectionString)
    Dim sourceReportSource = New UriReportSource() With { _
         .Uri = "Employee Sales Summary.trdx" _
    }
 
    Dim reportSource = connectionStringHandler.UpdateReportSource(sourceReportSource)
    Me.reportViewer1.ReportSource = reportSource
    Me.reportViewer1.RefreshReport()

 

app_code does not work with web applications..

source: http://vishaljoshi.blogspot.gr/2009/07/appcode-folder-doesnt-work-with-web.html

As you might already know we have two different project types for web development  in Visual Studio 1.) Web Application Projects (WAPs) 2.) Web Site Projects (WSPs)…

Often time developers hear that if you want to put a random class file in your web project you should put it in App_Code folder.  While this is true for Web Site Projects (WSPs), it is not so much true for Web Application Projects (WAPs) and in this post I will try to explain the inner workings on why that is the case…

Firstly App_Code folder is a special ASP.NET RUNTIME folder…  Any files in this folder are compiled by ASP.NET when your site is actually running on the server…  This essentially allows you to drop random class/code files in this folder to be compiled on the server side…  For this very reason if you drop something new into the App_Code folder of your running web site, it is like resetting it coz ASP.NET runtime now recognizes that there is a new class which needs to be kept in consideration during running the site…  This magical folder brings with itself various connotations when it comes to different project types…

First of all it is important to know that Visual Studio does not really create any DLLs when you are using Web Site Projects (even when you are building the web site)…  VS simply validates that your code is correct in WSP… In Web Application Projects (WAPs) this is not actually true as VS actually creates a DLL with all the code behind and class files that are present in your project and drops them into the BIN folder of your project…

In case of WAPs every file in the project is marked with a specific “Build Action” as shown below:

image

All the class files (.vb/.cs) are marked as “Compile”… This essentially tells VS to take all those files and call the correct VB/C# compilers on them…  The result of that activity is the DLL,which is named same as your project name i.e. WebApplication1.dll, being created in the BIN folder of your project…

With this understanding let us look at right click Add—> Add ASP.NET Folder –> options on Web Application Project

image

You will notice that App_Code folder is not really available as an option… This is an intentional behavior… 

If you add a App_Code folder into a Web Application Project and add classes to that folder then more than likely their “Build Action” will be marked as “Compile” (as all .vb/.cs files are defaulted to “Compile”)… This will signal Visual Studio to compile them inside the IDE to produce the DLL in the BIN folder…  For illustration let us assume you added a class called Products in App_Code\Products.cs file which is marked as “Compile”… Now when you build your WAP you will get a DLL in your project BIN (e.g. WebApplication1.dll), which when you open in ILDASM or Reflector will tell you that Product class exists in it…

Now when you try to run the project locally or do a xCopy deployment of your WAP to the server you will might accidentally move the App_Code\Products.cs on the server as well…  This is time when things start getting tricky… Now you have a DLL in the BIN which is provided as a reference to ASP.NET runtime which has the Products class… Also ASP.NET is trying to compile your App_Code folder (as it is a special Runtime folder and that is an expected behavior) which will result in duplicate declaration of your Product class (one in the referenced project DLL and second in the dynamic compilation)…  As you can imagine duplicate declaration of same type is not desirable…:-)

Additionally, VS will auto generate namespace for your Products class in the DLL to be something like WebApplication1.App_Code.Products vs ASP.NET runtime will produce a hashed version of the name space causing additional connotations giving you weird error messages…

So at a high level there are many reasons why App_Code folder is not supported for Web Application Projects and should be avoided…

Does this mean App_Code and WAPs just don’t ever work together?

No, that is not true… App_Code and WAPs can work together, you need to make sure that “Build Action” of none of the files in the App_Code folder is marked as “Compile”… Ideally you should mark them as “Content” which will ensure that they will get deployed on the destination and get compiled by ASP.NET instead of locally by VS IDE… 

But this will bring its own side effects that intellisense may not work very well for these files inside VS as they will not be treated as Class files by VS… But the key point is that you do not really need “App_Code in Web Application Projects (WAP) if you do not intend to put random code files or modify existing code files in App_Code folder directly on your production server…

What should one do if there are isolated code files which need to be added to WAPs?

You can add code files under any folder call it “CodeFolder”, “Controllers” or anything that makes sense in your project… Just avoid putting them under “App_Code” unless you specifically want the server side compilation behavior…

Securing ELMAH

“install-package elmah” is the easiest way to get started with elmah. One of the important and easily forgotten considerations is to secure it. Recently I came across a situation where I had to secure elmah on a web application running in VB.net and using 4.0 framework and ofcourse custom forms authentication 😀

If anyone is interested in the debate of why secure elmah give it a read

http://www.troyhunt.com/2012/01/aspnet-session-hijacking-with-google.html

One of the easiest and simplest way to secure elmah is to use roles and users in web.config. But besides there is also one interesting solution by Phil Haack

http://haacked.com/archive/2007/07/24/securely-implement-elmah-for-plug-and-play-error-logging.aspx/

However, if you are in a situation where you do not want to have an elmah.axd running on all locations and just want to see elmah exceptions under an admin application then give the following a read

http://lowleveldesign.wordpress.com/2013/03/24/elmah-axd-log-viewer-for-multiple-apps/

But hey the problem is still how to secure it. How to restrict access and redirect to some login page already in the application if someone tries to access elmah.axd at an unknown location known to you.

The answer is that you need to create a module in your application and pass this custom handler to another handler implementing SessionState.

Now you can make use of the global.asax and check for the usual session variables under an event like Application_PreRequestHandlerExecute and make sure that only authenticated user accesses the elmah.axd

Hope this helps!

Securing_Elmah_SourceCode

Convert RGB to HEX in SQL Server

CREATE function [dbo].[ConvertToBase]
(
@val as BigInt,
@base as int
)
returns varchar(63)
as
Begin
/* Check if we get the valid base */
If (@val<0) OR (@base 36) Return Null;
IF (@val = 0)  Return ’00’;
IF (@val = 1)  Return ’01’;
IF (@val = 2)  Return ’02’;
IF (@val = 3)  Return ’03’;
IF (@val = 4)  Return ’04’;
IF (@val = 5)  Return ’05’;
IF (@val = 6)  Return ’06’;
IF (@val = 7)  Return ’07’;
IF (@val = 8)  Return ’08’;
IF (@val = 9)  Return ’09’;
IF (@val = 10) Return ‘0A’;
IF (@val = 11) Return ‘0B’;
IF (@val = 12) Return ‘0C’;
IF (@val = 13) Return ‘0D’;
IF (@val = 14) Return ‘0E’;
IF (@val = 15) Return ‘0F’;

/* variable to hold final answer */
Declare @answer as varchar(63);

/* Following variable contains all
possible alpha numeric letters for any base
*/
Declare @alldigits as varchar(36);
Set @alldigits=’0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ’

/* Set the initial value of
final answer as empty string
*/
Set @answer=”;

/* Loop until your source value is greater than 0 */
While @val>0
Begin
Set @answer=Substring(@alldigits,@val % @base + 1,1) + @answer;
Set @val = @val / @base;
End

/* Return the final answer */
return @answer;
End

——————————————————————-

CREATE FUNCTION [dbo].[GetHEXfromRGB]
(
@input as varchar(255)
)
RETURNS varchar(63)
AS
BEGIN
Declare @r int;
set @r = CAST(LEFT(@input, CHARINDEX(‘,’,@input)-1) AS INT);

Declare @temp as varchar(255);
Set @temp = CAST(RIGHT(@input, LEN(@input) – CHARINDEX(‘,’,@input)) AS varchar(255))

Declare @g as int;
set @g = CAST(LEFT(@temp, CHARINDEX(‘,’,@temp)-1) AS INT)

Declare @b as int;
Set @b = CAST(RIGHT(@temp, LEN(@temp) – CHARINDEX(‘,’,@temp)) AS INT)

return dbo.converttobase(@r, 16) + dbo.converttobase(@g, 16) + dbo.converttobase(@b, 16)
END

——————————————————————-

Usage: select dbo.GetHEXfromRGB(‘125,161,134’)
Resultant HEX Value: 7DA186