Welcome to SofiaDev.Org's Blogs Sign in | Join | Help

Silverlight RIA - Jason Beres for SofiaDev.org today. Now available online

Today the SofiaDev.org US will host its monthly meeting. The talk will be about Silverlight and will be held by Jason Beres, MS MVP and an author of a few books for .NET and one for Silverlight.

The event will be broadcasted online at the following address: mms://srv1.msbgregistration.com/sofianet. We'll be online at 7:00 pm local time.

Want to join us? Send me an email at contact _at_ sofaidev.org.


Cheers,
Br

posted by branimir | 0 Comments

European Siverlight Challenge Contest - The Details

I haven't got the chance to post anything interesting in the last few months, but I believe now's a good time to do that.

I'm proud to present the first INETA European Contest - the European Silverlight Challenge in its Bulgarian version. The web site (http://silverlight.sofiadev.org) will be live after our UG meeting, scheduled for Thursday, Nov 29th. That means that you can start submitting your projects at that point.

The competition will continue by the end of January, 2008. Then we'll have a dedicated jury for selecting the winners. The #1 is going to qualify for the next round - in which he/she will be able to measure his/hers qualities in software design and development with the rest of Europe's finest.

It's about time you start working on that Silverlight project of yours. Visit the competition web after Nov 29th, register, then submit your project and get ready for becomming #1 Silverlight Developer/Designer in Bulgaria.

posted by branimir | 0 Comments

Back to Bulgaria

Hello boys, I'm baaaack.

As March 1st '07 I've got back home. Moving-in toghether with my girlfriend right in the center of Sofia. Kicking it up with a nice project for Tam Tam - the best place I've worked for.

posted by branimir | 0 Comments

Playing with strings (part 2 of n)

Do you know, that there's a build-in check for empty/null strings in .NET 2.0?

So instead of doing this:

 

string strValue = "";

if (null == strValue || strValue.Length <= 0)
{
   //do something
}

You can do this:


string
strValue = "";

if (string.IsNullOrEmpty(strValue))

   //do something
}

Basically the method implementation looks like this:

public static bool IsNullOrEmpty(string value)

   if (value != null
   { 
      return (value.Length == 0); 
   
}

   return true;
}

Happy coding!!!

posted by branimir | 0 Comments

Starting a pet project for SofiaDev.org registration web

I've started a pet project of mine during the holidays, for automating the registration for SofiaDev.org.

For now, the only way for registering is to get in touch with me (usually IM or email) and ask for an account. At the last meeting, a couple of guys, attending the event for the fist time, asked how they can register with the group.

It turned out that there are more people out there that want to get in, and can't do it, since there's no way to tell how you can get to an event, or even get an account for the site.

That's why I've started a simple pet project of mine, aiming at simplify the whole thing.

I've applied for a new project @ codeplex.com, but I'm still waiting for an approval there. I think they have problems with scaling the whole site out - a lot of new projects are getting stared there and just adding HDW is not that simple.

Nikola Kasev will do a code review, once I've something to show (I do, but it's still in our RnD repository, and I can't get him access). I'm also looking for volunteers for testing the registration and provide some feedback. If you're interested, send me an email at branimir _at_ gmail.com.

The requirements I've for now are published here: http://sofiadev.org/Pages/Requirements.aspx

 

posted by branimir | 0 Comments

Running Outlook Web Access on Vista

A colleague of mine had a problem today, sending emails through Outlook Web Access, while the web access URL was in he’s “Trusted sites” in IE 7.0.

A while ago, MS published an article, called Replacing the DHTML Editing Control in Windows Vista and Beyond”.

If you click on the “New” button in Outlook Web Access, running Vista, you won’t be able to edit the body of the message – the window looks like this:

Essentially, the problem relates to a missing ActiveX control in Vista, which will not be a part of any Windows from now on. A quick search into the body of the HTML source of the page, finds a reference to the GUID of the ActiveX control.

It looks like this:

<OBJECT class="MSGBODY" classid="clsid:2D360201-FFF5-11D1-8D03-00A0C959BC0A"

