Tag Archives: .NET

Visual Studio Tip #1: Ignoring Whitespace when Comparing

When comparing files, it’s frustrating when the default compare, doesn’t ignore whitespace, and many differences are caused by spaces vs tabs.

Solve it, by adjusting the parameters DiffMerge uses.

In Visual Studio:

  1. Tools->Options
  2. Source Control->Visual Studio Team Foundation Server
  3. Click the Configure User Tools button.

Now add an item with the following settings.

  • Extension : .*
  • Operation : Compare
  • Command : C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\diffmerge.exe
  • Or: C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\diffmerge.exe
  • Arguments : %1 %2 %6 %7 %5 /ignorespace

Entity Framework Tip #1: Loading Grandchildren

When calling .FindById(), it’s a relatively simple task, to have it include child properties explicitly. Simply add a lambda expression.

	myRepository.FindById(1, x=>x.ChildList);

This will ensure that the ChildListis populated and not null.

But what if you need to ensure a GrandChildren entity is populated as well? Writing this won’t work because ChildList is a collection.

	myRepository.FindById(1, x=>x.ChildList.GrandChildren);

What you need to do, is use .Select()

	myRepository.FindById(1, 
		x=>x.ChildList, 
		x.ChildList.Select(y=>y.GrandChildren)
		);

Simple…albeit non-intuitive.

AOP – Logging with Unity

I couple months ago I was tasked with adding logging to an application we are developing. Now, the typical way people handle this, is with a call to “Logger.Log” wherever they want to log that an activity took place. However, this relies on the programmers memory, and while the original team members may know and remember to keep up this practice. The new guy on the team may not. And this is where this technique really starts to break down. Logging is a cross cutting feature. We can’t keep all the code in one place, because it’s called from all over the application.

The solution, is AOP (Aspect Oriented Programming). Since we were using Unity, it’s quite simple to intercept calls based on an interface. There is more it’s capable of, but the issue I had was I couldn’t find a simple, “hello world” example. Everything felt the need to over complicate the example.

First things first, on your project, right click, Manage NuGet packages and add Unity Interception Extension.

Second: Config changes

<?xml version="1.0"?>
<configuration>
    <configSections>
        <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/>
    </configSections>
    <unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
      <sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Microsoft.Practices.Unity.Interception.Configuration"/>
 
      <container>
        <extension type="Interception" />
 
        <register type="LoggingTest.Namespace.IInterfaceToLog, LoggingTest.Namespace.Assembly">
          <interceptor type="InterfaceInterceptor" />
          <interceptionBehavior type="LoggingTest.Namespace.Loggers.LoggerBehavior, LoggingTest.Namespace.Assembly"/>
        </register>
      </container>
    </unity>
</configuration>

Third: Create Behavior

   public class LoggerBehavior : IInterceptionBehavior
    {
        public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
        {
            var stopwatch = new Stopwatch();
 
            var logger = LogManager.GetLogger(input.MethodBase.ReflectedType);
 
            var declaringType = input.MethodBase.DeclaringType;
            var className = declaringType != null ? declaringType.Name : string.Empty;
            var methodName = input.MethodBase.Name;
            var generic = declaringType != null && declaringType.IsGenericType
                              ? string.Format("<{0}>", string.Join<Type>(", ", declaringType.GetGenericArguments()))
                              : string.Empty;
 
            var argumentWriter = new StringWriter();
            for (var i = 0; i < input.Arguments.Count; i++)
            {
                var argument = input.Arguments[i];
                var argumentInfo = input.Arguments.GetParameterInfo(i);
                argument.Dump(argumentInfo.Name, argumentWriter);
            }
            var methodCall = string.Format("{0}{1}.{2}\n{3}", className, generic, methodName, argumentWriter);
 
            logger.InfoFormat(@"Entering {0}", methodCall);
 
            stopwatch.Start();
            var returnMessage = getNext()(input, getNext);
            stopwatch.Stop();
 
            logger.InfoFormat(@"Exited {0} after {1}ms", methodName, stopwatch.ElapsedMilliseconds);
 
            return returnMessage;
        }
 
        public IEnumerable<Type> GetRequiredInterfaces()
        {
            return Type.EmptyTypes;
        }
 
        public bool WillExecute
        {
            get { return true; }
        }
    }

