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 2014

Creative Commons License

Blog Flux Directory
Technology Blogs - Blog Top Sites

Limit uploaded files size in FCKeditor

FCKeditor (Changed to CKEditor for some reasons) is the coolest editor for asp.net (it works also with lot of other languages). It is easy to implement, full of features and can be easily customized.

I use it for some personal sites. One important feature  that is missing is the option to control and limit the size of individual uploaded file. I know I can do it in the web.config using the httpRuntime section, but it will effect all the site. I wanted to control the limit of individual uploaded file. Since the ASP.NET FCKeditor is an open source, I downloaded the source and made some changes to conquer my needs. Below you can download the modified code, or the compiled dll (release mode).

To control the limits of the uploaded files, After you placed the modified dll in your BIN folder, dig into the folder  \editor\filemanager\connectors\aspx inside your editor folder. There you will find the file 'config.ascx'. The method 'SetConfig()' is the place you will made some changes:

Add TypeConfig["File"].MaxAllowdSize = 4096;  to set the maximum uploaded file to 4MB

Add TypeConfig["Image"].MaxAllowdSize = 2096; to set the maximum, uploaded image to 2MB

TypeConfig["Flash"].MaxAllowdSize = 2096; to set the maximum, uploaded flash to 2MB

TypeConfig["Media"].MaxAllowdSize = 4096; to set the maximum uploaded media file to 4MB

Of course the numbers can be change as your needs.

FredCK.FCKeditorV2.dll.zip (14.26 kb)

FCKEditor.NET_src.zip (61.11 kb)

Currently rated 5.0 by 5 people

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

Tags:
Categories: ASP.NET
Posted by Miron on Friday, September 25, 2009 5:34 AM
Permalink | Comments (3) | Post RSSRSS comment feed

HttpCompression on IIS7 (Using MbCompression library)

If You have full control on the server, you probably don't need my compression library MbCompression, But if you are using share hosting, sure you do.

I just uploaded the configuration for the compression library to work on IIS7.  Check the latest source code from here

Currently rated 4.6 by 7 people

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

Posted by Miron on Thursday, July 23, 2009 8:46 AM
Permalink | Comments (5) | Post RSSRSS comment feed

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.6 by 17 people

  • Currently 4.647059/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 (5) | 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 3.5 by 21 people

  • Currently 3.523809/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 (21) | 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)

Currently rated 4.2 by 6 people

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

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

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

Update: In the last release of AjaxControlToolkit, the problem had been solved

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.7 by 3 people

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

Posted by Miron on Sunday, December 21, 2008 7:38 AM
Permalink | Comments (6) | 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.4 by 29 people

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

Posted by Miron on Monday, June 09, 2008 10:43 AM
Permalink | Comments (24) | 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 4.8 by 4 people

  • Currently 4.75/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 (2) | 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.5 by 10 people

  • Currently 4.500001/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

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