About the author

Miron Abramson
Me
Software Engineer,
CTO at PixeliT
and .NET addicted for long time.
Open source projects:
MbCompression - Compression library

Recent comments

Authors

Disclaimer

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

© Copyright 2009

Creative Commons License

Blog Flux Directory
Technology Blogs - Blog Top Sites

Cropping image using jQuery, Jcrop and ASP.NET

Letting the client cropping his images on the site was never an easy task. With jQuery and the plugin Jcrop by Deep Liquid it is easier than ever to do it in ASP.NET site. Here is how to do it:

First we need to include jQuery library,Jcrop script file & Jquery css file in the page. Then, we need to tell Jcrop wich element is our image to crop, and what method to be fire when we are changing the cropping area:

//
//  Initialize Jcrop
//
$(function() {
$('#theImage').Jcrop({
        onChange: showCoords,
        onSelect: showCoords
    });
});

//
//  Will fire every move of the cropping area
//
function showCoords(c) {
    $('#x1').val(c.x);
    $('#y1').val(c.y);
    $('#x2').val(c.x2);
    $('#y2').val(c.y2);
    $('#w').val(c.w);
    $('#h').val(c.h);
};

x1,y1,x2,y2 are inputs from where the code behind will read the values of the cropping area.

The code behind that will actualy crop the image:

 protected void btnCrop_Click(object sender, EventArgs e)
{
    int X1 = Convert.ToInt32(Request.Form["x1"]);
    int Y1 = Convert.ToInt32(Request["y1"]);
    int X2 = Convert.ToInt32(Request.Form["x2"]);
    int Y2 = Convert.ToInt32(Request.Form["y2"]);
    int X = System.Math.Min(X1, X2);
    int Y = System.Math.Min(Y1, Y2);
    int w = Convert.ToInt32(Request.Form["w"]);
    int h = Convert.ToInt32(Request.Form["h"]);

    // That can be any image (jpg,jpeg,png,gif) from anywhere in the server
    string originalFile = Server.MapPath("~/images/miautito.jpg");


    using (Image img = Image.FromFile(originalFile))
    {
        using (System.Drawing.Bitmap _bitmap = new System.Drawing.Bitmap(w, h))
        {
            _bitmap.SetResolution(img.HorizontalResolution, img.VerticalResolution);
            using (Graphics _graphic = Graphics.FromImage(_bitmap))
            {
                _graphic.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                _graphic.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                _graphic.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
                _graphic.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
                _graphic.DrawImage(img, 0, 0, w, h);
                _graphic.DrawImage(img, new Rectangle(0, 0, w, h), X, Y, w, h, GraphicsUnit.Pixel);

                string extension = Path.GetExtension(originalFile);
                string croppedFileName = Guid.NewGuid().ToString();
                string path = Server.MapPath("~/cropped/");


                // If the image is a gif file, change it into png
                if (extension.EndsWith("gif", StringComparison.OrdinalIgnoreCase))
                {
                    extension = ".png";
                }

                string newFullPathName = string.Concat(path, croppedFileName, extension);

                using (EncoderParameters encoderParameters = new EncoderParameters(1))
                {
                    encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, 100L);
                    _bitmap.Save(newFullPathName, GetImageCodec(extension), encoderParameters);
                }
            }
        }
    }
}

Method to find the right codec to save the image in the maximum quality:

/// <summary>
/// Find the right codec
/// </summary>
/// <param name="extension"></param>
/// <returns></returns>
public static ImageCodecInfo GetImageCodec(string extension)
{
    extension = extension.ToUpperInvariant();
    ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
    foreach (ImageCodecInfo codec in codecs)
    {
        if (codec.FilenameExtension.Contains(extension))
        {
            return codec;
        }
    }
    return codecs[1];
}

You can see some demos of the Jquery Here, and actual demo using the above code in here: ASP.NET Demo.

Complete working source is available in the link below:

Crop.zip (165.24 kb)

Currently rated 4.5 by 6 people

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

Categories: ASP.NET | C# | Client side | Server side
Posted by Miron on Monday, April 20, 2009 8:17 AM
Permalink | Comments (11) | Post RSSRSS comment feed

Why I think I will stick with WebForms

The MVC concept is clear and logic and the guys at Microsoft did a very good job with the new MVC Framework , But I think I will stick with the 'old fashioned' WebForms and this is why:

1. I don't need anybody to 'force' me to seperate my code into layers. I do it any way in every site I build. I have a DataAccess layer, a Business logic layer and a 'View' layer, and I know exactly when and where to use each layer.