You can find it around line #249.

I’m not aware of any plans by MS, on releasing a patch for Exchange. However, I believe that pretty soon (maybe around or after RTM for Vista) they will act on it.

posted by branimir | 0 Comments

Playing with strings (part 1 of n)

I was writing a method today, one that has to concatenate and format 2 strings. As every other developer on the planet, I’m using System.Text.StringBuilder class when I work with strings (for concatenating and formatting – because that’s what we’re using it for).

There’s also a very well known static method of System.String class called string.Format(string, string).
It’s being used when you want to do a quick and dirty string formatting, without having to initialize a new instance of System.Text.StringBuilder.

So today, I’ve asked myself: What does the string.Format(string, string) use internally?

There are 3 ways of getting an answer on that question.

1. Becoming a MVP and then becoming a member of the Shared Source Initiative program, under a very special NDA. That gives you access to the source of the Windows OS, and .NET as a part of it. After that you can’t discuss what you’ve seen with people outside that program. So writing a blog post like this one is not an option

2. Doing some refactoring with Resharper. It’s one of the best tools out there, when it comes to trying to find out what’s going on under the covers of any .NET assembly that haven’t been obfuscated.

3. Getting the source of SSCLI implementation of .NET. SSCLI is an open source initiative by Microsoft, that represents a good portion of the .NET Framework. Microsoft has released the v2 of SSCLI a couple of months ago, so it’s publicly available. While there is no guarantee that what you’ll see will be the same thing running in .NET 1.0/1.1/2.0, but it’s the closest thing you have. And it has the source of the CLR implementation of SSCLI along with some of the tools you get with .NET Framework SDK – something you can’t get to work with Resharper – most of those are native code.
You can get the SSCLI here: http://www.microsoft.com/downloads/details.aspx?FamilyId=8C09FD61-3F26-4555-AE17-3121B4F51D4D&displaylang=en.

At Tam Tam, we have the SSCLI under our source control database (we use Vault for source control system – it has very comfortable Web UI for accessing your sources).

So I’ve opened the repository were I’ve put the SSCLI into a few weeks ago, and found the implementation of the before mentioned method.

Here it is:

 

public static String Format(String format, Object arg0) {

            return Format(null, format, new Object[] {arg0});

        }

   

        public static String Format(String format, Object arg0, Object arg1) {

            return Format(null, format, new Object[] {arg0, arg1});

        }

   

        public static String Format(String format, Object arg0, Object arg1, Object arg2) {

            return Format(null, format, new Object[] {arg0, arg1, arg2});

        }

 

 

        public static String Format(String format, params Object[] args) {

            return Format(null, format, args);

        }

 

        public static String Format( IFormatProvider provider, String format, params Object[] args) {

            if (format == null || args == null)

                throw new ArgumentNullException((format==null)?"format":"args");

            StringBuilder sb = new StringBuilder(format.Length + args.Length * 8);

            sb.AppendFormat(provider,format,args);

            return sb.ToString();

        }

 

The important one is the last – the others are simply calling it with some default parameters.

It turns out that the method itself uses  System.Text.StringBuilder. So it’s safe to use it, when we have a simple concatenation or formatting and concatenation cases. Like the one I had.

 

posted by branimir | 0 Comments

Running Intel Core Duo

I’ve just got my new Toshiba Portege M400 – my first Intel Core Duo and Tablet PC @ the same time. And it’s great. It came just a couple of days before I went back to Sofia, for DevDays 2006.

However, I think Toshiba has some problems with the preinstalled software they ship. A colleague orf mine has the same (although he’s not a Dev) and he shared with me that he has some major problems with the performance. It turned out (at least for me) that when I run virtual machines, for example, I get much better performance after I’ve uninstalled Toshiba Bluetooth Stack – a sort of a pack of drivers and software for managing and working with Bluetooth devices that came with the preinstalled OS. The bad thing is that so far I haven’t found another way of enabling Bluetooth on my tablet – MS’s drivers that come with XP SP2 doesn’t seem to find the hardware components. And I need those, because I want to be able to use Internet over GPRS (which is pretty cheap in The Netherlands these days – 10 EUR per a month for unlimited access). So I’ll keep searching.

