Sasha Sydoruk

Building a better mousetrap with XHTML, AJAX and RSS

Archive for January, 2007

“Ambiguous match found” in a Web Control - a Possible Bug

If you use ASP.NET AJAX you might come up with this error popup - “Ambiguous match found”.

The issue here is that you have 2 variables that are named the same but have different casing. You have to rename the variables to have different names. Changing from protected to private will not help.

More info can be found at Eran Sandler’s blog - “Ambiguous match found” in a Web Control - a Possible Bug.

Eran Sandler’s blog - Subscribed!

1 comment

Infragistics vs Telerik - Fight!

http://www.googlefight.com/index.php?lang=en_GB&word1=Infragistics&word2=Telerik

No comments

How to instantiate templates (properly)

Something for myself to bookmark. Here is a really good article describing the right way to instantiate templates in asp.net controls.

Every time a control is added to a parent control the child control will immediately “catch up” to the lifecycle point of the parent control. The control lifecycle includes the familiar Init, Load, PreRender, and a number of other lifecycle stages related to state management. When a template is instantiated through a call to InstantiateIn, all that happens (typically) is that the controls in the template are instantiated one by one, and added to the container that you passed in to InstantiateIn, again one by one.

 How to instantiate templates (properly)

I also subscribed to the blog and waiting for more good articles.

No comments

HowTo - CompositeControl with a TextBox and a bunch of Validators

Here is an example of how I create composite controls in small server control library. It is pretty handy. With controls like this you can say something like this:

<csc:textbox id=”customServerControl1″ minlength=”4″ maxlength=”10″ required=”true” runat=”server” />

And that’s it! The composite control will automatically add the required validators and will create appropriate error messages!

Here is the source code:

