Dusan Czupek's blog

Blog related .NET & web development

Configuring IIS to Run 32-bit Applications on 64-bit Windows

Configuring IIS to Run 32-bit Applications on 64-bit Windows

If your application is using any 32bit dll, IIS on 64 bit machine needs to be switched to support 32 bit applications. Otherwise you will get an error message saying:

Could not load file or assembly 'XXXX' or one of its dependencies. An attempt was made to load a program with an incorrect format.

In II6 you have to run script in order to get working 32bit app on your 64bit IIS:
cscript.exe adsutil.vbs set W3SVC/AppPools/Enable32BitAppOnWin64 “true”


II7 has option in Advanced Settings of your application pool. Default value is false.

 

Posted: Mar 08 2010, 07:15 by dczupek | Comments (6) RSS comment feed |
  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Filed under: dotNet

Migration of ASP.NET app from IIS6 to IIS7 (7.5)

For many of us familiar problem. You developing applications under IIS6 and you're about to move them to IIS7.  In previous version of IIS was enough to copy over your files, create app pool and site. IIS7 (7.5) is different in this point.

In IIS6 there was only one way hot to extend server with other features – using ISAPI filters. Whole .NET is lived within one dll aspnet_isapi.dll. If the request was for files with .NET type extensions (such .aspx, .ashx, .axd and so on) your application know them and was able to serve them. If request was for file with extension for example .jpg or other static file, the application was not aware about them. For example this is the reason why URL authorization does not work for static files.

IIS7 offers two modes of work:

  • Classic – In IIS requests are processed by above description. Basically the system is compatible with previous versions of IIS
  • Integrated – the default one. In this mode has IIS privileged position, the HTTP handlers and modules (known from ASP.NET) can be executed directly. They are in line with ISAPI filters and built-in IIS functionality.

HTTP handlers, modules were not changed at all, so you don't need to rewrite or recompile them. But was has been changed is the way how to know IIS about which handler, module to use. Basically this is often problem when app is running properly under IIS6 but won't under IIS7. This is not such difference between IISs but it's big difference between Classic and Integrated mode on application pool. You have two options:

  1. Put your application under Classic managed pool (this is not recommended, use it only in case when other solutions fails)
  2. Change the registration of modules and handlers in web.config file to reflect newest configuration schema.

There is no difference whether you register handler or module under IIS6 or IIS7 Classic Mode. Illustration of its registration in web.config:

<?xml version="1.0"?>
<configuration>
    <system.web>
      <httpHandlers>
        <add verb="*" path="*My.axd" type="MyHttpHandler"/>
      </httpHandlers>
      <httpModules>
        <add name="MyModule" type="MyHttpModule"/>
      </httpModules>
    </system.web>
</configuration>

In case of web.config in II7 Integration mode, registration will looks like:

<?xml version="1.0"?>
<configuration>
  <system.webServer>
    <handlers>
      <add name="NameOfMyHandler" verb="*" path="*My.axd" type="MyHttpHandler"/>
    </handlers>
    <modules>
      <add name="MyModule" type="MyHttpModule" preCondition="managedHandler"/>
    </modules>
  </system.webServer>
</configuration>


Generally you have to perform these changes:

  1. you need rename httpHandlers to handlers  and httpModules to modules.
  2. Handlers has required attribute name, so you have to name them
  3. Modules should have attribute preCondition with value managedHandler. This is optional and depends on behavior of particular module (module will called only in case when its execution will be driven by handler written in .NET).

Changes can be done manually or by command line tool (see bellow).

HTTP modules are called for each request. In case of II6 or Classic mode it means for each request mapped in aspnet_isapi.dll configuration. For integrated mode it means for all request including for static files.

Well sometimes you run into problem when you your app needs to work IIS6 as well IIS7. Problem is once you register handlers and module in system.webServer section you need to remove their registration from system.web section. If the IIS would ignore old registration in system.web section I could be security risk caused by not executed some modules, handlers. Mostly those for authentication and authorization. But there is am option how to avoid this checking and allow to have registrations in both sections. All you need to do is to turn off validation by attribute validateIntegratedModeConfiguration. Using this attribute is not really recommended.
So the universal web.config for both scenarios would looks like:

<?xml version="1.0"?>
<configuration>
  <system.web>
    <httpHandlers>
      <add verb="*" path="*My.axd" type="MyHttpHandler"/>
    </httpHandlers>
    <httpModules>
      <add name="MyModule" type="MyHttpModule" />
    </httpModules>
  </system.web>
  <system.webServer>
    <validation validateIntegratedModeConfiguration="false"/>
    <handlers>
      <add name="NameOfMyHandler" verb="*" path="*My.axd" type="MyHttpHandler"/>
    </handlers>
    <modules>
      <add name="MyModule" type="MyHttpModule" preCondition="managedHandler"/>
    </modules>
  </system.webServer>