posted by branimir | 0 Comments

Intellisense for MS SQL Server 2000/2005

There’s a limited time free of charge offer by Red Gate Software for their product “SQL Prompt”. Check it out @ http://www.red-gate.com/products/SQL_Prompt/index.htm

posted by branimir | 0 Comments

Generic event-handlers in .NET 2.0

I was writing-up an event handler with custom event arguments, getting ready for defining the event args class along with a delegate for the event definition (as you’re supposed to in .NET 1.1), when I’ve noticed that in VS intellisense is helping me with an advice saying that I can use a generic event argument. Cool !!!

So I’ve decided to take a couple of minutes off and see what’s can I do with .NET 2.0.

In .NET 1.x, we had to do the following:
  1. Define a delegate type that holds the signature for the even type.
  2. Define a custom class that inherits from System.EventArgs.
  3. Define a class that will raise the the event instance
  4. And encapsulate an event of the delegate type in the class from #2.
  5. Attach event handlers for the event
  6. And then consume the event

Here’s a simple event definition compatible with MS.NET 1.1 (and still working in 2.0)

 

using System;

namespace SofiaDev.Events.dn11
{
      public delegate void CustomEventHandler(object sender, CustomEventArgs e);

      /// <summary>
      /// Event Args class. Holds data, specific for the event instance.
      /// </summary>
      public class CustomEventArgs : System.EventArgs
      {
            private DateTime m_dtEventSend;
            private string m_strMessage;
           

            /// <summary>
            /// returns a message send to the mesasge subscriber.
            /// </summary>
            public string Message
            {
                  get { return m_strMessage; }
            }
            /// <summary>
            /// another specific field for the event subscriber
            /// </summary>
            public DateTime DateEventSend
            {
                  get { return m_dtEventSend;  }

            }           

            /// <summary>
            /// Initializes a new instance of the custom event arg instance
            /// </summary>
            public CustomEventArgs(string message, DateTime dateEventSend)
            {
                  m_strMessage = message;
                  m_dtEventSend = dateEventSend;
            }
      }
}

 

So that’s the event args definition and the delegate.
Then we need the class that does the incapsulation and raises the event. 

Like this:

 

using System;
using
System.ComponentModel;
using
System.Threading;
 

namespace SofiaDev.Events.dn11
{
      /// <summary>
      /// Class that raises events of the type we've defined in dn11_Event.cs
      /// </summary>
      public class SomeClassThatRaisesEvent
      {
            /// <summary>
            /// This is the event subscription hook. You should attach you're handler to it. When the moment is right, the class will
            /// call your handler with the appropriate event args data.
            /// </summary>
            public event CustomEventHandler CustomEvent;
           

            /// <summary>
            /// This method actually does the calling. If the event handler queue is not empty, it should call
            /// the delegate, passing the appropriate event arguments.
            /// </summary>
            /// <param name="e"></param>
            protected virtual void OnCustomEvent(CustomEventArgs e)
            {
                  if ( null!=CustomEvent )
                  {
                        CustomEvent(this, e);
                  }
            }
           

            /// <summary>
            /// calls a method that will return in 2 seconds
            /// </summary>
            public void CallEventhandlersIn2Seconds()
            {
                  BackgroundWorker bgw = new BackgroundWorker();
                  bgw.DoWork += new DoWorkEventHandler(bgw_DoWork);
                  bgw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgw_RunWorkerCompleted);
 

                  bgw.RunWorkerAsync();
            }
 

            /// <summary>
            /// Actual work being done here.
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            void bgw_DoWork(object sender, DoWorkEventArgs e)
            {
                  Thread.Sleep(2000);
            }

 
            /// <summary>
            /// we'll call the event handler from here.
            /// </summary>