2. I build web sites. I don't need my code to work with any other 'View' other than HTML, and if I do, as I mentioned before, my Business logic layer is in a seperate dll so I can reuse it.

3. One of the first things I do when I start a new project is to disable the ViewState in the web.config, which leaves me with a hidden field with about 50 chars length (aroung 50bytes) - I can live with that. That will not slow down my site. If the page is not doing any POST, I can remove the <form runat="serve"> from it, and then there will be no ViewState at all.

4. I heavily use JavaScript and Ajax (usually with jQuery & my own js 'framework') to give better user experiance.

5. The only 'Databinding controls' I use are Repeater and ListView (and DropDownList) that are rendering exactly the HTML I want.

6. The only server control (other than  'Databinding controls') I use are HyperLink,Literal and PlaceHolder that not render any extra HTML other then what I want.

7. I heavily use inline expression

8. I use short 2-3 chars names for my controls.

9. I do use NUint (truly, only when I must)

10. I use httpcompression to improve performance.

11. I use Url rewriting if needed.

12. My code is well organized and very easy to maintain.

13. I know all the little secrets of the ASP.NET framework and know how to take it to it's limits

 

I bet my sites have no worse performance than MVC sites or any other technology  and I'm sure it will take me less time to build a well organized site with all the points above.

I built and designed tens of sites. From small, medium to very large, and never had a performance problem that couldn't be solved by using the above points.

Use MVC if you want to be cool. I will stay with my oldy friend - WebForm

Why should I replace a winning horse ?

Currently rated 4.3 by 10 people

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

Tags:
Categories: ASP.NET | C# | Performance
Posted by Miron on Friday, February 13, 2009 6:26 AM
Permalink | Comments (22) | Post RSSRSS comment feed

Generate thumbnails on the fly - Yet another version

There are many posts how to generate thumbnails using ASP.NET. Some good some less. Be sure to get distance from the versions that use Image.GetThumbnailImage method.

I'm using my own version that going with me from project to project and it is an HttpHandler that registered in the web.config. You can specified maximum height, maximum width, both, specified quality (1-100) and if the image will be cached or not. It is working well with .jpg, .bmp, .png and .gif. The code is too long to write it here, but it is really easy to undestand and really easy to implement and use it.

To use it, add the class to your dll or just drop it in the App_Code folder,register the handler in the web.config as the following:

<add verb="*" path="image.axd" type="Miron.Web.ImageHandler" validate="false"/>

In your site, to generate a thumbnail with size 150X150 in 90% quality (The image will be cached automatically):

<img src="image.axd?src=~/images/photo.jpg&amp;w=150&amp;h=150&amp;q=90">

If you want the image to not be stored in the cache:

<img src="image.axd?src=~/images/photo.jpg&amp;w=150&amp;h=150&amp;q=90&amp;nocache">

 

You can see it in action in the gallery I did to my new nephew Noam: http://mironabramson.com/noam

Hope it will be useful.

ImageHandler.zip (2.85 kb)

Be the first to rate this post

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

Categories: ASP.NET | C#
Posted by Miron on Sunday, February 08, 2009 7:51 AM
Permalink | Comments (11) | Post RSSRSS comment feed

Events from control inside Accordion control are not being fired in first click

I never used the Accordion control before. Last days, I had to work on another developer's code that used an Accordion control.  One of the problems the code had was that when you click on a button that inside the Accordion control - the first click doesn't do nothing, only the second click fire the event. The control was inside an updatepanel, so I was sure that make the problem, but it still happened after I took it out from the updatepanel.

I searched the Internet, and I found that is very common problem with that control. I tried lot of solutions suggested, like adding a reference  to the button in the OnInit page event, adding manually  the event, and some stuff similar, but nothing really worked. After I almost got crazy, I found this post and it had some source code that claimed to be the solution. I downloaded the whole source of the AjaxControlToolkit.dll, change the code in the Accordion class with the attached code in the post, compiled it, replaced the AjaxControlToolkit.dll in my project with the new compiled one - and Walla!!! the Accordion starts to work as expected, and to fire all the needed events!

So, if you have that problem, that events are not being fired from withing your Accordion control, and you are lazy to download and compile the source code of the AjaxControlToolkit, just download the file below, replace the AjaxControlToolkit.dll in your project with this one, and your Accordion will work just fine.

AjaxControlToolkit.zip (402.69 kb)

Currently rated 4.0 by 1 people

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

