Friday 23 December 2011

My ASP.NET MVC Page (using Forms Authentication) is not Rendering CSS and Javascript on the Login View - All Requests Show as Redirects to the Login Controller Action in Fiddler

I recently tried to deploy an ASP.NET MVC 4 mobile application (using jQuery Mobile 1.0) to one of the Oakton Amazon Web Services (AWS) web servers. This application used Forms Authentication.

I span up a completely new instance of Windows Server 2008 R2, restored a backup database and xcopy deployed the new application to a newly created Virtual Directory. I ran the Microsoft Web Platform Installer to get the latest MVC framework and supporting components.  I enabled Forms And Anonymous Authentication on that IIS 7 Site and made sure that All users can access the CSS files even before logging in with the following entries in the web.config file:

<location path="Content">
            <system.web>
                  <authorization>
                        <allow users="*" />
                  </authorization>
            </system.web>
      </location>
      <location path="Styles">
            <system.web>
                  <authorization>
                        <allow users="*" />
                  </authorization>
            </system.web>
      </location>
      <location path="Scripts">
            <system.web>
                  <authorization>
                        <allow users="*" />
                  </authorization>
            </system.web>
      </location>

However, when hitting this server, the login screen just wouldn't render correctly. Looking at the requests showing up in Fiddler - it seemed that even the CSS and javascript files were being redirected to the login page. Some of my colleagues had a look - but were also stumped. All the permissions looked right!

While the application pool user had the correct permissions, the problem was that Anonymous users (i.e. everyone before login) were not running as the Application pool user - they were still running as the default which is IUSR. I simply edited the Anonymous authentication credentials setting in IIS 7 to use the Application Pool Credentials rather than IUSR. Alternatively, I could have given the IUSR_MachineName user permissions on the required supporting directories to fix the problem.


This resolved the problem - and CSS and jQuery were again accessible for all users (including anonymous ones). As usual this seems pretty obvious in hindsight - but the mad rush to get the whole environment running and to deploy the application meant that this critical link was missed.

Let this be a reminder.
DDK

Friday 16 December 2011

TFS 2010 - How do I create email alerts when anything is checked into TFS, Build's Fail/Succeed or Work Items are Assigned/Changed?

This is quite simple to do with the right tools installed on your development machine:

1) Ensure that you have an SMTP Server Configured for your TFS box - as described on MSDN at "How to: Configure SMTP Server and E-mail Notification Settings in the Services Web.Config File" 
2) Install the Visual Studio 2010 Team Foundation Server Power Tools from MSDN
3) Open up the Alert Explorer which installs a set of alert actions. The alert explorer is accessible from several different menus within Visual Studio 2010. See screenshots below:

From the Team Menu:

On TFS Work Items:


From the top level TFS Server Node:



On Branches or Folders within the TFS Source Control Explorer windows:



There are several predefined alerts that come with the Visual Studio TFS Power Tools. These are shown below:



The alert filters are quite flexible. You can modify and change these Alerts in the alter definition editor as shown below:


DDK

Monday 5 December 2011

SQL Master Data Services (MDS) - How to I retrieve the connection string from Microsoft.MasterDataServices.Workflow.Properties.Settings? - it is not available via ConfigurationManager.AppSettings or ConfigurationManager.ConnectionStrings

A question today from one of my Colleagues surrounded the retrieval of a value from an app.config file used by a Master Data Services Workflow Extender.

Master Data Services (MDS) workflow extenders support the creation of Business Logic (amongst other things such as external WCF Service calls) against data changes in the Master Data Services catalogs. These workflow extenders run in the context of the SQL Server Master Data Services executable (Microsoft.MasterDataServices.Workflow.exe) - and consequently rely upon the app config file named Microsoft.MasterDataServices.Workflow.exe.config.

Unfortunately, it doesn't appear as though the MDS System Settings classes give you access to that connection string either (http://msdn.microsoft.com/en-us/library/ff487028.aspx). Consequently, you have to default to basic .NET functionality for handling configuration sections.

The traditional appSettings section of the Microsoft.MasterDataServices.Workflow.exe.config file is not used by MDS - it actually uses an applicationSettings section of the file that is not accessible by the usual ConfigurationManager.AppSettings and ConfigurationManager.ConnectionStrings nodes in the config file. Specifically, it uses a custom System.Configuration.ApplicationSettingsGroup of type System.Configuration.ClientSettingsSection.  


To consume this section, you can use the following method (GetSettingValueFromAppConfig):