            void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
            {

                  string strMessage = string.Format("hello from the second thread at {0}", DateTime.Now.ToString("dd-MM-yyyy hh:mm:ss"));
                 

                  //init the custom event args instance with specific data
                  CustomEventArgs args = new CustomEventArgs(strMessage, DateTime.Now);
                 

                  //call our internal method that does the actual call of the events on clients.
                  OnCustomEvent(args);
            }
      }
}

 

In this one, we have a couple of additional methods that will help us demonstrate the event call itself.  Check out the comments for more info.

Then we can use the whole thing. Like this:
 

using System;
using
System.Collections.Generic;
using
System.Text;
using
System.Threading;
using
SofiaDev.Events.dn11;

namespace EventArgs
{
      class Program
      {
            static bool StillWaiting = true;           

            static void Main(string[] args)
            {
                  //init the instance that will we're gonna be waiting on.
                  SomeClassThatRaisesEvent instance = new SomeClassThatRaisesEvent();
 

                  //attach an event handler of our own
                  instance.CustomEvent += new CustomEventHandler(instance_CustomEvent);                 

                  //call method that will call us in a couple of secs (when he's ready
                  instance.CallEventhandlersIn2Seconds(); 

                  Console.WriteLine("about to start waiting");

                 

                  while ( StillWaiting )
                  {
                        Console.Write(".");
                  }

                
                  Console.WriteLine("\n\nExiting!!!");
            }

             static void instance_CustomEvent(object sender, CustomEventArgs e)
            {
                  Console.WriteLine("\nCall returned. ");
                  Console.WriteLine("Message: {0},\ndate: {1}", e.Message, e.DateEventSend.ToString());

 
                  StillWaiting = false;
            }
      }
}

 

The problem here is that when you author an extensive library, it takes a lot of time to do the same code over and over again.

The new thing in .NET 2.0, is the possibility to use a generic delegate (there is one within the .NET BCL already) and use it everywhere. To be able to do that, you only need to define your custom event class holding the data specific to your event. In fact we can use the same class declaration as in the .NET 1.1 example and still be able to use a generic delegate as the event type.

Here’s how the same class will look with a generic event declaration:

 

using System;

namespace SofiaDev.Events
{
      /// <summary>
      /// same class as in the .NET 1.1 example
      /// </summary>
      public class SomeClassThatRaisesEvent
      {
            /// <summary>
            /// Only this time the event handler will have a generic definition
            /// </summary>
            public EventHandler<CustomEventArgs> CustomEvent;

          
            protected void OnCustomEvent(object sender, CustomEventArgs e)
            {
                  if (null != CustomEvent)
                        CustomEvent(this, e);
            }
      }
}

 

An example solution with both ways of doing the event declaration is available as an attachment.



posted by branimir | 0 Comments
Attachment(s): EventArgs.zip

Comparing and Sorting with Generics

I’m working on a project on which I need to sort some custom classes. Today, I’ve decided to play around and find easier and faster way to deal with different sorting scenarios with the use of generics.

I’ve a simple class hierarchy with a root abstract class called DataObject. From there I’ve inherited with a number of implementation classes that are used as a data containers (I’m using nHibernate for accessing the data in my MS SQL database).

I need to be able to sort arrays of instances of my data container classes. Some of them by a property A, and other by property B. Property A and B might have different types (string and int for example), and I don’t want to write a number of IComparer implementations.

So, I wrote that:

using System;
using System.Collections;

namespace SofiaDev.Generic
{
      public abstract class DataObjectSortableBy<T> : DataObject, IComparer where T : IComparable<T>
      {
            protected abstract T SortOnThisField
            {
                  get;
            }

            public virtual int Compare(object o1, object o2)
            {
                  T t1 = ((DataObjectSortableBy<T>)o1).SortOnThisField;
                  T t2 = ((DataObjectSortableBy<T>)o2).SortOnThisField;

                  if (null != t1 && null == t2)
                        return 1;
                  if (null == t1 && null != t2)
                        return -1;
                  if (null == t1 && null == t2)
                        return 0;

                  return t1.CompareTo(t2);
            }           

