Skytec

warning: Creating default object from empty value in /home/pulsar/webroot/htdocs/modules/taxonomy/taxonomy.pages.inc on line 33.

OpenHUG Meeting

_pulsar_: OpenHUG Meeting, wir freuen uns auf zahlreiches Erscheinen! http://linkd.in/drEaBF || http://bit.ly/aERlUU || http://bit.ly/bNGGCt - _pulsar_: OpenHUG Meeting, wir freuen uns auf zahlreiches Erscheinen! http://linkd.in/drEaBF || http://bit.ly/aERlUU || http://bit.ly/bNGGCt [/me Twitters]

Sharepoint 2007 Variations Woes

While fighting some more problems with Sharepoint 2007 Variations "System" I had to write this comment in my code today:

  1. // note: there is a bug in Sharepoint 2007 when using ", " within a page name - "foo, bar.aspx" for instance.
  2. // note: This will render the relationship list entry useless. A healthy object id attribute in a
  3. // note: relationship list's entry looks like this:
  4. // note: ows_ObjectID='http://mucskysp04:4711/DE/Seiten/Seite mit Sönderzeichen.aspx, /DE/Seiten/Seite mit Sönderzeichen.aspx'
  5. // note: once "broken" using the naming-"exploit", the relationship will be represented as:
  6. // note: ows_ObjectID='http://mucskysp04:4711/DE/Seiten/variationsseite, mitkommaundleerzeichen.aspx'
  7. // note: note the missing relative path. There is no reason to work around this bug in this tool since the original
  8. // note: entry in Sharepoint won't be functional anyway (no entries will be shown in the variations dropdown)

Cry? Laugh? I think I'll stick with pulling my hair.

One more reason why I love local initializers

  1. public static IDictionary<RequestTypeEnum, RequestGroupEnum>
  2. RequestTypeToGroup= new Dictionary<RequestTypeEnum, RequestGroupEnum>()
  3. {
  4. {RequestTypeEnum.RegisterAccount, RequestGroupEnum.Account},
  5. {RequestTypeEnum.UnregisterAccount, RequestGroupEnum.Account},
  6. {RequestTypeEnum.RegisterInetAccess, RequestGroupEnum.InetAccess},
  7. {RequestTypeEnum.UnregisterInetAccess, RequestGroupEnum.InetAccess},
  8. {RequestTypeEnum.RegisterMailbox, RequestGroupEnum.Mailbox},
  9. {RequestTypeEnum.UnregisterMailbox, RequestGroupEnum.Mailbox},
  10. {RequestTypeEnum.RegisterRLA, RequestGroupEnum.RLA},
  11. {RequestTypeEnum.UnregisterRLA, RequestGroupEnum.RLA}
  12. };

Unexpected Consequences


Ooops! That was quite unexpected

Accessing Arrays in .NET/c# via Reflection

Yesterday I was implementing a generic serializer (for logging purposes). While there is a good number of XML serializers available for .NET - none of them was meant to be used for only the purpose of reading. That means, I would not need deserialization but only some nice human readable output.

Anyway, thats not the point here. What took me about an hour to figure out is how to handle arrays (of natives) via reflection. I kinda feel stupid, but let me show you what i tired:

  1. Object propertyValue = prop.GetValue(o, null);
  2. if (propertyValue != null &amp;&amp; propertyValue.GetType().IsArray)
  3. {
  4. //if you need the type, here is how we get it, it's not used
  5. //in this example.
  6. Type arrayType = propertyValue.GetType().GetElementType();
  7. object[] arr = propertyValue as object[];
  8. for (int i = 0; i &lt; arr.Length; i++)
  9. {
  10. // serialization logic goes here
  11. }
  12. }
  13. ...

While this might work perfectly for arrays of "real" objects such as string[] - it will fail when your array is composed of native objects such as long[]. The cast to object[] will get you a nice null reference. Yummy.

After that I've been looking for Array.ForEach() which was pretty interesting, but did not really help due to it's generic nature. The solution was much simpler in the end, it just did not cross my mind to cast the propertyValue to Array - sometimes .NET can be pretty mysterious in terms of Autoboxing. Here is how it should be done:

  1. Object propertyValue = prop.GetValue(o, null);
  2. if (propertyValue != null &amp;&amp; propertyValue.GetType().IsArray)
  3. {
  4. Array array = propertyValue as Array;
  5. foreach (var arrElement in array)
  6. {
  7. // serialization logic goes here
  8. }
  9. }
  10. ...

Straight forward, simple - makes me feel stupid.

Why I Love Local Initializers...

  1. layoutTable.Rows.Add
  2. (
  3. ControlUtils.CreateRow
  4. (
  5. EmployeeFieldLabels.ExternalCompanyName,
  6. new ExtCompanyPickerControl(CreateChildID(&quot;ExternalCompanyName&quot;))
  7. {
  8. Customizer = new ExtCompanyCustomizer(MedaSession),
  9. AllowMultipleSelection = false,
  10. RenderListHeader = false,
  11. CountryProviderId = locationPickerControl.ID,
  12. CountryProviderProperty = &quot;SelectedCountryIsoCode&quot;;
  13. },
  14. false,
  15. EmployeeFieldTooltips.ExternalCompanyName,
  16. Page,
  17. CreateChildID(&quot;ExternalCompanyLabel&quot;),
  18. (
  19. externalCompanyValidator = new CompareValidator
  20. {
  21. ControlToValidate = CreateChildID(&quot;ExternalCompanyName&quot;),
  22. Operator = ValidationCompareOperator.Equal,
  23. Type = ValidationDataType.Integer,
  24. ValueToCompare = &quot;1&quot;,
  25. EnableClientScript = false,
  26. Display = ValidatorDisplay.Dynamic,
  27. ErrorMessage = string.Format(EmployeeManagerControlRes.ErrorValueRequired, EmployeeFieldLabels.ExternalCompanyName)
  28. }
  29. )
  30. )
  31. );

