Wednesday, July 31, 2013

Nuget package adopted by Microsoft

It’s official – Microsoft has adopted our Nuget package “bootstrap”.

As of Visual Studio 2013, bootstrap is the default Css library for .Net web applications, delivered by the bootstrap Nuget package we created.

How it all began

Over a year ago we announced our new Nuget package called bootstrap, which aimed to spread awareness of the Twitter bootstrap library and to make it easier for .Net developer to use it.

What does adoption mean?

At first, you get to trade emails with Microsoft superstars such as Jon Galloway.

Then, they kick you off the project.

In all fairness they must remove you as owner in order to ensure the code is up to Microsoft standard and won’t be tampered with.

That didn’t upset me too much. The package lives on and has, for my part, done its job. And I’m still listed as the original author.

What’s next?

The ASP .NET team has added a version, upgrading to bootstrap 2.3.1.

The bootstrap library has just released a new mobile-first version 3.0. Smart move, Twitter. That evens the playing field with competing Css library,  Zurb Foundation 4. Bootstrap 3.0 even has an extra script for IE8 support.

Hopefully, the good folks at Microsoft will update the NuGet package soon.

For now, its out of my hands.

Monday, October 15, 2012

DLL Hell and TFS Builds


Just when you thought you had escaped DLL Hell by advancing to .NET, that legacy COM DLL shows up and crashes the party.

As if non-managed code isn't enough of a pain in itself, it can play havoc with your precious nightly team build in TFS.

Background:

A Visual Studio .NET project can reference COM DLLs that are registered on the server (RegSvr32.exe) and VS accomplishes this by creating an Interop wrapper behind the scenes.

Problem:

However, this means that the COM DLLs must be registered on the TFS build machine. If not, your TFS build will fail with errors such as Class ID XX-XXXXX-XX not found. <shudder!>

Solution:

  1. Make sure the COM DLL (compiled) is in TFS as well.
  2. Manually edit your VS project file to change the relevant COMReference elements to COMFileReference elements as follows:


OLD:
<COMReference Include="myDLL">
      <Guid>{0D120A48-361B-4705-9325-8CFFB8AB47D1}</Guid>
      <VersionMajor>1</VersionMajor>
      <VersionMinor>1</VersionMinor>
      <Lcid>0</Lcid>
      <WrapperTool>tlbimp</WrapperTool>
      <Isolated>False</Isolated>
      <EmbedInteropTypes>True</EmbedInteropTypes>
</COMReference>

NEW:
<COMFileReference Include="..\..\..\Lib\COM\myDll.dll">
      <EmbedInteropTypes>True</EmbedInteropTypes>
</COMFileReference>



This allows the DLL to be referenced without registration on the server.

On the actual application server, the call to the DLL still works as long as the DLL is registered.

The manual edit is necessary b/c the COMFileReference build action isn't supported in the VS UI, although it has been available since .NET 3.5.

More information: http://stackoverflow.com/questions/8842742/how-can-c-sharp-use-a-legacy-dll-simply-without-registrationregsvr32 (the second answer; not the accepted answer; see related links.)

Saturday, May 19, 2012

NuGet Package: Twitter Bootstrap

By your own bootstraps

 Twitter kindly created Bootstrap, a collection of CSS and JS code to speed up the creation of standards friendly web sites.

 Bootstrap on NuGet

 Failing to find a handy NuGet package, I rolled my own NuGet package for Twitter Bootstrap (bootstrap 2.0.2), relying on dotless for .less support.

 I hope this helps someone out there.

 Please post feedback in the comments.

Monday, February 14, 2011

Kerberos Security Checklists

Security ala Microsoft

Security – authentication and authorization – is a basic need of intranet applications and a great amount of infrastructure is geared toward enabling security features seamlessly.

Denizens of the planet Microsoft store their intranet user accounts and security groups in Active Directory. Then they configure their web applications for Windows Integrated Security, a.k.a. Single Sign On, whereby the user’s NT username – already authenticated when logging into the client machine – is passed to the web server along with the Http Request and used to authenticate and authorize the user for the application, by means of Kerberos authentication.

The Dreaded Double-Hop Error

One particularly nefarious error looks as follows:

Unauthorized (null)

or

Anonymous logon (null)

Causes include:

  • Bad server configuration
  • Bad network configuration (Service Principal Name - SPN; speak to your network admin)
  • Bad client browser configuration
  • Client login ticket has expired

Solution Checklists

Checklist: Server

  • Connection Pool of site runs under Network Service identity
  • Windows Authentication enabled for site
  • Impersonation enabled for site