            public abstract object Empty
            {
                  get;
            }
      }
}

Now I can define base abstract classes for sorting.
Like this:

namespace SofiaDev.Generic
{
      public abstract class DataObjectSortableByString : DataObjectSortableBy<string>
      {

      }

      public abstract class DataObjectSortableByInt : DataObjectSortableBy<int>
      {

      }
}

 

And then inherit from them and oiverride the SortOnThisField method.

.NET RULEZ :)

posted by branimir | 0 Comments

WSE 2.0 and Windows Authentication

I’m currently finishing on a project which uses WSE 2.0 SP3 as a communication platform. At one point I’ve had an interesting problem, which I couldn’t find solution for (at least not according to the specs and WSE documentation). So I’ve decided to share my knowledge on the matter and how I’ve solved it, in case anyone else finds it difficult to deal with a similar situation.

So what’s the problem?

I was implementing a SOAP over SMTP messaging infrastructure for sending XML messages through email, because of the fact that the backend of the application can’t be published on the internet for security reasons. So we’ve done a proof of concept (Paul did that) which was working like a charm.

Then when I took over and started to put the whole thing together, I’ve got a strange problem with a web service published in WSS site, which was called through the Soap over Smtp “component”. The problem was, that Sharepoint needs a windows identity that should be verified by IIS (sharepoint uses IIS for the authentication process). So even if you do a local LogonUser, WSS/SPS won’t be happy because of some strange reason that I couldn’t find. So now I had to make the call on the behalf of a user that has to be authenticated against IIS (so Active Directory or a local Windows account) and then, eventually I was going to be able to do my thing in Sharepoint. That means that along with the message relay though my SoapReciver, I had to send a windows identity. It turned out that this is not an easy thing to do with WSE 2.0 (SP3). Smile [:)]

What did I try?

1. Obtaining the context of the SoapHttpOutputChannel and setting the PreAuthenticate property to true, along with the Credentials to System.Net.CredentialCache.DefaultCredentials (my service that relays the messages is logged on the same machine, so I should have been able to use the credentials).

The “obtaining” part was done in a custom SoapOutputFilter that was called for every message that was send.

That doesn’t work.

It fails with a strange exception, that has been partially documented with ASP.NET 1.1, but doesn’t work with ASP.NET 2.0 as well. How to test it and see that it doesn’t work? Here’s a simple program that’s sending a single message to a very, very simple web service:

try
{
      SoapEnvelope message = new SoapEnvelope();
      message.Context.Addressing.Action = new Action("http://tempuri.org/HelloWorld");

      Uri urlTo = new Uri("http://localhost:7357/WSTest/Service.asmx");
      SoapSender sender = new SoapSender(urlTo);

      message.Body.InnerXml = "<HelloWorld xmlns=\"http://tempuri.org/\" />";
      sender.Send(message);
}
catch ( Exception ex )
{
      Console.WriteLine(ex.Message);
      Console.WriteLine(ex.StackTrace);
}

And here is the filter that’s been called:

public class Output : SoapOutputFilter
{
      public override void ProcessMessage(SoapEnvelope envelope) 
      {
            if ( null!= envelope.Context )
            {
                  ISoapChannel channel = envelope.Context.Channel;
                  SoapHttpOutputChannel httpChannel = channel as SoapHttpOutputChannel;                 

                  if ( null!=httpChannel )
                  {
                        httpChannel.Options.PreAuthenticate = true;
                        httpChannel.Options.Credentials = CredentialCache.DefaultCredentials;
                  }
            }
      }
}

 

And finally, here’s the exception:

The operation has timed-out.
   at System.Net.HttpWebRequest.GetRequestStream()

   at Microsoft.Web.Services2.Messaging.SoapHttpTransport.Send(SoapEnvelope mess

age, EndpointReference destination, SoapHttpChannelOptions options)
   at Microsoft.Web.Services2.Messaging.SoapHttpOutputChannel.Send(SoapEnvelope message)
   at Microsoft.Web.Services2.Messaging.SoapSender.Send(SoapEnvelope envelope)   at ConsoleTest.TheMainClass.Main(String[] args) in c:\documents and settings\branimir\my documents\visual studio projects\consoletest\main.cs:line 29