That’s it. One simple class that does the logging. And a config change to mark what interfaces you want logged.

        <register type="LoggingTest.Namespace.IInterfaceToLog, LoggingTest.Namespace.Assembly">
          <interceptor type="InterfaceInterceptor" />
          <interceptionBehavior type="LoggingTest.Namespace.Loggers.LoggerBehavior, LoggingTest.Namespace.Assembly"/>
        </register>

This config change will run the LoggerBehavior on the methods defined in LoggingTest.Namespace.IInterfaceToLog. If you want to log the methods on more interfaces, just add another register node to the config. While you still need to add these manually. You do it at the interface level, rather than the method level. AND you can add/change what is logged after compiling.

There is more you can do, check the Unity codeplex page.

Wrap existing .NET site in a Portal/Theme

Recently I ran into the problem where we were attempting to have all of our websites run inside of a portal. Where you could easily jump from one app to another, without having to go back and forth, or always back to a home page with links.

What we wanted was a header menu added to ALL of our websites that handled some authentication, and showed what websites you had access to, and allowed you to easily navigate between them, as though they were one large application.

Now, rewriting all these applications would be a nightmare. There was no time. Even if the goal was simply to modify the master pages of each app…some of which were very dated, and didn’t have the luxury of master pages.

So with a little research on the Page Adapter Class and some creative use of the .browsers file, I came up with an unobtrusive method to easily add our new portal to all existing applications, without any recompiling.

First, lets create our Portal Page Adapter project. Add a new class file named PortalPageAdapter.cs

namespace PortalPageAdapter
{
	using System;
	using System.Collections.Generic;
	using System.Linq;
	using System.Text;
	using System.Web.UI;
	using System.Web.UI.HtmlControls;
	using System.Xml;
	using System.Web.UI.WebControls;
	using System.Web;
	using System.Security.Principal;
	using System.Xml.Linq;
 
	public class PortalPageAdapter : System.Web.UI.Adapters.PageAdapter
	{
		protected override void OnInit(EventArgs e)
		{
			// Do whatever security checks you need to do...
			string user = HttpContext.Current.Request.LogonUserIdentity.Name;
 
			List<string> roles = new List<string>();
 
			//populate your roles
 
			// Setup Context
			HttpContext.Current.User = new GenericPrincipal(HttpContext.Current.User.Identity, roles.Distinct().ToArray());
 
			base.OnInit(e);
		}
 
		protected override void CreateChildControls()
		{
			base.CreateChildControls();
 
			// Inject portal onto page
			HtmlForm html = this.Page.Controls.OfType<HtmlForm>().First();
			html.Controls.AddAt(0, new LiteralControl("<br/>PORTAL GOES HERE"));
 
			// Hide WebControls based on their Role Attribute
			// 	This allows the portal, to handle the rendering of any websites 
			//	you have, it can show/hide items at the control level
 
			List<WebControl> controls = html.Controls.OfType<WebControl>()
				.Where(c => ! string.IsNullOrEmpty(c.Attributes["role"]))
				.ToList();
 
			foreach (WebControl control in controls)
			{
				control.Visible = false;
 
				foreach (string role in control.Attributes["role"].Split(' '))
				{
					if (HttpContext.Current.User.IsInRole(role))
					{
						control.Visible = true;
						break;
					}
				}				
			}
		}
	}
}

Now that we have our portal written, with a trick up it’s sleeve to hide/show content based upon the users roles, let’s look at how we add it to an existing website.

In the App_Browsers folder, add a file called default.browsers

<browsers>
	<browser refID="Default">
		<controlAdapters>
			<adapter controlType="System.Web.UI.Page" adapterType="PortalPageAdapter.PortalPageAdapter" />
		</controlAdapters>
	</browser>
</browsers>

And add the compiled dll of our PortalPageAdapter class to the bin folder.

Navigate to your website and the first thing you see should be the line “PORTAL GOES HERE”, which you can modify in the Portal Page Adapter class to create whatever content you would like. How you generate the html is up to you. Be it includes, databases, xml/xsl, whatever. Get creative.

