About the author

Miron Abramson
Me
Software Engineer, Senior Developer at Rima, and .NET addicted for long time.

Recent comments

Authors

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2008

Creative Commons License

Sorting a collection using Linq and 'SortExpression' string

Already happened to you that you had a collection of object from type 'X' with some properties, and you had to sort it one time by property 'ID', and another time by property 'Name' ? You wished that you can sort it by just using a 'Sort Expression' ? If still not, I'm sure this moment will arrive sooner or later. Let me save you some time and an headache.

This is how it can be done: 

 public static IEnumerable<T> Sort<T>(this IEnumerable<T> source, string sortExpression)
{
    string[] sortParts = sortExpression.Split(' ');
    var param = Expression.Parameter(typeof(T), string.Empty);
    try
    {
        var property = Expression.Property(param, sortParts[0]);
        var sortLambda = Expression.Lambda<Func<T, object>>(Expression.Convert(property, typeof(object)), param);

        if (sortParts.Length > 1 && sortParts[1].Equals("desc", StringComparison.OrdinalIgnoreCase))
        {
            return source.AsQueryable<T>().OrderByDescending<T, object>(sortLambda);
        }
        return source.AsQueryable<T>().OrderBy<T, object>(sortLambda);
    }
    catch (ArgumentException)
    {
        return source;
    }
}

Just drop it in a static class, and you will be able to sort any collection that implement the interface IEnumerable.

Lets say you have a class 'User':

public class User
{
    public int ID { get; set; }
    public string Name { get; set; }
}

and a List<User> collection: users. You can sort it however you want:

IEnumerable<User> sortedUsersIEnumerable = users.Sort<User>("ID desc"); 

Or

List<User> sortedUsersList = users.Sort<User>("Name").ToList();

I really think this extension should be 'built-in' part of the 'Linq'. 

Extensions.cs (1.08 kb)

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: ASP.NET | C# | Server side
Posted by Miron on Wednesday, May 07, 2008 1:59 PM
Permalink | Comments (1) | Post RSSRSS comment feed

Some basic but useful C# methods implemented in JavaScript

While I was working on a full Ajax interface based on pure ajax calls and not on any framework,  I implemented some basic and simple methods that we use all the time in the server code, and just not exist in javascript. It's not big deal, but since I wrote them, I use them all the time.

Even it is very simple, I decided to share it here. Hope it will same other coders few minutes:

Cache object:

//
//  Cach object implementation
//
var Cache = new function()
{
    var _cache = new Array();
    this.Insert = function ( key, value ){
        _cache[key] = value;
        }
    this.Get = function ( key ){
        return _cache[key];
        }
    this.Contains = function ( key ){
        if( !_cache[key] || _cache[key] == null ) return false;
        else return true;
        }
};

The use of the cache is as simple as it is in the server side, and it is realy useful to save some calls to the server:

 Cache.Insert("myKey","MyValue");
 if( Cache.Contains("myKey") ) alert( "Yeee the value of my key is in the cache:" + Cache.Get("myKey") );  

String.Format(string,params)  &  String.IsNullOrEmpty(string) :

//
// String.Format implementation
//
String.Format = function(format,args){
    var result = format;
    for(var i = 1 ; i < arguments.length ; i++) {
        result = result.replace(new RegExp( '\\{' + (i-1) + '\\}', 'g' ),arguments[i]);
    }
    return result;
}

//
// String.IsNullOrEmpty implementation
//
String.IsNullOrEmpty = function(value){
    if(value){
        if( typeof( value ) == 'string' ){
             if( value.length > 0 )
                return false;
        }
       if( value != null )
           return false;
    }
    return true;
}

Again, the use is the same as server side:

alert( String.Format("Hello {0}. Yes, hello {0} again. My name is {1}","world","Miron") );
if( String.IsNullOrEmpty('') ) alert('Empty string');

StartsWith(string suffix,bool ignoreCase)EndsWith(string suffix,bool ignoreCase)  and Trim() :

//
// string.StartWith implementation
//
String.prototype.StartsWith = function(prefix,ignoreCase) {
    if( !prefix ) return false;
    if( prefix.length > this.length ) return false;
    if( ignoreCase ) {
        if( ignoreCase == true ) {
            return (this.substr(0, prefix.length).toUpperCase() == prefix.toUpperCase());
        }
    }
    return (this.substr(0, prefix.length) === prefix);
}

 //
// string.EndsWith implementation
//
String.prototype.EndsWith = function(suffix,ignoreCase) {
    if( !suffix ) return false;
    if( suffix.length > this.length ) return false;
    if( ignoreCase ) {
        if( ignoreCase == true ) {
            return (this.substr(this.length - suffix.length).toUpperCase() == suffix.toUpperCase());
        }
    }
    return (this.substr(this.length - suffix.length) === suffix);
}

 //