Checklist: Client

  • Windows Integrated Authentication enabled (Tools > Internet Options > Advanced)
  • Check "Bypass proxy server for local addresses" (Tools > Internet Options > Connections > LAN Settings)
  • Allow "Automatic logon only in Intranet zone" (Tools > Internet Options > Connections > Security > Local Intranet > Custom Level)
  • Add intranet domain (*.mydomain.com) to list "web sites" (Tools > Internet Options > Connections > Security > Local Intranet > Sites > Advanced > Web Sites )

If the user has successfully accessed the site in the past, it may be a matter of refreshing the login token:

  • Close-reopen browser (IE7+)
  • Right click browser icon > Run as... > enter credentials (IE6)
  • When all else fails... REBOOT

Wednesday, February 9, 2011

Synchronous Ajax with Microsoft

Ajax Without the A

Microsoft Ajax makes it easy for us to call Web Service methods and code-behind Page Methods from our client JavaScript code. However, the process is always asynchronous (the A in Ajax) and requires the use of callback functions.
What about synchronous calls? Sometimes, you want to halt execution until the results arrive – for purposes of data validation, for instance.
The bad news: synchronous calls are not supported out-of-the-box.
The good news: you can work synchronously without having to work with XmlHttpRequest or switch to jQuery.

Synchronous Steps

Step 1
Add scripts to your page for the XmlHttpSyncExecutor and ExecuteSynchronously wrapper method provided thanks to Ricardo Peres.
Step 2
Make sure your Web Service has the right attributes:
[WebService]
    [System.Web.Script.Services.ScriptService(ResponseFormat = ResponseFormat.Json)]
    public class MyWebService: System.Web.Services.WebService
    {
        
        [WebMethod]
        [System.Web.Script.Services.ScriptMethod]
        public string MyWebMethod(int id)
        {
            return "test:" + id.ToString();
        }
    }
Step 3
Call the web service using the ExecuteSynchronously wrapper function in your client-side JavaScript:
var res = ExecuteSynchronously('<%=Request.ApplicationPath %>/WebService/MyWebService.asmx', 
                               'MyWebMethod',
                               { 'id': 100 });
alert(res.d);
Note two things:
  • Pass parameters as a JSON object (third parameter of the ExecuteSynchronously function)
  • The JSON result is stored in property d of the return value

Thursday, December 30, 2010

Integrated Windows Authentication and FireFox

Your manager decides to support FireFox in addition to IE for all intranet applications.

"That should be easy. You develop cross-browser anyway. Right?"
Well, yes and no.

Your Html, Css and JavaScript are only part of the picture.

Browser settings are another creature altogether, and when you're working with Kerberos authentication, browser settings are critical to:

  •  pass the users credentials without prompting him or her to sign in (single sign-on) and

  • allow impersonation and delegation of users credentials from the web server to the database server (double hop).



FireFox Settings - Cheat Sheet

There are 5 settings you need to change, all accessible when you type about:config in the address bar:

setting: network.negotiate-auth.delegation-uris

value: mySite.com,myotherSite.com

setting: network.negotiate-auth.trusted-uris

value: mySite.com,myotherSite.com

setting: network.automatic-ntlm-auth.trusted-uris

value: mySite.com,myotherSite.com

setting: network.automatic-ntlm-auth.allow-proxies

value:true

setting: network.negotiate-auth.allow-proxies

value: true

Piece of cake.

Now for the hard part: figuring out how to change the FireFox settings for your thousands of users...

Wednesday, October 6, 2010

Outlook 2010 Add-In Issue: Closing “Send Using Email” Window

Scenario:

Add-In for Outlook performs an action in the Application_ItemSend handler for outgoing email.

Add-In works for Outlook 2007, but in Outlook 2010 a strange side-effect occurs. When using the “Send Using Email” feature of Word 2010, the email sends but the modal email window stays open! The user has to close it manually.

More good news: Calling the Close(..) method of the inspector throws an error.

Solution:

There is no elegant solution; you have to resort to DLL Imports.

Add the DLL Imports for finding a window and sending it a message:

[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
internal static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool PostMessage(IntPtr hWnd, uint wMsg, IntPtr wParam, IntPtr lParam);
const int WM_CLOSE = 0x10;

Then, in call this in your code, making sure to clean up any COM object references that need to be released (but NOT the EmailItem reference):

void Application_ItemSend(object Item, ref bool Cancel)
{
    
    if (Item is Outlook.MailItem)
{ Outlook.MailItem mail = Item as Outlook.MailItem; Outlook.Inspector inspector = null; if (null != mail) { > try { inspector = mail.GetInspector; if (null != inspector) { //TODO: your add-in magic! } } finally { if (null != inspector) { IntPtr _inspHwnd = FindWindow("rctrl_renwnd32", inspector.Caption); bool retVal = PostMessage(_inspHwnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero); Marshal.ReleaseComObject(inspector); } } } } }

 

Thanks to Ken Slovak and Andrei Smolin for their valuable input…