Now, the last thing, is, the ‘trick’ that has been programmed in, on any aspx page, you can add the “role” attribute to any WebControl (asp:whatever) and it will be rendered (or not) based upon the roles loaded by the PortalPageAdapter class.

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="PageAdapter._Default" %>
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
	<title></title>
</head>
<body>
	<form id="form1" runat="server">
	<div>
		<asp:Panel runat="server">
			Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum imperdiet justo id sem. Aenean convallis mi sed ipsum. Donec semper dapibus erat. Suspendisse consequat libero quis felis feugiat aliquam. Sed nec elit. Fusce sapien tellus, vestibulum id, pharetra in, scelerisque sit amet, lectus. Vivamus eu turpis at nunc elementum ultricies. Morbi feugiat fringilla est. Fusce urna diam, accumsan vitae, ultrices non, varius vitae, quam. Vivamus vitae enim vel nulla mattis aliquam. Suspendisse lacinia arcu non urna. Praesent convallis ante ut sapien. Nunc sit amet mauris ornare mauris accumsan ultricies. Praesent venenatis tellus id quam. Fusce vel enim a est malesuada venenatis.
			<p />
		</asp:Panel>
		<asp:Panel runat="server" role="ADMIN">
			Sed eget mauris vitae libero imperdiet malesuada. Suspendisse feugiat semper erat. Duis sit amet odio ultricies dui ultrices volutpat. Sed id risus vitae odio bibendum varius. Nam rutrum consectetur felis. Donec vitae velit. Phasellus facilisis ornare mi. Etiam quis dui id leo bibendum vehicula. Proin egestas, neque quis pulvinar malesuada, odio tellus porta orci, nec dictum est nunc id diam. Integer eu dui. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Ut nec ante ut pede ornare ornare. Mauris eget mauris et urna tincidunt tincidunt. Suspendisse sit amet lacus in dui fermentum aliquam. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse odio. Phasellus orci. Aliquam erat volutpat. Nam eget ligula id arcu fermentum lobortis. Sed vel leo.
			<p />
		</asp:Panel>
		<asp:Panel runat="server" Role="USER ADMIN">
			Suspendisse pulvinar. Etiam ipsum. Proin vulputate nibh et purus. Nunc hendrerit. Morbi consequat nibh id tortor. In mollis rhoncus velit. Pellentesque magna ipsum, cursus sit amet, viverra eu, porttitor et, dolor. Cras quis sem. Ut interdum nisi quis magna. Donec mauris erat, consequat id, gravida eu, scelerisque ac, nisi. Nulla ante purus, dignissim nec, mollis quis, euismod quis, arcu. In vel arcu. Duis enim erat, accumsan vel, blandit vel, ultricies id, pede. Nulla luctus, nisi at faucibus tincidunt, orci sapien ornare erat, vitae iaculis justo risus ut magna.
			<p />
		</asp:Panel>
		<asp:Panel runat="server" Role="MANAGER">
			Etiam imperdiet lacus at dui fringilla dictum. Etiam condimentum, diam vitae fringilla faucibus, ante ante facilisis nulla, at porttitor diam ipsum vel odio. Aliquam sollicitudin neque et diam. Aenean feugiat, justo ut imperdiet cursus, sem risus ultrices ligula, eget rutrum orci leo tempor enim. Nunc eget velit. Pellentesque dictum, odio a tempor aliquet, ipsum justo lacinia mauris, sed posuere metus enim vel ipsum. Donec dolor. Aliquam semper, eros vitae vehicula lacinia, dolor massa suscipit libero, a molestie enim justo tincidunt sem. Praesent eget mi ut purus interdum vehicula. Nulla a leo. Morbi lacinia, ligula id pharetra vulputate, sapien arcu dignissim tortor, ac condimentum velit libero at purus.
			<p />
		</asp:Panel>
		<asp:Panel runat="server">
			Donec adipiscing lacus ac sapien. Nulla ac quam. Sed enim. Curabitur magna. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras viverra, libero quis molestie cursus, justo lacus semper nisl, in fringilla enim pede ac elit. Pellentesque facilisis. Etiam fringilla adipiscing mauris. Vivamus bibendum nibh nec massa. Maecenas risus. Cras tempus accumsan pede. Cras dictum hendrerit dolor. Curabitur et tortor ullamcorper elit mattis lacinia. Cras tempus euismod velit. Donec feugiat nunc quis dui. Vivamus nisi urna, bibendum et, imperdiet sit amet, facilisis in, libero. Maecenas lobortis velit at ante. Aenean in lacus et massa fringilla molestie. Praesent mollis nibh ut nunc.
			<p />
		</asp:Panel>
		<asp:Button runat="server" role="ADMIN" Text="Admin Button" />
		<asp:Button runat="server" role="USER MANAGER" Text="User Button" />
	</div>
	</form>