// string.Trim implementation
//
String.prototype.Trim = function() {
    return this.replace(/^\s+|\s+$/g, '');
}

The last three are working on an istance of a string:

var test = "Hello Words ";
test = test.Trim();
var end = test.EndsWith("ds",true);
var begin = test.BeginsWith("rr",false);

All the code can be downloaded here: 

Utils.js (1.94 kb)

Currently rated 4.5 by 2 people

  • Currently 4.5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: Client side
Posted by Miron on Sunday, May 04, 2008 4:43 PM
Permalink | Comments (0) | Post RSSRSS comment feed

What's going on...

It's around 3 weeks I haven't write anything in my blog. Actually I have some nice things in my mind I want to post about, but I really run out of time.

I am going to leave my current job, and going to work in a new company CapitalIQ. I'm really looking forward for this change. CapitalIQ is a really big company, and I'm going to face new challenges.

Now, the last project I'm working on is a really nice and useful Anti-Spam filter based on Paul Graham's Naive Bayesian Spam Filter algorithm. I Implemented the improved algorithm and added some nice features such 'white/black' lists 'phishing/scam' detecting and made it 'self learning' system that you can actually train it, and it will be improved every time you train it. The results are very very impressive. after some days of learning, from 1014 spams emails and 50 real emails in a weekend, the system detected 1008 spams as spam, and all the real emails as real. I think it could be very useful system, and I'm thinking of uploading it into Codeplex as an open source project.

I have some more nice things to post about, but I have too much things to do and think about, so I will wait for more 'relax time' to post it. I hope all the new changes will be ok and without any problems, and I hope I will have the time to post new and nice things soon.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted by Miron on Sunday, April 20, 2008 9:34 AM
Permalink | Comments (0) | Post RSSRSS comment feed

Uniform Distribution algorithm in C#

Background
Where I work, one of the serviced we give to our clients is Medical articles.With the time, we have tones of articles. Millions. All PDF files, and all are in the same folder.

The Problem
It became impossible to open the folder with Windows explorer, trying to search, copy or move files. I had to find a way to reorder it, and divide it into 1000 folders that every folder will have around the same number of files, and when a request for a specific file will come, I will be able to know in witch folder it is.

The Solution 
I contacted my brother Ari (his site is outdated) for help. He have PhD from the "Electrical Engineering department" at the Technion institute.  He is the smartest guy I have known. So, that is his Algorithm, I just implemented it in C#. It's not too complicate, but it does the job perfect.

The algorithm gets a string and maps it into the set 0-999 (or any given range) with uniform distribution.

/// <summary>
/// Get the position in the range of the specified string
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public int GetPosition(string input)
{
    if (string.IsNullOrEmpty(input))
    {
        return 0;
    }

    input = hasher.ComputeHash(input).Replace("-",string.Empty);
    double Sum = 0.0;
    int Aj;
    double Tj;
    double Pj;

    for (int j = 0; j < input.Length; j++)
    {
        Aj = (int)input[j];
        Tj = (Math.PI * (1 + j%5) / 2);
        Pj = Math.Pow(Aj,Tj);
        Sum += Math.Round((Math.Ceiling(Pj) - Pj) * Range) * Tj;
    }
    return ((int)(Sum % Range)) + LowerValue;
}

To use it, just create an object from type Mapper, and call the 'GetPosition' method for any needed string:

Mapper aMap = new Mapper(RANGE);
int position = aMap .GetPosition(input)); 

The Results 

I run the algorithm few times with random strings 10 chars long and map them into some ranges of 'folders'. Here are the results:

1,000,000 random strings into range of 1000: the folder with the maximum # of files contained 1156 files, and the minimum  contained 886 files.
1,000,000 random strings into range of 100: the folder with the maximum # of files contained 10,699 files, and the minimum  contained 8800 files.
1,000,000 random strings into range of 10: the folder with the maximum # of files contained 106,873 files, and the minimum  contained 98,747 files.

Very nice results. Maybe not perfect, but certainly good enough for this kind of purpose!

Special thanks to my brother Ari for his help.

Source code:

AriMap.zip (2.34 kb)

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: C#
Posted by Miron on Wednesday, April 02, 2008 8:58 AM
Permalink | Comments (0) | Post RSSRSS comment feed

Extensions can make us free from testing against null

The concept of the Extensions in the last frameworks is great. They are extremely easy to write and use, give us infinit options to add needed methods we just wished to have in the framework,  and the thing that most catched my eyes is the fact that the extensions are "attached" to an instance of an object, but can be excute with a 'null' object. It is kind of weird.