using System.Configuration;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace CompanyName.MasterDataWorkflow.Tests
{
    /// 
    /// Summary description for GetConnectionSettingsTest
    /// 
    [TestClass]
    public class GetConnectionSettingsTest
    {
        public GetConnectionSettingsTest()
        {
        }

        [TestMethod]
        public void TestGetConnectionSettings()
        {
            //Should return the value from the local applicationSettings Node.
            //Fully qualified section name
            const string sectionName = "applicationSettings/Microsoft.MasterDataServices.Workflow.Properties.Settings";
            const string settingName = "ConnectionString";

            Assert.AreEqual(
                GetSettingValueFromAppConfig(settingName,sectionName),
                "Server=.;Database=MasterDataServices;Integrated Security=SSPI") ;

        }

        private string GetSettingValueFromAppConfig(string settingName, string sectionName)
        {
            System.Configuration.ClientSettingsSection section =
               (System.Configuration.ClientSettingsSection)
                System.Configuration.ConfigurationManager.GetSection(sectionName);
            foreach (SettingElement setting in section.Settings)
            {
                string value = setting.Value.ValueXml.InnerText;
                string name = setting.Name;
                if (name.ToLower().StartsWith(settingName.ToLower()))
                {
                    return value;
                }
            }
            return string.Empty;
        }
    }
}


DDK

Thursday 1 December 2011

SharePoint 2010 - How to Get XML Sample Data for Debugging Web Parts that support XSL transform customization (e.g. Search and Content Query Web Parts)

XSLT is the preferred technology for customizing the visual output of SharePoint Web parts (primarily as it is standards-based and non-proprietary). However, there is absolutely no XSLT debugging support provided within the SharePoint environment (this is surprising as it is so pervasive). With these limitations in mind, XSLT should ideally be developed outside of SharePoint in a proper IDE that supports XSL debugging such as Visual Studio 2010 or Altova's XMLSpy.

However, debugging XSLT requires a data source (in the form of XML sample data) as input to the XSL transform. The simplest way to get a sample input XML file provided by SharePoint for a XSL-enabled web part is to do the following:

1) Open ContentQueryMain.xsl and find the XSL that looks like the following:

<xsl:template match="/">
  <xsl:call-template name="OuterTemplate"> </xsl:call-template></xsl:template>

Replace this XSL with the following so that it outputs all xml rather than just applying the OuterTemplate xsl template :
<xsl:template match="/">
  <xmp><xsl:copy-of select="*" /></xmp>
</xsl:template>

To avoid modifying system files like ContentQueryMain.xsl, you can make a copy the ContentQueryMain.xsl e.g. ContentQueryMainDebug.xsl and point your CQWP to the Content QueryMainDebug.xsl file instead - using the MainXslLink property of the Content Query Web Part (defined in the .webpart file).

2) View Source on the page and locate the block of XML that has been output by your web part.

3) Save it as a text file and use it as input into your favourite XSL development tool.

DDK

SharePoint 2010 - Modifying the Core Search Results Web Part to Display Results Sorted by Site Name or Document Title (With Paging Limitations...)

I recently had a requirement from my client to have the following functionality in SharePoint 2010:
a) The Search Core Results web part displaying sorted in Alpha order
b) The Search Core results part should just show sites (not documents) that the current user has access to.

Requirement b) was simple - you can set the keywords on the Core Search Web Part to just display sites (using the "contentclass:STS_Site" keyword in the "Fixed Keyword Query" property - and the part would default to showing a list of sites the current user has access to (via the normal SharePoint 2010 security trimming functionality).


However, the first requirement was a little bit trickier. The default Core Search Web part only provides for 2 search sort options - by date and by relevance (which is the default).


To fix this, the XSLT which defines the search results needs to be changed. This XSLT is specific to the instance of the web part - modifying it won't affect the normal search functionality of your site.

To modify the XSLT for the search results web part, you need to first uncheck the "Use Location Visualization" checkbox. The XSLT that opens is around 700 lines long and has a lot of different XSL templates defined within it. To sort the search results by alpha order, you need to use an xsl-sort call within the main apply-templates call.

Some sites such as http://kwizcom.blogspot.com/2008/11/how-to-change-moss-search-retults-sort.html have a simple suggestion - but this would not work as the "select node is missing" on the "apply-templates directive. You need to provide a valid parent to allow for sorting. The fix was to change the empty apply-templates node in the default search XSL:
<xsl:apply-templates />

to the following:
<xsl:apply-templates select="All_Results/Result">
    <!-- The xsl-sort needs operate upon a single field - it doesn't work if the sort has to evaluate child nodes--> 
    <xsl:sort select="title" />
   </xsl:apply-templates>

Note that I didn't require the other elements in the Search XML (the TotalResults and the NumberOfResults nodes), so this solution may not work in your scenario. This list can then act as a facility for cross-site collection navigation (which is not available out of the box in SharePoint 2010)


Another limitation of this approach is that it will only work on a non-paged resultset - which is a pretty major limitation! In our scenario (for Phase 1 of our provisioning solution), it was acceptable for our customer to increase the page size to avoid any pagination from occurring. Your mileage may vary.

Other solution options are:
  1. Scripting - Using jQuery to do a search call and sorting and paging the results yourself
  2. Server side - with your own custom web part that also does the paging for you - using the SPGridView or inheriting from
    Microsoft.Office.Server.Search.WebControls.CoreResultsWebPart
    
Phase 2 of our project will use a combination of Server Side customization (as described at http://msdn.microsoft.com/en-us/gg620579) by extending the CoreResultsWebPart
 and the jQuery approach above for easy inline searching of accessible site collections.
DDK