</body>
</html>

This would also be a simple way to add an embeded IM client to a series of websites.

Happy coding.

The C# ?? null coalescing operator

A simple tip to save typing and increase your codes readability is the “double question mark operator”, more accurately called the “null coalescing operator”.

Instead of using this to set defaults in a function

function void test(int aVar) {
	int myVar = aVar;
	if (aVar == null) {
		myVar = 42;
	}
}

or

function void test(int aVar) {
	int myVar = aVar == null ? 42 : aVar;
}

You can simply use

function void test(int aVar) {
	int myVar = aVar ?? 42;
}

Granted, you’d likely find much better ways to use this than simply defaults in a function call, but hey, this is just an example, let your imagination do the work.

MSDN reference: http://msdn.microsoft.com/en-us/library/ms173224.aspx

XML Validation with XSDs

I’ve been doing a lot of work with excel uploads lately to allow clients to easily upload data to their systems.  Not the best approach mind you, but they know how to use excel…so what can you do?

What I have worked out is a multi step process to import the excel file to the database and validate the contents to a reasonable degree.  I have these all written into some custom classes and use IOC and DI to handle workflow so that writing subsequent uploads is a trivial task, and the majority of code is simply the validation and transformation files (XSDs, XSLs, and Stored Procs)

First, you have to retrieve the contents of the excel sheet(s)

protected XElement GetWorksheetXML(int sheetNumber, string xsltPath)
{
  // Create working file
  string workingFilePath = Path.GetTempFileName();
  File.WriteAllBytes(workingFilePath, this.filebytes);
 
  // Read the worksheet
  DataSet myDataSet = new DataSet();
  string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + workingFilePath + ";Extended Properties='Excel 8.0;HDR=No;IMEX=1;'";
 
  // Fill the Dataset
  OleDbDataAdapter myCommand = new OleDbDataAdapter("SELECT * FROM [" + GetExcelSheetNames(strConn)[sheetNumber] + "]", strConn);
  myCommand.Fill(myDataSet);
 
  // Clean up
  File.Delete(workingFilePath);
 
  // Return transformed XML
  return XElement.Parse(Utility.Transform(myDataSet.GetXml(), xsltPath, null));
}

Secondly, convert it to a better XML format with an XSLT.  You should also merge any sheets here so you have one XML file from the XSL.  I’m not going to bother showing this, as it’s hardly the point of the article, though, if you are unsure how to do this, feel free to ask

Third, and the whole point of this article, verify data types with XSD.

protected XElement ValidateXSD(XElement item, string xsdPath)
{
  XElement errors = new XElement("Errors");
 
  if (File.Exists(xsdPath))
  {
    // Reference: http://msdn.microsoft.com/en-us/library/bb358456.aspx
    XDocument xsd = XDocument.Load(xsdPath);
    XDocument xml = XDocument.Parse(item.ToString());
    XmlSchemaSet schemas = new XmlSchemaSet();
    schemas.Add("", XmlReader.Create(new StringReader(xsd.ToString())));
    xml.Document.Validate(schemas,
      // Validation Event/Error Handling
      (sender, e) =&gt;
      {
        errors.Add(new XElement("Error", e.Message));
      }
    );
  }
 
  // If there were errors return them, otherwise return null
  return errors.Elements().Count() &gt; 0 ? errors : null;
}

Fourth, at this point, if there are no errors, you should pass the XML file as input to a stored procedure to further validate the data (if there are IDs and Codes that need to be verified with other systems), and assuming all has gone well, pass the XML file to a stored procedure which writes the data into your database…or whatever you need to do.  By this point your XML should be clean, and valid.