using System;
using System.Security.Permissions;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace SashaSydoruk.Web.UI.WebControls
{
[AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal)]
[AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
[ToolboxData(“< {0}:textbox required=\"false\" runat=\"server\" />“)]
[ValidationProperty(“Text”)]
public class TextBox : CompositeControl
{
protected System.Web.UI.WebControls.TextBox _textBox = null;
protected RequiredFieldValidator _reqValidator = null;
protected RegularExpressionValidator _regExValidator = null;
protected TextBoxLengthValidator _lengthValidator = null;
protected string _regExValidatorErrorMessage = string.Empty;

#region Constructors

public TextBox()
{
EnsureChildControls();
}

#endregion

#region Error Messages

public const string REQUIRED = “is a required field.”;
public const string REGEX = “is invalid.”;
public const string LENGTH = “length has to be {0} to {1} characters long”;

#endregion

#region Public Properties

public System.Web.UI.WebControls.TextBox InnerTextBox
{
get { return _textBox; }
}

public RequiredFieldValidator InnerRequiredFieldValidator
{
get { return _reqValidator; }
}

public RegularExpressionValidator
InnerRegularExpressionValidator
{
get { return _regExValidator; }
}

public TextBoxLengthValidator InnerTextBoxLengthValidator
{
get { return _lengthValidator; }
}

public TextBoxMode TextMode
{
get { return _textBox.TextMode; }
set { _textBox.TextMode = value; }
}

public bool ReadOnly
{
get
{
object o = ViewState[“ReadOnly”];
if(o == null)
{
return false;
}
else
{
return bool.Parse(o.ToString());
}
}
set { ViewState[“ReadOnly”] = value; }
}

public int MaxLength
{
get { return _lengthValidator.MaximumLength; }
set
{
_lengthValidator.MaximumLength = value;
SetupValidators();
}
}

public int MinLength
{
get { return _lengthValidator.MinimumLength; }
set
{
_lengthValidator.MinimumLength = value;
SetupValidators();
}
}

public string RegularExpression
{
get { return _regExValidator.ValidationExpression; }
set
{
_regExValidator.ValidationExpression = value;
SetupValidators();
}
}

public string DisplayName
{
get
{
object o = ViewState[“DisplayName”];
if(o == null)
{
return string.Empty;
}
else
{
return o.ToString();
}
}
set
{
ViewState[“DisplayName”] = value;
SetupValidators();
}
}

public bool Required
{
get { return _reqValidator.Visible; }
set
{
_reqValidator.Visible = value;
SetupValidators();
}
}

public virtual string Text
{
get { return _textBox.Text; }
set { _textBox.Text = value; }
}

#endregion

protected override void OnInit(EventArgs e)
{
EnsureChildControls();
base.OnInit(e);
}

protected override void Render(HtmlTextWriter writer)
{
_textBox.Width = Width;
_textBox.Height = Height;
_textBox.RenderControl(writer);

_reqValidator.RenderControl(writer);
_lengthValidator.RenderControl(writer);
_regExValidator.RenderControl(writer);
}

protected override void CreateChildControls()
{
Controls.Clear();

_textBox = new System.Web.UI.WebControls.TextBox();
_textBox.ID = “textBox”;
Controls.Add(_textBox);

//Add required validator
_reqValidator = new RequiredFieldValidator();
Controls.Add(_reqValidator);

//Add length validator
_lengthValidator = new TextBoxLengthValidator();
Controls.Add(_lengthValidator);

//Add RegularExpression validator
_regExValidator = new RegularExpressionValidator();
Controls.Add(_regExValidator);

if(Width.Value == 0)
{
_textBox.Width = Unit.Pixel(170);
}

Required = false;

SetupValidators();
}

private void SetupValidators()
{
_reqValidator.Display = ValidatorDisplay.None;
_reqValidator.ControlToValidate = _textBox.ID;

_lengthValidator.Display = ValidatorDisplay.None;
_lengthValidator.ControlToValidate = _textBox.ID;

_regExValidator.Display = ValidatorDisplay.None;
_regExValidator.ControlToValidate = _textBox.ID;

if(MaxLength > 0)
{
_textBox.MaxLength = MaxLength;
}

_lengthValidator.Visible = (MaxLength > 0 || MinLength > 0);

_regExValidator.Visible = RegularExpression.Length > 0;

_reqValidator.ErrorMessage = DisplayName + ” “ + REQUIRED;

if(MinLength == 0 && MaxLength > 0)
{
_lengthValidator.ErrorMessage = DisplayName + ” “
+ string.Format(“is too long. {0} characters max.”, MaxLength);
}
else if(MinLength > 0 && MaxLength == 0)
{
_lengthValidator.ErrorMessage = DisplayName + ” “
+ string.Format(“is too short. {0} characters min.”, MinLength);
}
else if(MinLength > 0 && MaxLength > 0)
{
_lengthValidator.ErrorMessage = DisplayName + ” “
+ string.Format(“has to be {0} to {1} characters long.”, MinLength, MaxLength);
}
else if(MinLength > 0 && MaxLength > 0 && MinLength == MaxLength)
{
_lengthValidator.ErrorMessage = DisplayName + ” “ + string.Format(“has to be {0} characters long.”, MinLength);
}

_regExValidator.ErrorMessage = DisplayName + ” “ + REGEX;
}
}
}
2 comments

Windows Live Writer Error

I keep getting the following error while editing my blog settings. Does anyone know solution to this?
—————————
Unexpected Error Occurred
—————————
An unexpected error occurred while attempting to detect weblog settings:

Unable to cast COM object of type ‘mshtml.HTMLMetaElementClass’ to interface type ‘mshtml.IHTMLElement’. This operation failed because the QueryInterface call on the COM component for the interface with IID ‘{3050F1FF-98B5-11CF-BB82-00AA00BDCE0B}’ failed due to the following error: No such interface supported (Exception from HRESULT: 0×80004002 (E_NOINTERFACE)).
—————————
OK
—————————

2 comments

FormsAuthentication.SetAuthCookie does not work the same way in ASP.NET 2.0

Obviously I missed the boat somewhere along the line. I realized today that I’ve never used FormsAuthentication in an ASP.NET v2.0 application before. As it turns out, it doesn’t work the same as it used to.

The full post is here.

No comments

Master feed of Neudesic Blogs - Subscribed!

We have a bunch of Neudesic contractors working at my company and they all look like really bright guys. So, I finally subscribed to the master feed of all the bloggers at their mothership.

Here is the link - Neudesic Blogs.

No comments

Sansa Connect MP3 Player is running on Mono

Well, this is very cool. SanDisk’s Sansa Connect MP3 Player is running on Mono, open source implementation of .NET framework. Endgadget has more info.

Here is some of the features:

  • Integrated WiFi
  • Supports PlaysForSure
  • Works with Vista
  • Streaming Internet radio
  • microSD slot
No comments

C# vs Ruby Smackdown!

Finally I get to write a “smackdown” post. I had this post written for a while now, but just never got to publish it.

Here is my completely non-scientific comparison of C# and Ruby. I will come up with a simple task and will attempt to implement it in both languages. The results will be shown, but no analysis will be available; I don’t want to pick sides because I really like both languages and want to stay on good terms with both of them.

Enough of disclaimers, here is the task. Create a Day class and populate a collection of instances of class Day to represent a week. Display the week in the original order, reverse the order of the days, display the new order, restore the original order, show only the work day and show only the weekends.

Here is the expected output:

Regular Order
Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday

Reversed Order
Sunday, Saturday, Friday, Thursday, Wednesday, Tuesday, Monday

Regular Order
Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday

Work Week
Monday, Tuesday, Wednesday, Thursday, Friday

Weekend
Saturday, Sunday

Here is how I did it in C#:

   1:  using System;
   2:  using System.Collections;
   3:  using System.Collections.Generic;
   4:  
   5:  namespace RubyCsExample
   6:  {
   7:      internal class Example
   8:      {
   9:          public static void Main()
  10:          {
  11:              List<Day> daysOfWeek = Day.CreateWeek();
  12:              DisplayDays(daysOfWeek, “Regular Order”);
  13:  
  14:              //Reverse the order of the days
  15:              daysOfWeek.Sort(delegate(Day one, Day two)
  16:                                  {
  17:                                      return
  18:                                          (Comparer.Default.Compare(one.Ordinal,
  19:                                                                    two.Ordinal)*-1);
  20:                                  });
  21:              DisplayDays(daysOfWeek, “Reversed Order”);
  22:  
  23:              //Restore the order
  24:              daysOfWeek.Sort();
  25:              DisplayDays(daysOfWeek, “Regular Order”);
  26:  
  27:              //Show work week
  28:              DisplayDays(daysOfWeek.FindAll(delegate(Day d)
  29:                                                 {
  30:                                                     return !d.IsWeekend;
  31:                                                 }), “Work Week”);
  32:  
  33:              //Show weekends
  34:              DisplayDays(daysOfWeek.FindAll(delegate(Day d)
  35:                                                 {
  36:                                                     return d.IsWeekend;
  37:                                                 }), “Weekend”);
  38:  
  39:  
  40:              Console.ReadKey();
  41:          }
  42:  
  43:          public static void DisplayDays(List<Day> days, string message)
  44:          {
  45:              if (!string.IsNullOrEmpty(message))
  46:              {
  47:                  Console.WriteLine(message);
  48:              }
  49:              List<string> names = days.ConvertAll(new Converter<Day, string>(delegate(Day d)
  50:                                                                                  {
  51:                                                                                      return d.Name;
  52:                                                                                  }));
  53:              Console.WriteLine(string.Join(“, “, names.ToArray()) + “nn”);
  54:          }
  55:      }
  56:  
  57:      internal class Day : IComparable<Day>, IComparable
  58:      {
  59:          private string name;
  60:          private int ordinal;
  61:          private bool isWeekend;
  62:  
  63:          public Day(string name, int ordinal, bool isWeekend)
  64:          {
  65:              this.name = name;
  66:              this.ordinal = ordinal;
  67:              this.isWeekend = isWeekend;
  68:          }
  69:  
  70:          public string Name
  71:          {
  72:              get { return name; }
  73:              set { name = value; }
  74:          }
  75:  
  76:          public int Ordinal
  77:          {
  78:              get { return ordinal; }
  79:              set { ordinal = value; }
  80:          }
  81:  
  82:          public bool IsWeekend
  83:          {
  84:              get { return isWeekend; }
  85:              set { isWeekend = value; }
  86:          }
  87:  
  88:          public static List<Day> CreateWeek()
  89:          {
  90:              List<Day> days = new List<Day>(7);
  91:  
  92:              days.Add(new Day(“Monday”, 1, false));
  93:              days.Add(new Day(“Tuesday”, 2, false));
  94:              days.Add(new Day(“Wednesday”, 3, false));
  95:              days.Add(new Day(“Thursday”, 4, false));
  96:              days.Add(new Day(“Friday”, 5, false));
  97:              days.Add(new Day(“Saturday”, 6, true));
  98:              days.Add(new Day(“Sunday”, 7, true));
  99:  
 100:              return days;
 101:          }
 102:  
 103:          public int CompareTo(Day other)
 104:          {
 105:              return Comparer.Default.Compare(Ordinal, other.Ordinal);
 106:          }
 107:  
 108:          public int CompareTo(object obj)
 109:          {
 110:              return Comparer.Default.Compare(Ordinal, ((Day) obj).Ordinal);
 111:          }
 112:      }
 113:  }

As you can see, it took me 113 lines to achieve the required result. I am using Generics and some fancy stuff from List<>. You will need C# 2.0 to achieve similar results.

And here is the Ruby way of doing things:

   1:  class Day
   2:    attr_accessor :name, :ordinal, :is_weekend
   3:  
   4:    def initialize(name = :NotSet, ordinal = -1, is_weekend = false)
   5:      self.name, self.ordinal, self.is_weekend = name, ordinal, is_weekend
   6:    end
   7:  
   8:    def to_s
   9:      name
  10:    end
  11:  
  12:    def <=>(other_day)
  13:      self.ordinal <=> other_day.ordinal
  14:    end
  15:  
  16:    def Day.create_week
  17:      days = Array.new
  18:  
  19:      days << Day.new(:Monday, 1, false)
  20:      days << Day.new(:Tuesday, 2, false)
  21:      days << Day.new(:Wednesday, 3, false)
  22:      days << Day.new(:Thursday, 4, false)
  23:      days << Day.new(:Friday, 5, false)
  24:      days << Day.new(:Saturday, 6, true)
  25:      days << Day.new(:Sunday, 7, true)
  26:  
  27:      return days
  28:    end
  29:  
  30:  end
  31:  
  32:  def self.display_days(days, message = nil)
  33:    puts “#{message}n” if message
  34:    puts days.map{|day| day.name}.join(‘, ‘)
  35:    puts “nn”
  36:  end
  37:  
  38:  days_of_week = Day.create_week
  39:  
  40:  display_days(days_of_week, ‘Regular Order’)
  41:  
  42:  #Reverse the order of the days
  43:  days_of_week.sort!{ |a, b| (a <=> b) * -1 }
  44:  
  45:  display_days(days_of_week, ‘Reversed Order’)
  46:  
  47:  #Restore the order
  48:  days_of_week.sort!
  49:  
  50:  display_days(days_of_week, ‘Regular Order’)
  51:  
  52:  #Show work week
  53:  display_days(days_of_week.find_all{|day| !day.is_weekend}, ‘Work Week’)
  54:  
  55:  #Show weekends
  56:  display_days(days_of_week.find_all{|day| day.is_weekend}, ‘Weekend’)

As you can Ruby implementation took only 56 lines to achieve the required result.

Conclusion? I had a lot of fun playing with both languages. Give both languages a try!

12 comments

Prototype 1.5 was released. And now it has documentation and a brand new site!

Wow, what a day… New Rails and new Prototype are out. The new website for Prototype looks really nice. I can’t wait to dive into the documentation and see what’s new!

It also looks like new Script.aculo.us is on the way too.

Future looks bright!

No comments

Next Page »