Check them out! http://msdn.microsoft.com/en-us/library/bb384062.aspx

User Management with Active Directory

The last 2 days I've been working on a concept paper for a project. One aspect covers user management using an active directory.

At the first glance, everything looks easy. One would think AD is just another LDAP server - no worries here. It turns out, AD has a lot of hidden constraints and expect you do things a certain way. For instance, if you want to add a user to a specific group, you are not going to update the user's "memberOf" LDAP attribute. This is read only; you will need to add that user to the group LDAP node. This is just one and quite straight forward example how AD can be a pain in the arse if you have no idea about the internals.

Luckily the guys over at http://en.csharp-online.net/ have assembled a damn good article about all daily tasks you will encounter if you are going to automate some user administration tasks using the Active Directory as your backend. Head over here: http://en.csharp-online.net/User_Management_with_Active_Directory%E2%80%...

I have also stumbled across a wrapper library which abstracts all the LDAP / DirectoryEntry specific calls and focuses on user- and group-centric API: http://www.dotnetactivedirectory.com/ - I have no idea yet if this one is good or not, I guess I will find out soon since I plan to cut down the development times by 2 Days and use this API instead.

update
After looking into the free (lite) version of .NET Active Directory wrapper, I am not so sure about purchasing a license anymore. 400 or 1000 bucks a a pretty hefty price tag for a software not being in development anymore (as it seems, last update 2007) and consisting only from one pseudo class. It can hanlde only one AD connection due to static (!) fields for login and password. Furthermore it does not persist a connection to the AD but re-creates a new Directry Entry with each operation - now do some mass operations on say... 5k users by assigning them to a AD groups or something.  I suppose it will be still more expensive for the project for me to code the mini-api, but after considering those facts, I might be better off. Especially when it comes to multiple AD servers and support requests I might get for this particular module. Geez! Where do ppl learn coding!? I guess good marketing and price tags not reflecting the code quality can still compensate it

Sharepoint STSADM Extensions which will save your life!

If you are into Sharepoint-Development you will appreciate the STSADM Custom Extensions made by Gary Lapointe: http://stsadm.blogspot.com/2007/08/stsadm-commands_09.html

In our case they saved us a lot of troubles we had when moving a Sharepoint Site Collection to a new server while preserving the Variations which have been created before.

One of the commands we have been toying with was "gl-fixvariationrelationships". Since the sources to all of these extensions are available to download for free, I could even get this one working for a Variation root other than "/" by modifying the sources a tiny bit. If you run into the same situation feel free to grab my Version of the FixVariationRelationships Class over here or here (can't get drupal to ignore HTML validation for Geshi-Nodes editing)

 

Export an Outlook Folder to a Filesystem-Folder

Here is a small tool I wrote (well, rather hacked) which might come handy for some of you. Sourcecode is included so you might want to make it even fancier and do whatever comes to your mind with it.

OutlookFolderExporter 0.3 Beta

What does it do?
Export an Outlook folder containing E-Mail Messages to a physical filesystem folder. Message by message.

Requirements?

  • Outlook 2007
  • NET 2.0 Framework
  • Visual Studio 2007 (optional)


Why?
Someone asked me if I knew a tool or a way to do this. From what I understand he was about to share such messages using a Windows-Share. I know there are better ways to achieve this, provided you are using an Exchange-Server - but for some reason it did not work out for them.

Limitations?
Plenty, this is a really quick hack:

  • Supports only mail messages (no contacts, appointments etc)
  • Can export only one folder (no recursion) at a time
  • Developed and tested against Outlook 2007 (12.0) - no idea if this will even work for previous versions of Outlook. I suppose not.
  • Won't cook any coffee yet.
Obligatory Screenshot?


Usage?
You will need to know the path to your Outlook folder you would like to have exported. The root folder presumed by this applicationis the root folder of your default Outlook acccount. Beneath it you should have folders like Inbox, Contacts etc. To export all messages of the default inbox folder one would use "/Posteingang/" in the German version of Outlook. Must be something like "Inbox" for English Users I think. Another example would be "/Sent-Items/Archive" which would export the Archive folder which you have might created in the Sent-Items parent Folder.

License?
Public domain, check the "License.txt" in the sources package for further details.

History

0.3 Beta: 2008-07-02 20:40 0.3

  • Inbox->first folder restriction removed - You can export any account folder now.
  • Target directory might be created on demand.

0.2 Alpha 2008-07-02 14:00 - 0.2

  • Added an installer (otherwise we are missing some interop-libraries)
  • Repackaged, Sources will be also installed.

Download?

Debug, Log and Tail on Steroids

Sometimes I do really wonder why some great tools remain silent and hidden from the public for such a long time. The guys over at codeproject featured an article about the "TraceTool". Describing it with "yet another log viewer" won't do any justice. Just head over to the article and glance over it. It's able to interface with the most common logging frameworks such as .NET's native, log4net/log4j, NT System Evenlog and plain files.

I must admit I did not try it yet. Will do next week when I'm back in the office - I don't really feel like I want to be coding this weekend. But just reading the specs and howtos on the codeproject site blew my mind. Looks like a jewel, smells like a jewel... might be one!

Syndicate content