My EnumHelper class

<!–

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: Consolas, “Courier New”, Courier, Monospace;
background-color: #ffffff;
/*white-space: pre;*/
}

.csharpcode pre { margin: 0em; }

.csharpcode .rem { color: #008000; }

.csharpcode .kwrd { color: #0000ff; }

.csharpcode .str { color: #006080; }

.csharpcode .op { color: #0000c0; }

.csharpcode .preproc { color: #cc6633; }

.csharpcode .asp { background-color: #ffff00; }

.csharpcode .html { color: #800000; }

.csharpcode .attr { color: #ff0000; }

.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}

.csharpcode .lnum { color: #606060; }

Previously I’ve posted a few Helper Classes . This post describes my EnumHelper class. The class uses other helper classes, in particular CollectionsHelper
Related links: Overriding ToString on enum,
Mapping Text to Enum entries . Enum Helper Class Using Generics ,
My new little friend, Enum<T>,
Making C# enums more usable – the Parse() method
https://connect.microsoft.com/VisualStudio/feedback/Workaround.aspx?FeedbackID=98356
  
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.VisualBasic;

public class EnumHelper
{
// The code below does not have full runtime data checks (we can not require the generic parameter be an enum at compile time), but should save a little code.    //note in C++ you can say where T : enum http://weblogs.asp.net/kennykerr/archive/2005/05/16/The-Case-of-the-Missing-Generic-_2800_Parse-Method_2900_.aspx
  
//example of VB call EnumHelper.Parse(Of MenuMode))(sMode)
       public static TEnum Parse<TEnum>(string text) where TEnum : struct
        {
            string sEnum = text;
            ThrowExceptionIfNotEnum<TEnum>();
            if (!Enum.IsDefined(typeof(TEnum), text))
            { // Unfrortunately IsDefined is case sensitive //See also https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=145431
                sEnum = text.ToLower();
                if (!Enum.IsDefined(typeof(TEnum), sEnum))
                {
                    sEnum = text.ToUpper();
                    if (!Enum.IsDefined(typeof(TEnum), sEnum))
                    {
//NOTE that numeric value, passed as string is not recognized by IsDefined, but accepted by Parse. 
//  Debug.Assert(false, String.Format("The value passed ("{0}") is not a defined within {1}.", text, typeof(TEnum).ToString()));
                    }
                }
            }
            TEnum t = (TEnum)Enum.Parse(typeof(TEnum), text, true);
            return t;
        }
        public static List<T> ConvertToList<T>()
        {//from http://rodenbaugh.net/files/folders/18/download.aspx
            List<T> values = new List<T>();
            Array array = Enum.GetValues(typeof(T));
            foreach (T item in array)
                values.Add(item);
 
            return values;
        }
        //from http://rodenbaugh.net/files/folders/18/download.aspx
        public static string[] GetNames<T>()
        {
            return Enum.GetNames(typeof(T));
        }
        //from http://rodenbaugh.net/files/folders/18/download.aspx
        ///<typeparam name="U">usually int</typeparam>
        public static List<U> GetValues<T, U>()
        {
            List<U> values = new List<U>();
            Array array = Enum.GetValues(typeof(T));
            foreach (U item in array)
                values.Add(item);
            return values;
        }
        ///<typeparam name="ValueType">usually int</typeparam>
        public static bool AreValuesUnique<EnumType, ValueType>()
        {
            List<ValueType> valuesList = GetValues<EnumType, ValueType>();
            return CollectionsHelper.AreValuesUnique<ValueType>(valuesList);
        }
        ///<typeparam name=”ValueType”>usually int</typeparam>
        public static List<ValueType> FindDuplicates<EnumType, ValueType>()
        {
            List<ValueType> valuesList = GetValues<EnumType, ValueType>();
            return CollectionsHelper.FindDuplicates<ValueType>(valuesList);
        }
 
        // use Enum Description attribute to specify description
        // http://www.codeproject.com/csharp/enumwithdescription.asp
        //Also consider use ResourceManager see http://www.codeproject.com/csharp/LocalizingEnums.asp?print=true
        public static string GetDescription(Enum value)
        {
            FieldInfo fi = value.GetType().GetField(value.ToString());
            DescriptionAttribute[] attributes =
                  (DescriptionAttribute[])fi.GetCustomAttributes(
                  typeof(DescriptionAttribute), false);
            return (attributes.Length > 0) ? attributes[0].Description : value.ToString();
        }
 
        // http://rodenbaugh.net/files/folders/18/download.aspx has generic class Enum<T> with a lot of interesting methods.
        // examples of use see http://rodenbaugh.net/archive/2006/11/01/Enum-Helper-Class-Using-Generics.aspx
        //TODO consider to use if required
        #region “Chars to Enums”
        //Not used in TSA at the moment
        public static char ValueAsChar<TEnum>(TEnum value) where TEnum : struct //ideally enum
        {
            ThrowExceptionIfNotEnum<TEnum>();
            char ch = Convert.ToChar(Convert.ToInt16(value));// Strings.Chr Convert.ToChar(AppType);
            return ch;
        }
        public static TEnum CharAsciiAsEnum<TEnum>(string schValue, TEnum enDefault) where TEnum : struct //ideally enum
        {
            ThrowExceptionIfNotEnum<TEnum>();
            TEnum enum1 = enDefault;
            if ((schValue != null) && (schValue.Length == 1))
            {
                enum1 = CharAsciiAsEnum<TEnum>(schValue[0], enDefault);
            }
            return enum1;
        }
 
 
        public static TEnum CharAsciiAsEnum<TEnum>(char chValue, TEnum enDefault) where TEnum : struct //ideally enum
        {
            ThrowExceptionIfNotEnum<TEnum>();
            TEnum enum1 = enDefault;
            short num1 = (short)Microsoft.VisualBasic.Strings.Asc(chValue);
            if (Enum.IsDefined(typeof(TEnum), num1))
            {
                enum1 = (TEnum)Enum.ToObject(typeof(TEnum), num1);
            }
            return enum1;
        }
        #endregion //”Chars to Enums”
        #region private methods
 
        private static void ThrowExceptionIfNotEnum<TEnum>()
        {
            if (!typeof(TEnum).IsEnum)
            {
                throw new ArgumentException(typeof(TEnum).ToString() + ” is not an Enum”);
            }
        }
        #endregion //private methods
 
}
    //The function is not required enum.ToString() does the same with “,” separator
    //public static string ValueToNamesString<T>(T enValue, string sDelimeter) where T : struct
    //{
    //    if (!typeof(T).IsEnum)
    //    {
    //        throw new ArgumentException(typeof(T).ToString() + ” is not an Enum”);
    //    }
    //    string sRet;
    //    StringBuilder sb = new StringBuilder();
    //    foreach (T flag in Enum.GetValues(typeof(T)))
    //    {
    //       // T flag = (T)i;
    //        sRet = FlagToStringIfOn<T>(enValue, flag);
    //        if (!String.IsNullOrEmpty(sRet))
    //        {
    //            sb.Append(sRet);
    //            sb.Append(sDelimeter);
    //        }
    //    }
    //    sRet = StringHelper.TrimEnd(sb.ToString(), sDelimeter);
    //    return sRet;
    //}
    ////TODO make generic method
    //public static string FlagToStringIfOn<T>(T value, T flag) where T : struct
    //{
    //    if (!typeof(T).IsEnum)
    //    {
    //        throw new ArgumentException(typeof(T).ToString() + ” is not an Enum”);
    //    }
    //    string sRet = “”;
    //    TODO convert to ulong to support & operator
    //    bool bOn = ((value & flag) != 0);
    //    if (bOn)
    //    {
    //        sRet = Enum.GetName(typeof(T), flag);
    //    }
    //    //TODO see https://secure.codeproject.com/csharp/masksandflags.asp
    //    return sRet;
    //}

 

Using SubText for blogging in geekswithblogs.net

Recently I’ve  noticed,that a format of my blog has been changed.

It is good that Geekswithblogs.net moved to the modern version, but why the owners didn’t send a warning/notice e-mail to their users?

It is not easy to find satisfactory skin. In an old version I preferred gertrude-blue.css, because it showed content on the left side, making it printer-friendly.  Subtext Default Skins has previews for some skins, but I had to experiment myself by changing skin and view results.

 After the change to SubText my default skin was AnotherEON001, that has Print option (it is good), but doesn’t highlight links well and is quite narrow – I prefer to have width=100% of the browser window).

I’ve tried a few other skins and decided that NAKED is acceptable(also slightly messy),but now I’ve noticed that feedback comments box  is too small and e-mail box  doesn’t show important note “never displayed”.
I’ve experimented with others skins and found a few issues:

 KeyWest looks quite nice, but “links hover” hides the text.

Pyio-has menu and ads on right, but still too narrow.

A few skins keep menu and ads at the top or even at the bottom, which looks very odd(I don’t mind if ads will be at the bottom, butI want to have menu on the right)

I like Cogitation, but again:”Could menu be moved to the right side of the page? ” and have Print button visible.
And if categories will be shown (as in naked), the skin will be perfect.
I will ask support@geekswithblogs.com if they can create thenew skin.

Also I’ve noticed couple things:

1. “Home” lists the posts in order by the time of last modification,,not by the time of creation.
So if I would update some old post , it will be shown first on the home page. I prefer to see articles in the creation order.

2. Statistics summary shows only new Comments as comments and all old comments as Trackbacks 
(e.g.my blog has only 4 comments, which is wrong)

Actually it is amaizing,that I’ve read Phil Haack‘s blog quite often and found his posts very useful, and now I am using his product.

UPDATE:
I noticed one more feature that exist in Naked and missed in most other skins:Edit icon to edit the post. Edit icon  is shown on HomePage, but not on individual post view.

And other bugs/issues I’ve found with the Subtext.
1. E-mail box in feedback comments is now mandatory field. Jeff Julian answed that it is done against spam. But for spammers it is easy to supply bla@bla.bla.com. And some people want to leave a comment, but do not want to disclose their e-mail address. Personally I prefer to leave my blog contact instead of my e-mail address.

2. I am unable to remove comment from Feedback list of my post.  I see Remove Comment 112139 on the page. When I click the link, confirmation alert appears. I answer ‘Yes’ to delete the comment, but nothing happened. It seems the same bug, as it was in Text.
I hoped that I would be able to delete it from Admin Feedback page,but the comments are not in order and it is hard to find the comment that I want to delete. In Text comments on Admin Feedback page were ordered by Date descending which was convinient.

Another UPDATE: I’ve noticed  today, that my Admin/Feedback.aspx  shows the same records regardless of the page number selected (comments from 3/16/07 3:35A to 3/9/07 2:08A).
Also these comments are not the latest.

If I select “Show Only Comments ” or “Show Only PingTrack ” it shows different records,but also they stay the same regardless of page number selected.

I am not sure is it a bug on geekswithblogs.net or in SubText?

Skin UPDATE:I’ve used Cogitation for a few months, but recently found(thanks to Tim Hibbard‘s blog) that Piyo has option to switch from Fixed to Elastic layout. So now I am using Piyo skin.

.Net remoting error “The input stream is not a valid binary format.”

I have a .Net remoting application, that often reports System.Runtime.Serialization.SerializationException “The input stream is not a valid binary format. The starting contents (in bytes) are: xx-xx-xx …”

There area few threads  about this error(e.g .Re: Error passing a large variable as a parameter to a remote method  and Remoting / Serialization problem trying to Migrate to .NET 2.0 )

As it is correctly noted in the posts,  IIS sends back an error message as plain text that the binary formatter doesn’t know how to handle.

In other words, unhandled exception on remoting server causes  (De)SerializationException on the client.

As an example, when I’ve made a mistake in web.config on remoting server, IIS sent the error to the client, but client just show hexadecimal starting content.

 If the content would be shown as text as well, it will be easy to recognize the problem. 

The good policy will be not allow to throw exception through remoting server boundary and catch them,log and return some indicator (e.g. null,false, exception as a parameter etc) to client.  Unfortunately someproblemslike invalid web.config willbe reported before your code (with try/catch) will be invoked.

I am using A custom channel sink to fix the HttpChannel/BinaryFormatter/ASP.NET host bug and it helps.