</configuration>

Instead of modifying web.config manually, you can perform required changes from command line by
%windir%\system32\inetsrv\Appcmd migrate config "<ApplicationPath>"

ApplicationPath is site map name in IIS, for example Default Web Site.
The tool will modify web.config in order to move registration of handlers, modules from system.web to system.webServer section.

Even you've did web.config changes you app can still failing under Integration mode. The most common is "Request is not available in this context" exception. This happens when your implementation is about to access Request object in Application_Start method of global.asax file. Error is due to design change in the II7 Integrated pipeline that makes Request object unavailable in Application_Start. The Classic mode has no problems with it. What you can do about it is to change your app to avoid reference to Request context inside Application_Start or running app under Classic mode (not recommended). More about avoiding reference to Request object you can find on Mike Volodarsky's blog.

DotNetKicks Image
Posted: Feb 25 2010, 15:08 by dczupek | Comments (7) RSS comment feed |
  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Filed under: dotNet

ReSharper 5.0 Beta released

JetBrains' ReSharper 5.0 Beta is now available and includes many improvements, fully VS 2010 support.

ReSharper 5.0 has evolved in four major directions:

  • Web Development. We have greatly extended the toolset available to ASP.NET developers when they work with markup files and web site infrastructure.
  • Project and Team. ReSharper becomes a valuable assistant not only to individual developers but to teams working with large, complicated projects. It allows them to view, change and maintain project structure.
  • Support for Visual Studio 2010. ReSharper 5.0 provides support for the new Visual Studio version earlier than ever. Of course, Visual Studio 2008 is supported, too.
  • Code Analysis. This area incorporates several improvements, from "plainly" implementing a substantial pack of new code inspections to upgrading foreach and for loops to LINQ queries and letting you track how data values and method calls are passed through your code.

Comparison matrix can be found at: http://www.jetbrains.com/resharper/docs/ReSharper50vs_ReSharper45_comparisonMatrix.pdf

ReSharper Beta2 download location at:
http://download.jetbrains.com/resharper/ReSharperSetup.5.0.1565.10.msi

DotNetKicks Image
Posted: Dec 29 2009, 13:39 by dczupek | Comments (3) RSS comment feed |
  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Filed under: dotNet

Visual Studio 2010 and .NET Framework 4 Beta 2 For Public

Visual Studio 2010 and .NET Framework 4 focuses on the core pillars of developer experience, support for the latest platforms, targeted experiences for specific application types, and core architecture improvements.

Microsoft Visual Studio 2010 Ultimate Beta 2 - ISO
http://download.microsoft.com/download/F/C/9/FC9131D2-688C-43DC-91CF-53359D4882E7/VS2010B2Ult.iso

Microsoft Visual Studio 2010 Premium Beta 2 – ISO
http://download.microsoft.com/download/9/8/9/989B6C8D-DA2E-4849-A533-69BE52C4C674/VS2010B2Prem1.iso

Microsoft Visual Studio 2010 Professional Beta 2 - ISO
http://download.microsoft.com/download/5/8/A/58ABDB52-684A-4DED-AD14-FD82E9EECAE6/VS2010B2Pro1.iso

More details about Visual Studio 2010
http://msdn.microsoft.com/en-us/vstudio/dd582936.aspx
http://www.microsoft.com/visualstudio/en-us/products/2010/default.mspx

DotNetKicks Image
Posted: Oct 21 2009, 20:06 by dczupek | Comments (7) RSS comment feed |
  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Filed under: dotNet

Javascript in Flash

Imaging an situation when you need to track redirect activity from the flash animation. Execute some tracking script right before user left the flash animation.

Basically there are two ways have you can call javascript from ActionScript:

1) getURL()
2) ExternalInterface.call

Problem is that browsers does not behaves same way.
getURL is properly executed on FF but not in IE7.
ExternalInterface.call is working on FF, IE in same way. Browser executes javascript before redirect.

Posted: Oct 17 2009, 16:53 by dczupek | Comments (6) RSS comment feed |
  • Currently 1/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Filed under: dotNet

Build Version Increment Add-In Visual Studio

Somehow Visual Studio doesn't come with an option to only auto increment the build version of the AssemblyFileVersion attribute. Sure, by placing an * in the AssemblyVersion attribute and leaving the the AssemblyFileVersion out the compiler will auto generate build versions for both but this is a pain to maintain when you're releasing signed assemblies. Besides I don't feel like grabbing a calculator just to see when version 1.0.3394.25054 has been build. I needed a little more control.

I found use full addin for visual studio on codeplex. Click for more details.

Posted: Sep 30 2009, 21:44 by dczupek | Comments (8) RSS comment feed |
  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Filed under: dotNet