Excuting the following code will thow an exception (of course):

string s;
s = null;
s = s.Replace("bla", "alb");

But, if we add the following extension:

public static string EReplace(this string s, string oldValue, string newValue,
    bool ignoreCase)
{
    if (s == null)
        return s;

    if (ignoreCase)
    {
         return Regex.Replace(s, oldValue, newValue, RegexOptions.IgnoreCase);
    }
    return s.Replace(oldValue, newValue);

 and try to excute the code:

string s;
s = null;
s = s.EReplace("bla", "alb",true);

the code will run without any exception.

Conclusion:

Using extensions and validate input, will make us free from testing against null any object before excuting a method, and this way, avoid errors that can be throw exceptions on runtime environment.

Currently rated 4.0 by 1 people

  • Currently 4/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: C#
Posted by Miron on Saturday, March 22, 2008 5:32 AM
Permalink | Comments (0) | Post RSSRSS comment feed

Really quick "Downloads" page

I guess it's the same for all of us. We are the 'computers guy' of the family. When anyone of the close/far family/friends have a problem with the  computer, or need any software - the first call he do, is for us. The 'computers guy'. The technical part is a little problematic, but the 'Do you have an Anti-Virus' for me? 'With what application I can open RAR files?' is the easy part.

Since I have an hosting account, I just created a folder, droped in it this Default.aspx (1.33 kb) I did, droped in it all the (legal) software I have, and when somebody ask me for an application, I just give him the link for that folder. From time to time, when I have a new app, I just upload it to this folder. No need to change any code. The Default.aspx will list it by itself.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:
Categories: ASP.NET | General
Posted by Miron on Tuesday, March 18, 2008 1:46 PM
Permalink | Comments (0) | Post RSSRSS comment feed

Another version for the missing method: Enum.TryParse (in C#)

The 'TryParse' methods for all types are very useful and I'm using them all the time. It's very surprising that Microsoft didn't include in the Framework a method that can be very useful: Enum.TryParse. A lot of coders find themself writing from time to time  'parsing' methods for their enums. Something like that:

public enum ImageType
{
    Jpg,
    Gif,
    Png
}

public static ImageType ParseImagetype(string typeName)
{
    typeName = typeName.ToLower();
    switch (typeName)
    {
        case "Gif":
            return ImageType.Gif;
        case "png":
            return ImageType.Png;
        default:
        case "jpg":
            return ImageType.Jpg;
    }
}...

 Thats work fine, but you need to write such 'parsing' method for each enum you have.  The Enum class have it's own 'parsing' method (that luckly have 'IgnoreCase' flag), but not a TryParse method. The commonly fix around is to put the Enum.Parse method inside Try & Catch, what is, of cource, give bad performance in case of failure. The Enum class have also a method 'IsDefined' that return an indication if a value is exists in the enum. unfortunately, this method doesn't have an  'IgnoreCase' flag.

So, trying to put all this 'knowledge' together, I wrote my own generic version for 'Enum.TryParse' method that is also ignore case and not using try & catch:

public static bool EnumTryParse<T>(string strType,out T result)
{
    string strTypeFixed = strType.Replace(' ', '_');
    if (Enum.IsDefined(typeof(T), strTypeFixed))
    {
        result = (T)Enum.Parse(typeof(T), strTypeFixed, true);
        return true;
    }
    else
    {
        foreach (string value in Enum.GetNames(typeof(T)))
        {
            if (value.Equals(strTypeFixed, StringComparison.OrdinalIgnoreCase))
            {
                result = (T)Enum.Parse(typeof(T), value);
                return true;
            }
        }
        result = default(T);
        return false;
    }
}

The line 'string strTypeFixed = strType.Replace(' ', '_');' is because I was getting the data from third party WebService that send the enum strings with spaces, what is not allowed in enum, so my enums had '_' instead of  spaces.

To parse a ImageType (from the example above) just use it like this:

ImageType type;
if (Utils.EnumTryParse<ImageType>(typeName, out type))
{
    return type;
}
return ImageType.Jpg;

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:
Categories: C#
Posted by Miron on Saturday, March 08, 2008 8:54 AM
Permalink | Comments (8) | Post RSSRSS comment feed

Update to my compression module to compress third party scripts

My last version of the compression module was working great and able to compress and cache pages, WebResources, CSS and JavaScripts files. It have one problem (that similiar to most of the compression modules you can find). To compress the javascripts files, you have to modify the way you register them and change their links to something like that: 

<script type="text/javascript" src="/Scripts/utils.js">

needs to became 

<script type="text/javascript" src="Scripts/jslib.axd?d=~/Scripts/utils.js">

It is not so hard work to do, but it became useless when you use third party controls as 'Telerik' (RadControls)  and force it to doesn't use it's scripts as WebResources. In such case, the controls 'Injects' their scripts links into the HTML code and you can't modify them as needed to let the compression handler to compress it.  In the new version of my compression component, I added a ResponseFilter that parse the Scripts links in the HTML and convert them into 'compressable' links. By default, this option is disabled in the compression module. To enable it (if you use such third party controls), just add the attribute compressThirdParityScripts="true" to the compression configuration.

Full implementation instructions can be found here: Compression module implementation 

Last code update date: 5-5-08

To download  dll only: HandlersAndModules-NoSource(1.0.1.5).zip (14.67 kb)

Full source code: HandlersAndModules(1.0.1.5).zip (28.67 kb)

Currently rated 5.0 by 2 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted by Miron on Friday, February 22, 2008 4:15 AM
Permalink | Comments (3) | Post RSSRSS comment feed

Simple Generic Business Entities

"Business Entites" are widly commonly use everywhere. Sometimes the entities are very big and contains a lot of methods and properties, but most of the time, they are basicly objects that holds data in easier and cleaner way than DataTables/DataSets. Sometimes you have entity for specific type such "Customer", "Laboratory", "Shop" or whatever, but lots of time you just need to load and hold data that is not from spesific type. Good way to hold such "un typed data" is using Generic. A "Generic Entity" that can hold any kind of data you need in the moment. For example, I create Generic entity called "Quadruple" that have 4 properties that will be from type you choose. If you create an instance of this entity like this:

Quadruplet<int,string,int,string> q1 = new Quadruplet<int,string,int,string>();

Quadruplet<bool,bool,Array,string> q2 = new Quadruplet<bool,bool,Array,string>();

q1 will be entity that can hold int, string, int & string and q2 will be entity that hold bool, bool, Array, string. No casting is needed.

List<Quadruplet<int, string, int, string>> quadrupletList = new List<Quadruplet<int, string, int, string>>();

quadrupletList  will be List of object from type Quadruplet<int,string,int,string>.  This kind of entitis can be very usuful in any kind of application, and it very reusable from application to another. 

In the file below, there are 4 entites: Duplet - hold 2 objects from any kind, Triplet 3 object (I know there is such class in 'System.Web.UI' but it holds 3 objects from the type 'Object' and casting will be needed),  Quadruplet for 4 objects and Quintet for 5. All those entities contains basic needed methods as Equals(object), operator ==, operator != and GetHashCode().

Those entities are NOT comming to replace the  "Customer", "Laboratory", "Shop" or any other specific needed entity. They are to help working with "un type" of data. Where the data is not from specific type or you don't want to make specific entitiy for that data.

SimpleGenericBusinessEntities.zip (4.26 kb)

Currently rated 4.3 by 6 people

  • Currently 4.333333/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted by Miron on Saturday, February 16, 2008 6:57 AM
Permalink | Comments (1) | Post RSSRSS comment feed

Collect all controls from specific type

I got a simple "mission" to make a method that collect all the TextBox controls from any given control on the page (or from the Page itself).  As I like to do things in the most 'Generic' way, I finished with a simple method that collect all contols from any type you want.

This is the method that run recursive and collect all the controls from type T: 

        /// <summary>
        /// Loot recursive and collect the controls
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="contol"></param>
        /// <param name="list"></param>
        private static void LoopControls<T>(Control parentContol, List<T> list) where T : Control
        {
            foreach (Control ctrl in parentContol.Controls)
            {
                if (ctrl is T)
                {
                    list.Add(ctrl as T);
                }
                else
                {
                    if (ctrl.Controls.Count > 0)
                    {
                        LoopControls(ctrl, list);
                    }
                }
            }
        }

To start the 'collecting' process:

        /// <summary>
        /// Collect all the controls from type 'T'
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="contol"></param>
        /// <returns></returns>
        public static List<T> CollectControls<T>(Control parent) where T : Control
        {
            List<T> list = new List<T>();
            LoopControls(parent, list);
            return list;
        }

Drop this method in your 'Utilities' class, and its ready to go.  Now, To collect  all the TextBox in the page, just us it like this:

System.Collections.Generic.List<TextBox> l = Utils.CollectControls<TextBox>(Page);

and to collect all the Labels, just change the  '<TextBox>' to '<Label>'.

Using 'Generic' is very goot thing, and a lot of times, if you thing on the feutre and not focus only on the current mission when you write any method, you will end up using the Generic namespace.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:
Categories: ASP.NET | C# | Server side
Posted by Miron on Wednesday, February 06, 2008 8:50 PM
Permalink | Comments (3) | Post RSSRSS comment feed