.net: May 2009 Archives
One of the really annoying things with PDB files is when you don't have them for something. Be it 3rd party component, module you just plain don't care about. John Robbins seems to be the PDB guru and has written "Keeping specific PDB files from loading in the debugger".
The guy's a genius.
The guy's a genius.
It's (finally!) here...
Most useful is (having blogged recently about another Colour Picker), the ColorPalete. Hopefully it'll be of a high enough calibre. And second most useful (given that it doesn't provide multiple file-upload facilities and the nice UI of the one I'm already using, is the FileUploadField.
Given that we've managed to find a few files that our current implementation vomits on, it's well worth a try!
Most useful is (having blogged recently about another Colour Picker), the ColorPalete. Hopefully it'll be of a high enough calibre. And second most useful (given that it doesn't provide multiple file-upload facilities and the nice UI of the one I'm already using, is the FileUploadField.
Given that we've managed to find a few files that our current implementation vomits on, it's well worth a try!
Just because these two articles really can't get enough link-love! The definitive guide to PDB files, what they are, how to use them and why you (as a developer) should have a really deep understanding of just how much easier they can make your life.
John Robbins - PDB Files: What every developer must know
John Robbins - Visual Studio remote debugging and PDB files
John Robbins - PDB Files: What every developer must know
John Robbins - Visual Studio remote debugging and PDB files
Another load of "Notes to Self", this time around changing a users password on a remote machine / domain:
- CodeProject: How to change a user's password on a remote computer
- CodeProject: How to get a list of users from a server
- pinvoke.net: NetServerEnum
- pinvoke.net: DsGetDcName
Say you wanted toget a list of all the SLN (Visual Studio Solution) files in a given directory and all child directories, sorted alphabetically, you could use something similar to this:
public static void GetSolutionList()
{
DirectoryInfo d = new DirectoryInfo(@"C:\Solutions\");
FileInfo[] items = d.GetFiles("*.sln", SearchOption.AllDirectories);
Array.Sort(items, new FileInfoComparer());
List<string> solutions = new List<string>();
foreach (FileInfo f in items)
{
solutions.Add(f.FullName);
}
}
public class FileInfoComparer : IComparer<FileInfo>
{
public int Compare(FileInfo x, FileInfo y)
{
return ((new CaseInsensitiveComparer()).Compare(y.Name, x.Name));
}
}
The key bit of "magic" is the FileInfoComparer - whilst this is a simple one, it shows how easy it is to implement a comparer for the purposes of sorting!
public static void GetSolutionList()
{
DirectoryInfo d = new DirectoryInfo(@"C:\Solutions\");
FileInfo[] items = d.GetFiles("*.sln", SearchOption.AllDirectories);
Array.Sort(items, new FileInfoComparer());
List<string> solutions = new List<string>();
foreach (FileInfo f in items)
{
solutions.Add(f.FullName);
}
}
public class FileInfoComparer : IComparer<FileInfo>
{
public int Compare(FileInfo x, FileInfo y)
{
return ((new CaseInsensitiveComparer()).Compare(y.Name, x.Name));
}
}
The key bit of "magic" is the FileInfoComparer - whilst this is a simple one, it shows how easy it is to implement a comparer for the purposes of sorting!
Riffing on "dix-huit ans aujoud'hui = 18 pounds!" from Frankarr, an australian blogger.
In the entry he mentions that "One fact about 18 which I really love is that 18, aside from 0, is the only number that equals twice the sum of its decimal digits - cool huh?". Now, being a geek I had to write a scratch program t prove that one way or the other, without further ado here it is:
for (int i = 0; i < int.MaxValue -1; i++)
{
string intValue = i.ToString();
int sumValue = 0;
foreach (char digit in intValue.ToCharArray())
{
sumValue += ((Convert.ToInt32(digit.ToString()))* 2);
}
if (sumValue == i)
{
Console.WriteLine("Value found: {0}", i);
}
int modulus = i % 100000;
if (modulus == 0)
{
Console.WriteLine(string.Format("{0}", i));
}
}
The second Console.WriteLine is just so that when running, I can see that the program hasn't frozen/crashed. And it's true, in all the numbers between 0 and int.MaxValue -1, there are no numbers other than 0 and 18 where his fact holds true. Geeky goodnesss!
In the entry he mentions that "One fact about 18 which I really love is that 18, aside from 0, is the only number that equals twice the sum of its decimal digits - cool huh?". Now, being a geek I had to write a scratch program t prove that one way or the other, without further ado here it is:
for (int i = 0; i < int.MaxValue -1; i++)
{
string intValue = i.ToString();
int sumValue = 0;
foreach (char digit in intValue.ToCharArray())
{
sumValue += ((Convert.ToInt32(digit.ToString()))* 2);
}
if (sumValue == i)
{
Console.WriteLine("Value found: {0}", i);
}
int modulus = i % 100000;
if (modulus == 0)
{
Console.WriteLine(string.Format("{0}", i));
}
}
The second Console.WriteLine is just so that when running, I can see that the program hasn't frozen/crashed. And it's true, in all the numbers between 0 and int.MaxValue -1, there are no numbers other than 0 and 18 where his fact holds true. Geeky goodnesss!
Yet another link dump of things that I'm probably going to find useful:
Creating a folder inside the ZIP file with System.IO.Packaging
Fire and Forget class for ASP.NET
ASP.NET 4.0 and Visual Studio 2010 Web Development Overview
And a link that's as amusing as it is interesting, "Teach me to smoke", which reminds me of being at University where the example of how to boil a kettle was used as an exercise in exactly the same way.
Creating a folder inside the ZIP file with System.IO.Packaging
Fire and Forget class for ASP.NET
ASP.NET 4.0 and Visual Studio 2010 Web Development Overview
And a link that's as amusing as it is interesting, "Teach me to smoke", which reminds me of being at University where the example of how to boil a kettle was used as an exercise in exactly the same way.
More of a note to self than anything else, as the software I'm working on uses a dervived System.Web.UI.Page and always uses a set master page, so time is saved by having a custom webform template:
Really rather useful!
- In vs.net 2008, how to add a 'using blah.myblah;' to all new page codebehinds?
- Changing the default using directives in Visual Studio
- Visual studio 2005 - Item Templates
- Item templates - adding references by default
Really rather useful!
There are numerous ways to read CSV files in .net, using ODBC, using Jet OLED, and then hand-crafting a solution using string.Split (which is almost always the worst way to do things). Not to mention a multitude of home-grown solutions on codeproject.com and the like. None of which seem to handle every case.
One that seems to receive very little press is the TextFieldParser in the Microsoft.VisualBasic.IO namespace. Quite why this got "relegated" to what is effectively the modern-day MSVBVMxx.DLL, I have no idea as it's bloody useful. Yes. Bloody useful!
One that seems to receive very little press is the TextFieldParser in the Microsoft.VisualBasic.IO namespace. Quite why this got "relegated" to what is effectively the modern-day MSVBVMxx.DLL, I have no idea as it's bloody useful. Yes. Bloody useful!
I think I agree wholeheartedly with Ken Cox that commercial blogs should not be allowed on a community site. The "Visual WebGui" blog is purely marketing, so has no place on weblogs.asp.net!
From Aaron Stebner's Weblog, is a way to determine the currently installed version of the .net Framework 3.0/3.5. What would be even nicer (and I'm sure it's somewhere, I've just yet to find it) is if there was a Win32 API call that could be made to determine the currently installed version(s) of the .net Framework.
How about a DLL in System32 called "NetFrameworkInfo" that exposes a GetVersionInfo method, or an IsAtLeastVersion method. That said, how long would it be until these had GetVersionInfoEx and IsAtLeastVersionEx siblings? ;-)
How about a DLL in System32 called "NetFrameworkInfo" that exposes a GetVersionInfo method, or an IsAtLeastVersion method. That said, how long would it be until these had GetVersionInfoEx and IsAtLeastVersionEx siblings? ;-)
The final piece of the puzzle to get an Expression Builder working is the entries that are required in the web.config file. Assuming that your expression builder class is in the App_Code directory, the following is all that's required:
<expressionBuilders>
<add expressionPrefix="L10N" type="LocalisationExpressionBuilder" />
</expressionBuilders>
That gets placed in the <configuration><system.web><compilation> node of the web.config file and points to the LocalisationExpressionBuilder type that was previously created.
It's really that simple.
<expressionBuilders>
<add expressionPrefix="L10N" type="LocalisationExpressionBuilder" />
</expressionBuilders>
That gets placed in the <configuration><system.web><compilation> node of the web.config file and points to the LocalisationExpressionBuilder type that was previously created.
It's really that simple.
An expression builder is invoked by ASP.net when it transforms the ASP.net server control markup into C# code ready to be compiled and then rendered out, allowing code to be invoked to set properties on controls without having to put it into the coded-behind.
A specimen expression builder class is below:
A specimen expression builder class is below:
using System;This basically allows a server control to be marked-up as follows:
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.Compilation;
using System.CodeDom;
[ExpressionPrefix("L10N")]
public class LocalisationExpressionBuilder : ExpressionBuilder
{
public LocalisationExpressionBuilder()
{
}
public override bool SupportsEvaluate
{
get
{
return true;
}
}
public override object EvaluateExpression(object target, BoundPropertyEntry entry, object parsedData, ExpressionBuilderContext context)
{
return entry.Expression;
}
public override CodeExpression GetCodeExpression(BoundPropertyEntry entry, object parsedData, ExpressionBuilderContext context)
{
CodeExpression[] inputParams = new CodeExpression[] { new CodePrimitiveExpression(entry.Expression) };
return new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(this.GetType()),
"GetRequestedValue", inputParams);
}
public static object GetRequestedValue(object expression)
{
string expressionString = (string)expression;
if (expressionString == "a.localisation.string")
{
return "b";
}
else
{
return expressionString;
}
}
}
<asp:Literal runat="server" Text="<%$ L10N: a.localisation.string %>In that example, the "Text" property will be set to "b", if the string in the expression was anything else, it would be echo'd back. The code in the static "GetRequestedValue" method could do anything. In my working solution it connects to the database.
Some linkage first:
For example:
- Use ExpressionBuilder To Avoid "Server tags cannot contain <% ... %> constructs"
- The CodeExpressionBuilder
- skmExpressionBuilders - A Suite of Custom Expression Builder Classes
- Using Expression Builders in ASP.NET
For example:
In a product I'm working on I'm planning on using it to implement database backed localisation for UI strings. The current solution has all pages inherit from a base page that provides an abstract "SetLocalisedStrings" method which gets called and is responsible for setting all the relevant ".Text" properties of various controls. Clunky, and it separates the localisation keys from the actual controls making it hard to match-up what goes where.
<asp:Literal runat="server" Text="<%$ MyExpressionBuilder: my.key.that.gets.handled %>
If I said 177 types are loaded by the .net framework, what scenario would you expect me to be describing? How about a simple hello world app?
Ouchies!
Ouchies!
(How much effor goes into writing Colour with a U after spending time coding,... argh!)
There's a pretty nice one, that improves on the one that comes with Coolite (the <ext:ColorPalette>) to be found here: Ext.ux.ColorPicker, Ext.ux.ColorPanel and Ext.ux.ColorDialog for ExtJS 2.1
There's a pretty nice one, that improves on the one that comes with Coolite (the <ext:ColorPalette>) to be found here: Ext.ux.ColorPicker, Ext.ux.ColorPanel and Ext.ux.ColorDialog for ExtJS 2.1
Coolite, by default will "break" any page that has the <meta http-equiv="X-UA-Compatible" content="IE=7" /> tag in it, as IE requires the tag to be pretty much the first one in the <head> tag.
Any page that has Coolite components loaded will thus have the Coolite script/CSS tags inserted right at the top of the <head> element. Fear not though, the Coolite ScriptContainer comes to the rescue! By adding this into the <head> element in your page/master page, you can tell Coolite where to insert its tags which thus stops it from breaking the X-UA-Compatible meta-tag.
Any page that has Coolite components loaded will thus have the Coolite script/CSS tags inserted right at the top of the <head> element. Fear not though, the Coolite ScriptContainer comes to the rescue! By adding this into the <head> element in your page/master page, you can tell Coolite where to insert its tags which thus stops it from breaking the X-UA-Compatible meta-tag.