Posted by Miron on Sunday, December 21, 2008 7:38 AM
Permalink | Comments (8) | Post RSSRSS comment feed

Fast version of the Activator.CreateInstance method using IL

We all know (I guess) the method Activator.CreateInstance(Type) and the generic version:  Activator.CreateInstance<T>()  that are used to create an instance of a specified Type.

In now days all are talking about 'Entity-relationship model' , 'Object-relational mapping' and that stuff, that basically it means getting a IDataReader, loop over it and fill with the data a List with specfied type of objects and return a List instead of DataSet or DataTable (or similar mechanism). While looping over the IDataReader, every iterate, an instance of the specified type needs to be create. It can be done using one of the methods above, but it can be improved by usind IL and some help using some cache. Here is how can it be done:

public static class FastObjectFactory
{
    private static readonly Hashtable creatorCache = Hashtable.Synchronized(new Hashtable());
    private readonly static Type coType = typeof(CreateObject);
    public delegate object CreateObject();

    /// <summary>
    /// Create an object that will used as a 'factory' to the specified type T 
   /// <returns></returns>
    public static CreateObject CreateObjectFactory<T>() where T : class
    {
        Type t = typeof(T);
        FastObjectFactory.CreateObject c = creatorCache[t] as FastObjectFactory.CreateObject;
        if (c == null)
        {
            lock (creatorCache.SyncRoot)
            {
                c = creatorCache[t] as FastObjectFactory.CreateObject;
                if (c != null)
                {
                    return c;
                }
                DynamicMethod dynMethod = new DynamicMethod("DM$OBJ_FACTORY_" + t.Name, typeof(object), null, t);
                ILGenerator ilGen = dynMethod.GetILGenerator();

                ilGen.Emit(OpCodes.Newobj, t.GetConstructor(Type.EmptyTypes));
                ilGen.Emit(OpCodes.Ret);
                c = (CreateObject)dynMethod.CreateDelegate(coType);
                creatorCache.Add(t, c);
            }
        }
        return c;
    }
}

Note the static HashTable is been used as a cache. The first  time we create a delegate 'CreateObjec' for the given type it is 'slow', so all the point here, is to cache this delegate. The next time we need to create an object from the given type, the 'CreateObjec' delegate will be used from the cache. Without caching it, the whole story worth nothing.

Here are some benchmarks:

1 Object:



100 Objects:

1000 Objects:

Comparing to the generic constraint : new()

Below there is the small project I used for the benchmarks:

FastObjectFactory.zip (50.35 kb)

Currently rated 5.0 by 6 people

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

Categories: C# | Performance | IL
Posted by Miron on Saturday, August 09, 2008 12:52 PM
Permalink | Comments (17) | Post RSSRSS comment feed

High performance css minifier

It is known that minifying the JavaScript and CSS files can really reduce the files size and improve the general site performance. Lot of sites (BlogEngine.NET among them)  do it on run-time and not it the build time. At this point, I want to recommend the JavaScript minifier JSMIN by Douglas Crockford. It does the job very good, and by far, much faster than all the RegularExpression \ Replace minifiers. Because in my Compression project MbCompression I do the minifying on run-time, I decided to use jsmin minifier.

The Css minifier

All the Css minifiers I found are using Regular Expression\ Replace to remove the unneeded characters. This is working fine, but have a realy bad performance, special on run-time. The speed is slow (special using the Regular Expression), and another important thing is, every Replace creates a very big string in the memory! (Strings are immutable, remember?), so if you have several Replaces, it creates several big strings in the server memory!

To improve performance, I took  JSMIN idea, that are not using any strings in the memory, and perform the minifying much faster, and created a CSS minifier that produce a small CSS file, much faster, and with much less memory overhead.

This minifier was tested on several CSS files. Feel free to download it and use it. If there is any file that not been minify correctly, send it to me, and I will try to improve the minifier.

CssMinifier.cs (9.59 kb)

Currently rated 5.0 by 9 people

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

Categories: C# | Client side | Performance
Posted by Miron on Sunday, June 29, 2008 4:48 AM
Permalink | Comments (17) | Post RSSRSS comment feed