If you want to test it yourself, download the code and run it. The web service is a ASP.NET 2.0 WS, so you need that installed. Along with WSE 2.0 SP3 for the console app.

2. Obtaining the SoapHttpOutputChannel before sending the message. Doesn’t work as well. The problem here is that sending the message has nothing to do with what protocol will be used for that. You should be able to add or remove protocols though the configuration of the app, so this way you can replace the default Http sender with a custom HttpSoapTransport. That really makes sence. Actually this is how I finally cracked it :) – see #3 for details on this one.

I’ve tried the following to get a reference to the SoapHttpOutputChannel instance:

 

EndpointReference endpoint = new EndpointReference(urlTo);
ISoapTransport transport = SoapHttpTransport.GetTransport(endpoint);
SoapHttpTransport httpTransport = transport as SoapHttpTransport;


if
( null!=httpTransport )
{
      SoapHttpOutputChannel httpOutputChannel = 
            httpTransport.GetOutputChannel(endpoint, SoapChannelCapabilities.None) as SoapHttpOutputChannel;

      
      httpOutputChannel.Options.Credentials = CredentialCache.DefaultCredentials;

      httpOutputChannel.Options.PreAuthenticate = true;
}

3. Replacing the default SoapHttpTransport with a custom implementation that does the authentication by default. It’s not so easy to write that (and test it so you can be sure that it works).
So I’ve decided to decompile what Microsoft did, and customize it.
Then I’ve added a new protocol scheme for using integrated authentication called “http.auth://” and used it when I wanted to make calls that authenticate with Windows Integrated.

Check out the attachments for this post for the complete source code.

Initially I wanted to just change the default options of the default SoapHttpTransoport, but that turned out the be impossible. I kept getting the same exception as in #1.

So I’m guessing that there is a problem with the Options of the protocol (don’t think that they’ve tested it good enough – the options are not getting initialized anyway).

At that point I’ve already decompiled MS’s implementation and I’ve filled in the gaps, so it was actually working. I’ve added a couple of lines of code to  the method that does the actual call and it was ready. It actually worked Smile [:)]. Wohooo - I have a SoapHttpTransport with a Windows Authentication of my own, and it's working Smile [:)].

If you wan to use this one, once you complile the transport, you need to add the following lines to your config file (the wse2 section should be there already):

  <microsoft.web.services2>

    <messaging>

            <transports>

                  <add scheme="http.auth" type="SofiaDev.Wse.SoapHttpTransport, SofiaDev.Wse" />

            </transports>

    </messaging>

  </microsoft.web.services2>

Then, use http:auth:// as a transport scheme instead of http. This way WSE knows which transport  protocol implementation to instantiate, based on what it finds at the config file.

posted by branimir | 0 Comments
Attachment(s): WSE Files.zip

Accessing Active Directory without specifying LDAP path

I’m writing up a class that wraps all of the functionality I need for accessing AD in one place.
So how do I get the LDAP path to the domain controller?

It’s easy – just get it from AD itself. Here’s the code:

using (DirectoryEntry rootDse = (PreAuthenticate ? new DirectoryEntry("LDAP://rootDSE", Username, Password) : new DirectoryEntry("LDAP://rootDSE")))

{

      if (null == rootDse)

      {

            throw new ApplicationException("Can't connect to LDAP://rootDSE. Please make sure that the computer on which you're trying to run the component is a member of the domain and is currently connected to at least one DC.");

      }

 

      TypedPropertyValueCollection<string> prRootDse = new TypedPropertyValueCollection<string>(rootDse, "defaultNamingContext");

      TypedPropertyValueCollection<string> prDomainName = new TypedPropertyValueCollection<string>(rootDse, "dnsHostName");

 

      RootDSE = prRootDse.Value;

      DomainName = prDomainName.Value;   

}

 

Then you can get the LDAP Path like this: