Recently in asp.net Category

Coolite - File Upload Dialog & other breaking changes

|
I think I've mentioned the custom File Upload Dialog for Coolite previously which sadly doesn't seem to work with Coolite v0.8 due to a breaking change that's not mentioned in the Version 0.8.0 -BREAKING CHANGES forum post. In summary, the ParameterCollection object no longer has a "ToJsonObject" method, but this has been replaced/renamed with "ToJson". Changing the source for the file upload dialog and re-compiling resolves this.

I also found that, as mentioned in ScriptContainer location not honoured in 0.8 against 0.7, the behaviour of the Coolite ScriptContainer has changed as it now seems to have been split-out into the ScriptContainer and StyleContainer controls. Easily solved, but no less annoying that I had to spend time doing so.

extJs: Combobox .getValue oddity - 2 (The "Solution")

|
Previously: extJs: Combobox .getValue oddity

Here's a quick-hacky solution (a better one would be to ensure your combobox's are selection-only):

Ext.override(Ext.form.ComboBox, {
    getValue: function()
    {
        return this.value;
    }
    });

Coolite documentation

| | Comments (3)
It might only have been auto-gen'd from the sourcecode, but it's still better than nothing: Coolite Toolkit Documentation. The quality of (or lack of) documentation seems to be a fairly frequent complaint on the Coolite forums, and as there's not quite always a one-to-one mapping between Coolite and extJs, looking at the (comprehensive) extJs documentation isn't always useful.

In addition, to anyone working with Coolite, I would strongly recommend downloading the sourcecode and reviewing it when you come across strange/unexpected/confusing behaviours. It's not that difficult to step-through and get a fairly good idea of what's going on!

extJs: Combobox .getValue oddity

| | Comments (2)
At least in extJs version 2.2.1 (the version baked into Coolite v0.8), the getValue function on the Ext.form.ComboBox appears to be thus:

function()
{
  if (this.valueField&&this.forceSelection)
  {
    return typeof this.value!="undefined"?this.value:"";
  }
  else
  {
    return Ext.form.ComboBox.superclass.getValue.call(this);
  }
}
Of interest is the fact that differing code-paths are taken based on the "forceSelection" property. If it's set (i.e. thou shalt choose something from this combo and not enter free-text), then the .value property is used as the return value of the call to getValue, otherwise a call is made to superclass.getValue, which returns something quite entirely different!

Instead of, as expected, returning the "key" value, it returns the displayed value. This is thanks to superclass.getValue being defined as:

function()
{
  if (!this.rendered)
  {
    return this.value;
  }
  var v=this.el.getValue();
  if (v===this.emptyText || v===undefined)
  {
    v='';
  }
  return v;
}
Whilst I've logged this as an "oddity", it is (seemingly) "by-design" as the combo-box allows for user-entered values, which is what the "forceSelection" code-branch causes. That said, I firmly believe that if the "selected value" is one that has been chosen from the contained items, then getValue should return in the same way as it does with forceSelection being false.

Miscellanea 15

|
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.

Community Blogs and Commercial software

|
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!

ASP.net Expression Builders 3 - In the web.config file

|
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.

ASP.net Expression Builders 2 - For Localisation

|
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:

using System;
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;
        }
    }
}
This basically allows a server control to be marked-up as follows:

<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.

ASP.net Expression Builders

|
Some linkage first:
Put basically, expression builders allow you to "intercept" the ASP parser before it starts actually processing server tags and thus insert code into the C# that's generated by the ASP.net markup, so you can set the values of properties in the ASP.net markup, rather than doing it in the Page_Load, or similar, method.

For example:

<asp:Literal runat="server" Text="<%$ MyExpressionBuilder: my.key.that.gets.handled %>
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.

Coolite - "breaks" the IE7/8 X-UA-Compatible meta-tag

|
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.

Miscellanea 12

|
Stop Blaming Technology and Own Up to Responsibility

Never a truer word spoken. The number of times we see a "XYZ will solve everything", or, "ABC is no good for anything" is silly. Use the right tools for the job, don't try and use a screwdriver to hammer a nail in and don't expect an adjustable spanner to fit all sizes of nut. Metaphors aside, take a read of the linked blog entry, well worth reading.

Side by side: UI changes from Windows 7 beta to build 7048