Create your own new Type and use it on run-time (C#)

It is not something you will use on daily bases. It doesn't have good performance. But one day, you will have to use it so it's good to know that it is possible. As you can understand from the title, I'm talking about creating a new type with fields and properties (it can also have methods), create instance/s from it and use it. It will not be 'type safe', of course, and you will be able to use it - read and set its values only with reflection. but, all the DataBindingControls (GridView, FormView etc...) are binding the data using reflection, so they will be happy to bind and use your new created objects from your own type you created on run-time.

Lets cut the crap and jump into the code:

Let's say you got an xml from a webservice. and you want to create an object from it. Something like that:

You receive an xml like this:

<root>
    <column name="Name">Miron</column>
    <column name="LastName">Abramson</column>
    <column name="Blog">www.blog.mironabramson.com</column>
</root> 

You want to make a 'match' type that looks like this:

public class MyType
{
    public string Name{ get; set; }
    public string LastName{ get; set; }
    public string Blog{ get; set; }
}

and than create an object from that type and fill it with your data. The prolem is that you don't know what will be the values of the xml attributes and fields. So you need to create the object on run-time:

private object CreateOurNewObject()
{
    string _xml = "<root>" +
        "<column name=\"Name\">Miron</column>" +
        "<column name=\"LastName\">Abramson</column>" +
        "<column name=\"Blog\">www.blog.mironabramson.com</column>" +
        "</root>";

    XmlDocument xmlDoc = new XmlDocument();
    xmlDoc.LoadXml(_xml);

    // create a dynamic assembly and module
    AssemblyName assemblyName = new AssemblyName();
    assemblyName.Name = "tmpAssembly";
    AssemblyBuilder assemblyBuilder = Thread.GetDomain().DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
    ModuleBuilder module = assemblyBuilder.DefineDynamicModule("tmpModule");

    // create a new type builder
    TypeBuilder typeBuilder = module.DefineType("BindableRowCellCollection", TypeAttributes.Public | TypeAttributes.Class);

    // Loop over the attributes that will be used as the properties names in out new type
    foreach (XmlNode node in xmlDoc.SelectSingleNode("root").ChildNodes)
    {
        string propertyName = node.Attributes["name"].Value;

        // Generate a private field
        FieldBuilder field = typeBuilder.DefineField("_" + propertyName, typeof(string), FieldAttributes.Private);
        // Generate a public property
        PropertyBuilder property =
            typeBuilder.DefineProperty(propertyName,
                             PropertyAttributes.None,
                             typeof(string),
                             new Type[] { typeof(string) });

        // The property set and property get methods require a special set of attributes:

        MethodAttributes GetSetAttr =
            MethodAttributes.Public |
            MethodAttributes.HideBySig;

        // Define the "get" accessor method for current private field.
        MethodBuilder currGetPropMthdBldr =
            typeBuilder.DefineMethod("get_value",
                                       GetSetAttr,
                                       typeof(string),
                                       Type.EmptyTypes);

        // Intermediate Language stuff...
        ILGenerator currGetIL = currGetPropMthdBldr.GetILGenerator();
        currGetIL.Emit(OpCodes.Ldarg_0);
        currGetIL.Emit(OpCodes.Ldfld, field);
        currGetIL.Emit(OpCodes.Ret);

        // Define the "set" accessor method for current private field.
        MethodBuilder currSetPropMthdBldr =
            typeBuilder.DefineMethod("set_value",
                                       GetSetAttr,
                                       null,
                                       new Type[] { typeof(string) });

        // Again some Intermediate Language stuff...
        ILGenerator currSetIL = currSetPropMthdBldr.GetILGenerator();
        currSetIL.Emit(OpCodes.Ldarg_0);
        currSetIL.Emit(OpCodes.Ldarg_1);
        currSetIL.Emit(OpCodes.Stfld, field);
        currSetIL.Emit(OpCodes.Ret);

        // Last, we must map the two methods created above to our PropertyBuilder to
        // their corresponding behaviors, "get" and "set" respectively.
        property.SetGetMethod(currGetPropMthdBldr);
        property.SetSetMethod(currSetPropMthdBldr);
    }

    // Generate our type
    Type generetedType = typeBuilder.CreateType();

    // Now we have our type. Let's create an instance from it:
    object generetedObject = Activator.CreateInstance(generetedType);

    // Loop over all the generated properties, and assign the values from our XML:
    PropertyInfo[] properties = generetedType.GetProperties();

    int propertiesCounter = 0;

    // Loop over the values that we will assign to the properties
    foreach (XmlNode node in xmlDoc.SelectSingleNode("root").ChildNodes)
    {
        string value = node.InnerText;
        properties[propertiesCounter].SetValue(generetedObject, value, null);
        propertiesCounter++;
    }
  
    //Yoopy ! Return our new genereted object.
    return generetedObject;
}

Mazal Tov!!!

We create our type and instance from it on run-time !!!

In the file bellow, there is full working exmple of the code

 

MyTypeRunTime.zip (4.15 kb)

Currently rated 4.2 by 15 people

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

Posted by Miron on Monday, June 09, 2008 10:43 AM
Permalink | Comments (14) | Post RSSRSS comment feed

Prevent from the user to submit any 'not legal' input, using client side validation

We are all know that client validations are good way to validate input, of cource you must re validate in server side also, but the client side will save some wasted post backs. Usually, we validate each input separate (writing manually script, or a validator control). What if you have a rule that is for all inputs in the page, or in the site? for example, you want to prevent the user to submit any input that contains 'fuc*' , 'shi*' or what ever words that are not 'legal' for you, or input that is not valid for the ASP.NET such '<'or  '/>' ?

I wrote some JavaScript code, that validate all the TextBox and Textarea controls in the page, and prevent it to be submitted if one (or more) of the input/s is in your 'not legal words' list. What the script actualy does, is checking the values of all Textboxes in the page, and if one input value contains one of the 'bad' words that defined in the 'MachingWords' variable, it will pop an alert, and will cancel the submit.  Here we go:

 // List of 'bad' words.  Append here all the words you want from the user to submit as an input, seperates by '|' char.

var MachingWords = "<|/>|fuck|shit|ass";


function FormValidationController()
{
    this.IsValid = true;
    this._notValidValuesCollection = [];
    this._notValidValuesHash = new Array();
    this.AddNotValidValue = function(value){   
        if( !this._notValidValuesHash[value] ){
            this._notValidValuesHash[value] = 1;
            this._notValidValuesCollection.push(value);
        }
    }
    this.PopMessage = function() {
        var wordsList = '';
        for( var i = 0 ; i < this._notValidValuesCollection.length ; i++ ) {
            wordsList = wordsList.length < 1 ? "'" + this._notValidValuesCollection[i] + "'" : wordsList + ", '" + this._notValidValuesCollection[i] + "'";
        }
        var notValidMessage = "The input{0} {1} {2} not valid.";
        alert( String.Format(notValidMessage,(this._notValidValuesCollection.length > 1 ? "s" : ""),(wordsList),(this._notValidValuesCollection.length > 1 ? "are" : "is")) );
    }
    this.Validate = function(){
        this.IsValid = true;
        this._notValidValuesCollection = [];
        this._notValidValuesHash = new Array();
        var inputElementsCollection = document.getElementsByTagName("INPUT");
        if( inputElementsCollection ){
            for (var index=0; index<inputElementsCollection.length; index++) {
                var el=inputElementsCollection[index];
                if( el.type.toLowerCase() == 'text' )
                    this.ValidateInput(el);
            }
        }
        var textareaElementsCollection = document.getElementsByTagName("TEXTAREA");
        if( textareaElementsCollection ){
            for (var index=0; index<textareaElementsCollection.length; index++) {
                var el=textareaElementsCollection[index];
                this.ValidateInput(el);
            }
        }
    }
    this.ValidateInput = function (element) {
        if( element ){
            if( !this.IsValidString(element.value) ) {
                this.AddNotValidValue(element.value);
                if( this.IsValid ){
                    this.IsValid = false;
                    element.focus();
                    element.select();
                }
            }
        }
    }
}

FormValidationController.RegularExpression = new RegExp(MachingWords,"i","g");
// Validate the current input
FormValidationController.prototype.IsValidString = function(strInput)
{   
    if( !strInput || typeof( strInput ) == 'string' ){
          if( strInput.length < 1 )
            return true;
    }
    if( FormValidationController.RegularExpression.test ( strInput ) )
        return false;
    return true;
}
var c = new FormValidationController();

//
// 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;
}

And the method that using it and excuting the validation:

 //
//  Excute the validation
//
function ValidatePage() {
    c.Validate();
    if( !c.IsValid ) {
           c.PopMessage();
           return false;
      }
    return true;
}

 The implementation is very simple. Add the script to your page, and add to  the OnLoad page event  the following line, and that's it.

ClientScript.RegisterOnSubmitStatement(this.GetType(), "ValidatePage", "return ValidatePage();");

Javascript file with the code available here: 

FormValidation.js (3.23 kb)

Currently rated 5.0 by 3 people

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

Categories: ASP.NET | Client side
Posted by Miron on Saturday, May 17, 2008 9:53 AM
Permalink | Comments (1) | Post RSSRSS comment feed

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)

Currently rated 4.7 by 6 people

  • Currently 4.666667/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 (7) | 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 save 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.7 by 7 people

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

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