Simple validation in Model View Presenter

Last time I wrote about how to implement simple page by Model View Presenter pattern.  Quickly we created form with 2 textboxes, label and button for firing presenter method SaveData.

This time let's focus a bit to validation in presenter and co-working your page with validation result.

Why validation in present

Let's imagine we have form for validating user contact information.

I will assume that you will have presenter in separate assembly. The assembly it self will contains interface of view (used for communication between presenter and page) and presenter logic (presenter logic and interface of presenter).

1) create new assembly, call it for example WebAppPresenter. Create new interface for View

namespace WebAppPresenter
{
    public interface IDataView
    {
        string FirstName { get; }
        string LastName {  get; }
        string EmailAddress { get; }
        string Status { set;  }
    }
}

Another one for interface of presenter

namespace WebAppPresenter
{
    public interface IDataPresenter
    {
        void SaveData();
        bool AreDataValid();
    }
}

2) the Presenter will implement IDataPresenter inferface created above.

using System;
using System.Text.RegularExpressions;

namespace WebAppPresenter
{
    public class DataPresenter : IDataPresenter
    {
        private IDataView _view;
        public DataPresenter(IDataView view)
        {
            _view = view;
        }

        public void SaveData()
        {
            if (AreDataValid()) { _view.Status = "Data could be saved"; }
        }

        public bool AreDataValid()
        {
            if (String.IsNullOrEmpty(_view.FirstName)) 
                { _view.Status = "First Name cannot be blank"; return false;}
            if (String.IsNullOrEmpty(_view.LastName))
                { _view.Status = "Last Name cannot be blank"; return false; }
            if (!String.IsNullOrEmpty(_view.EmailAddress)) 
            {
                if (!Regex.IsMatch(_view.EmailAddress,@"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$"))
                    {_view.Status="Email address is not valid!"; return false;}                
            }
            else { _view.Status = "Email address is not valid!"; return false; }
            
            return true;
        }

    }
}

Let's stop for a while to describe what is happening here. Constructor populating user entries from webpage through IDataView interface. Method SaveData executes validations and set Status based on validation results. The AreDataValid method is the one which is responsible for validation within presenter. It goes through user inputs present in property _view, validating each value and if one of the field is invalid set Status with proper error message.
Because AreDataValid method is present in interface and it's public can be called directly from webpage for example to prevent execution of other code (such SaveData() ) once the input data are not in good shape. It's up to you whether you make validation method visible outside presenter.

 

3) Now let's make user interaction with presenter. So firstly create some form for getting information from visitors: (extract from the page)

    <form id="frmContact" runat="server">
    First name:<asp:TextBox ID="tbFirstName" runat="server" /><br />
    Last name:<asp:TextBox ID="tbLastName" runat="server" /><br />
    Email Address:<asp:TextBox ID="tbEmailAddress" runat="server" /><br /><br />
    Result:<asp:Label ID="lblStatus" runat="server" /><br />
    <asp:Button ID="btnSave" runat="server" Text="Submit" />
    </form>

4) Code behind of the page. Firstly do not forget to inherit from the View (in my scenario it should be IDataView) to be able make connection between Presenter and View layer.

public partial class MyPage : System.Web.UI.Page,IDataView
{
    #region IDataView Members
    public string FirstName { get { return this.tbFirstName.Text; } }
    public string LastName { get { return this.tbLastName.Text; } }
    public string EmailAddress { get { return this.tbEmailAddress.Text; } }
    public string Status { set { this.lblStatus.Text = value; } }
    #endregion

    protected void Page_Load(object sender, EventArgs e)
    { }
}

I inherited from IDataView to be able implement it's members and connect them with the webform

5) In Page_Load() method is good to connect to the Presenter and initialize it.

protected void Page_Load(object sender, EventArgs e)
{
    IDataPresenter _presenter = new DataPresenter(this);
}

Notice that Presenter constructor had one parameter in its definition and that parameter is the View. So when I initializing presenter I need to populate it with the View. In my scenario View will be webform it self because it inherits from IDataView, so I can use this object.

6) Now just need to wire up button btnSave click event to launch SaveData method from Presenter.

protected void Page_Load(object sender, EventArgs e)
{
    IDataPresenter _presenter = new DataPresenter(this);
    btnSave.Click += delegate{ _presenter.SaveData(); };
}

As I mentioned above you can also call the _presenter.AreDataValid() first and then based on the result call _presenter.SaveData()

Posted: Sep 24 2009, 23:49 by dczupek | Comments (5) RSS comment feed |
  • Currently 1/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Filed under: dotNet

Tracking with dcsMultiTrack invalid fields on client side

dcsMultiTrack - is 3rd compoment. Instead of dcsMultiTrack you can use your own tracking tool or for example google analytics.

Sometimes you can find yourself in situation when you want to track if some of the fields on your form is not valid. Track some value when it does not goes through clientside validation. In this situation you need to somehow hook up on or before validation it self will be executed. In my sample I use custom javascript function which executes validation on form fields and based on their validity reporting status of the form.

1) set custom attribute on the field you want to track. For example on textbox with username you can set up attribute DSCError with value "UN".
<asp:textbox id="username" runat="server" DSCError="UN" />

2) place validation control by own choice (regular, required, custom ...) and ensure that clientside validation is turned on.

3) The button used for submit need to have onclick clientside event with own function used for validation. Custom validation function should contain one parameter ValidationGroup (useful for avoid validation of other validationgroups).
For example onclick="PreValidation('MyValidationGroup');"

4) Custom validation function. Function should consume ValidationGroup name but it is not required. If you does not provide it  (PreValidation('') or PreValidation() ) function will validate all fields with validators.

function PreValidation(valGroupName) {
    var errorsToReport = "";

    for (i = 0; i < Page_Validators.length; i++) {
        var val = Page_Validators[i];
        // in case there is no value for valGroupName validate all validators
        if (typeof (valGroupName) == 'undefined' || valGroupName == '' || val.validationGroup == valGroupName) {
            var cntrToValidate = $get(val.controltovalidate);
            if (cntrToValidate != null) {
                var DSCError = cntrToValidate.attributes["DCSError"];
                if (DSCError != null) {
                    ValidatorValidate(val, val.validationGroup, null);
                    if (val.isvalid == false) {
                        errorsToReport += (errorsToReport.length > 1 ? "," : "") + DSCError.value;
                    }
                }
            }
        }
    }
    if (errorsToReport.length > 0) {
        dcsMultiTrack("DCS.dcsuri", "/your_page_name", "DCSext.ErrorFields", errorsToReport);
    }
}


How does it works? Well firstly we need to go through all validators on the page, they are present in Page_Validators collection. Then check out whether actuall validator could be evaluated or not. If so store field you tracking into variable cntrToValidate. Check present of custom attribute DCSError on the field. Finally execute the validation with ValidatorValidate(...). Based on the results populate errorsToReport with list failed fields DSCError entries. When validation is done, try to track failed fields by calling dcsMultiTrack.

Posted: Aug 11 2009, 21:53 by dczupek | Comments (5) RSS comment feed |
  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Filed under: dotNet

Request.UrlReferrer Is Null In IE 6.0 when location.href(Javascript) is used to redirect

Microsoft announced fix will be from IE9. Until you can avoid problems with following code:

function navigateWithReferrer(url)
{
  var fakeLink = document.createElement ("a");
  if (typeof(fakeLink.click) == 'undefined')
    location.href = url; // sends referrer in FF, not in IE
  else
  {
    fakeLink.href = url;
    document.body.appendChild(fakeLink);
    fakeLink.click(); // click() method defined in IE only
  }
}

The trick is that, although location.href navigation (and window.navigate() too) doesn't send a referrer, the IE-only click() method on a hyperlink will send a referrer. So if you create a hyperlink, set its href, and then click() it with script, you'll get the referrer you want.

Unfortunately the click() method isn't supported on hyperlinks in some versions of Firefox, so you need to check for its presence and use location.href if it's not there. Since location.href sends a referrer on firefox, it works fine.
Posted: Aug 05 2009, 12:57 by dczupek | Comments (27) RSS comment feed |
  • Currently 1/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Filed under: dotNet

ReSharper for Visual Studio 2010 (Preview)

Finally JetBrains launched ReSharper v.5.0 for VS2010 after a month delay against previous announce.

Installation it self should be a bit tricky. First of all download a nightly build of ReSharper from

ReSharper EAP - ReSharper for Visual Studio 2010 (Preview). The download links are located at the very end of the page.

1) Before you click on downloaded .vsix file I highly recommend to click on "Load extensions from my local application data folder" in Tools/Options, Extension Manager menu.

2) Close all your VS2010 instances

3) After that click on downloaded .vsix file, following installation dialog.

4) Start VS2010 and open Tools | Extensions Manager menu and confirm that ReSharper is there

image

5) Maybe you will meet with registration of evaluation period during VS2010 start up. Basically evaluation period should start automatically, if not use following credentials:  (this will provide you a temporary license till 07/23/2009). I heard that keys from ReSharper 4.5 are working as well.

User Name: VS2010Beta1
License Key: 0-dY16Cav/tdLePfqRzD2kp37wt2HXosbp

 

Check JetBrains Resharper EAP VS2010 regularly for updates.

Posted: Jul 12 2009, 17:47 by dczupek | Comments (7) RSS comment feed |
  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Filed under: dotNet