Shiny, pretty. I've, personally, never had performance issues with Vista (or with anything else for that matter, so I'd quite like the Cialis/Viagra spam to stop, heh). If Windows 7 is faster than Vista, I'm gonna be laughing! What I do hope is that some of the UI "annoyances" where it takes longer to do things in Vista than XP are resolved. Like, getting to the screen to adjust multiple-monitors, t'was on the desktop right-click in XP. In Vista it's desktop right-click then choose option from window that opens. Ugh.

ASP.NET Configuration File Hierarchy and Inheritance

Must read in detail. I need to work out if it's possible to include/exclude different HTTPModules (say different modules for processing file uploads) in different levels of a single asp.net application by having web.config files in sub-directories. Initial (10minute) investigation seems to indicate it works in Cassini, but not in IIS6. Grr!
Could not load file or assembly 'NameOfAssemblyGoesHere' or one of its dependencies. An attempt was made to load a program with an incorrect format.

This message being spewed-forth by an asp.net application means that the DLL concerned has been compiled as a specific "bitness", but one that doesn't match that which IIS is running at. The most usual reason for this is an assembly marked as "x86" deployed to an "x64" server. If the assembly doesn't P/Invoke out to any 32-bit DLLs, change the platform target to "AnyCpu".

As far as the .net framework is concerned, the x86/x64 categorisation is only used as an indicator of requirements, thus if no P/Invoke is going on it's not needed, as the JIT compiler takes the assembly and JIT compiles it to the relevant instruction set at runtime anyway.

Miscellanea 5

|
asp.net example

Enough examples of various different bits of asp.net to sink a small ocean going vessel.

VB.NET to C# Conversion Hints, Tips and Gotchas

Simply what it says in the title.

Why I prefer c# over VB

Everyone's entitled to an opinion, I guess!

Exclude SCC / VSSSCC files from Web Setup Projects

|
The structure of a Web Setup Project (.vdproj) file is just plain strange as it's "kinda" like XML but with curly braces ( { and } ) and quotes instead of < and > symbols.Go figure.

If you have a large website that you build an MSI for using this technology, it's worth excluding "SCC" and "VSSSCC" files from the installer that's produced as you don't need them on the web server target and it'll reduce the install time and MSI size by a teeny tiny fraction. Anyhow, to do this, look for "ProjectOutput" in the .vdproj file in notepad and you'll find something similar to:

        "ProjectOutput"
        {
            "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_BD879AEA2DAF432A83AD511860E15E8C"
            {
            "SourcePath" = "8:"
            "TargetName" = "8:"
            "Tag" = "8:"
            "Folder" = "8:_9C12D7A6BA9C4F5EB16D2E73FBD55EB3"
            "Condition" = "8:"
            "Transitive" = "11:FALSE"
            "Vital" = "11:TRUE"
            "ReadOnly" = "11:FALSE"
            "Hidden" = "11:FALSE"
            "System" = "11:FALSE"
            "Permanent" = "11:FALSE"
            "SharedLegacy" = "11:FALSE"
            "PackageAs" = "3:1"
            "Register" = "3:1"
            "Exclude" = "11:FALSE"
            "IsDependency" = "11:FALSE"
            "IsolateTo" = "8:"
            "ProjectOutputGroupRegister" = "3:1"
            "OutputConfiguration" = "8:"
            "OutputGroupCanonicalName" = "8:ContentFiles"
            "OutputProjectGuid" = "8:{A986933C-EB0C-4375-8B80-6E948D13A0BD}"
            "ShowKeyOutput" = "11:TRUE"
                "ExcludeFilters"
                {
                "ExcludeFilter" = "8:*.refresh"
                "ExcludeFilter" = "8:*.vssscc"
                "ExcludeFilter" = "8:*.scc"

                }
            }

I've already put in the bits you need to add (in bold). Simple as that!

Populate an ASP.net ListBox with the values of an enumeration

|
Kind of like: Obtaining the string value of an enumeration name (but not).

        public void PopulateListBoxFromEnum(DropDownList listBox, Type enumeration)
        {
            string[] descriptiveValues = Enum.GetNames(enumeration);
            foreach (string descriptiveValue in descriptiveValues)
            {
                int statusValue = Convert.ToInt32(Enum.Parse(enumeration, descriptiveValue, true));
                listBox.Items.Add(new ListItem(descriptiveValue, statusValue.ToString()));
            }
        }

Not a lot more to say really, other than, see above ;-)