InternetException

About coding and whatnot.

Entity Framework and Base Entity class

clock May 16, 2013 14:32 by author n.podbielski

Entity Framework does great job with taking care of entities changes and entities collection internally. And its uses almost plain POCO objects. Almost because collections of dependents data like in 1 to many tables relationship needs virtual keyword. Its understandable since EF needs to track what happens to collection. For instance lets have 2 tables: Customer and dependent Order.

To map this relation in EF model we need to create two classes: Customer with relationship to Orders collection and Order with relationship to single Customer. Both end of relation needs to be virtual. Oh well. Actually they aren't have to be virtual, but as you can read here this allow for 'lazy loading' and 'change tracking' capabilities of EF, so its pretty useful to add virtual keywords in those places.

public partial class Customer
{
public int Id { get; set; } public string Name { get; set; } public virtual ICollection<Order> Orders { get; set; } } public partial class Order {
public int Id { get; set; } public virtual Customer Customer { get; set; } }

That's pretty much it. There some rare cases when for example useful is to initialize collection of child entities on entity creation but its not requirement from EF point of view. So what could be the reason to add base class for entity?

Thing is that whenever you want to transfer entity to some another subsystem to make changes there, Entity Framework cannot and could not track those changes (you NEVER EVER should transfer entity object directly but map it to some other data object first!). Mapping data from entity to some data transfer object (DTO), making changes and returning them again to EF, will more likely fail. With simple object its achievable and should working, but it can spawn errors with collections mapping. In last application I was working that was the case. But I used EntityFramework.Patters extension so, in pure EF this can work fine (but I doubt it).

Root of the problem was Order collection in Customer entity. When I tried to transfer customer through i.e. WCF service, make changes at client side, and return them to EF, it caused EF to think that I deleted all items from Orders, and added some new instead. Its cool that it can tell that collection changed. To bad that this happens even when it not changed at all! To be frank EF wasn't entirely responsible it was mapping mechanism in AutoMapper. It wasn't considering two Order items with same values the same because they weren't referencing same object. After replacing old Order with new Order in AutoMapper, EF wasn't considering them equal for exactly same reason: reference to them was different.

How to remedy that? There have to be some custom mechanism of entities equality. And its best to that on some BaseEntity object, right?

public class BaseEntity : BaseEntity where TEntity : BaseEntity
    {
        private int? oldHashCode;

        public override bool Equals(object obj)
        {
            if (obj == null)
            {
                return false;
            }
            if (obj == this)
            {
                return true;
            }
            if (obj is TEntity)
            {
                var objAsBaseEntity = obj as TEntity;
                return objAsBaseEntity.Id == this.Id;
            }
            return false;
        }
    }

This implementation is partly based on MSDN Equals guidelines and on base entity class I have found for NHibernate. But is not enough.  With Equals implementation we have to implement also GetHashCode. Problem with this is that, new entity should have whole time its exists the same hash code. More important hash code should be only dependent on Id property, which is only thing that allow two separate objects to be equal. So we need to make entity hash code dependent on id. But what about two new objects? They will have empty id and because of that the same hash code? One solution is to make hash code to be generated from base class when Id is empty.

public override int GetHashCode()
{
    // once we have a hashcode we'll never change it
    if (oldHashCode.HasValue)
    return oldHashCode.Value;
    // when this instance is new we use the base hash code
    // and remember it, so an instance can NEVER change its
    // hash code.
    var thisIsNew = Id == Guid.Empty;
    if (thisIsNew)
    {
        oldHashCode = base.GetHashCode();
        return oldHashCode.Value;
    }
    return Id.GetHashCode();
}

When id is set, hash code is generated from it. When it is not set, hash code is generated from base class which is object in our case. And first time hash code is generated is final. Hash code cannot be changed. It is because it would brake functionality of HashSet and Dictionary classes. EF uses both of them so it would be big issue. It is best implementation I could find, and still it have some drawbacks. For example entity loaded from DB and mapped from outside of EF with the same data and the same Id will have different hash code. It is because in first situation hash code is generated from database id. In second situation hash code is generated from new object which have empty id. It does not matter that after hash code generation id is set to real value. Once it is generated it can not be changed.

To remedy that we need to make mapping of mapped entities and entities loaded from DB by hand.
In next post I will explain how to make class that will resolve mapping of entities to correct this issue.

 

 



Ninject and Entity Framework

clock May 3, 2013 03:50 by author n.podbielski

Last time I wrote about problem with testing Entity Framework in Visual Studio 2012. During working on this project I also encounter problems with configuration of Ninject to allow injecting Entity Framework classes from its Patterns extension. To be frankly this was not much a problem then lack of documentation. I just was forced to experiment with Ninject and new-thing-for-me Entity Framework Patterns extension.

So to make world of .NET a little easier I decided to write about my experience.

I started with this documentation for EF extension. It is instruction for someone that decided to use Unity in their project.

There is also link to similar instruction with Ninject IoC container, but its empty. Why authors of this extension decided to include in documentation of their project link to something that is empty eludes me. Oh well you have to make through with things you have. It should not be hard to translate Unity configuration syntax to its equivalent in Ninject.

 

public static class CompositionRoot
    {

        private static readonly IUnityContainer UnityContainer = new UnityContainer();

        public static IUnityContainer Container { get { return UnityContainer; } }

        public static void RegisterServices()
        {
            // Registering interfaces of Unit Of Work & Generic Repository
            UnityContainer.RegisterType(typeof(IRepository<>), typeof(Repository<>));
            UnityContainer.RegisterType(typeof(IUnitOfWork), typeof(UnitOfWork));

            // Every time we ask for a EF context, we'll pass our own Context.
            UnityContainer.RegisterType(typeof(DbContext), typeof(Context));

            // Tricky part.
            // Your repositories and unit of work must share the same DbContextAdapter, so we register an instance that will always be used
            // on subsequente resolve.
            // Note : you should not use ContainerControlledLifetimeManager when using ASP.NET or MVC
            // and use a per request lifetime manager
            UnityContainer.RegisterInstance(new DbContextAdapter(UnityContainer.Resolve()), new ContainerControlledLifetimeManager());

            UnityContainer.RegisterType(
                new InjectionFactory(con => con.Resolve())
                );

            UnityContainer.RegisterType(
                new InjectionFactory(con => con.Resolve())
                );
        }
    }

As you can see it is a little convoluted. That is one of reasons why I like Ninject more. It is cleaner.

Oh right. First lets create Ninject module:

public class InjectModule : NinjectModule
    {
        public override void Load()
        {
           
        }
    }

Modules like that one are used by Ninject in following way:

var kernel = new StandardKernel();
kernel.Load<InjectModule>();

Depending of where you are starting Ninject container it can look a little diffrent but idea is the same you are using modules for registering packs of types. Using that i created module for EF in EF assembly and that way it can be shared in my tests, services, console applications etc.

Now lets fill this new module with meaningfull code. Firstly we will register repository and unit of work interfaces:

Bind(typeof(IRepository<>)).To(typeof(Repository<>));
Bind<IUnitOfWork&gt().To<UnitOfWork&gt();

Isn't that cleaner than Unity syntax? Next we need to register EF context class. It is as simple as:

Bind<DbContext>().To<DBEntities>();

Ofcourse DBEntities is your type of EF context class.

Now the harder part, a Unity 'tricky' registering of DBContextAdapter class. What we trying to do here is to make every instance of Repository and UnitOfWork, that is created by Ninject and is transient, created whenever necessary and then disposed, had to share same instance of DBContextAdapter. I decided to make this class single for thread scope. It is not ideal but is bult-in behavior of Ninject. In best case it should be shared for our whole application inlcuding spawned threads. Or for Web apps it could be better to use InRequestScope

Bind<DbContextAdapter>().To<DbContextAdapter>().InThreadScope();

To bind interfaces used by UnitOfWork an Repository classes, which allow them use context class indirectly through shared DBContextAdapter class, we have to bind those interfaces to shared instance of this class. To do that we register interfaces IObjectSetFactory (used by repository) and IObjectContext (used by UnitOfWork) with custom method that returns DBContextAdapter:

Bind<IObjectSetFactory, IObjectContext>()
               .ToMethod(con =>con.Kernel.Get<DbContextAdapter>());

Whole module for configuration of EF will looks like this:

 

public class EFModule : NinjectModule
{
public override void Load()
{
Bind(typeof(IRepository<>)) .To(typeof(Repository<>));
Bind<IUnitOfWork>().To<UnitOfWork>();
Bind<UnitOfWork>().ToSelf();
Bind<DbContext>().To<DBEntities>();
Bind<DbContextAdapter>().To<DbContextAdapter>().InThreadScope();
Bind<IObjectSetFactory, IObjectContext>()
.ToMethod(con =>con.Kernel.Get<DbContextAdapter>());
}
}


This is sufficient to make EF with Patterns extension working in our application.

this.kernel = new StandardKernel();
kernel.Load();
repository = kernel.Get<IRepository>();

var uow = kernel.Get<IUnitOfWork>();
repository.Insert(new Enity{});
uow.Commit();

This is it. Operation with UoW and repository pattern should work with EF.

Personally I am unhappy that this particular implementation of UnitOfWork does not implement IDisposable interface. This would greatly improve clarity of code as would be helpfull during maintaining of the code.

this.kernel = new StandardKernel();
kernel.Load();
repository = kernel.Get<IRepository>();

using(var uow = kernel.Get<IUnitOfWork>())
{
	repository.Insert(new Enity{});
	uow.Commit();
}

But you cant have everything Smile



Entity Framework Patterns extension and Unit Test in Visual Studio 2012

clock April 23, 2013 02:18 by author n.podbielski

Yesterday I was trying to make work simple test class in VS2012. I did not know what was wrong exactly. It was first project when I tried to glue together Entity Framework with repository pattern and Ninject as IoC container. Because of the fact that this was first time for solution like that I was sure that it is me, or rather source of my problem was indeed my code. But let's not skip ahead.

So when I manage to translate adding EF classes to Unity from here: IoC : using EntityFramework.Patterns with Unity 2.1 into Ninject language. I got error like this from VS (when tried to running test case):


Result Message:    Unable to create instance of class UnitTest. Error: System.IO.FileLoadException: Could not load file or assembly 'EntityFramework, Version=4.3.1.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040).
Result StackTrace:   
at System.Signature.GetSignature(Void* pCorSig, Int32 cCorSig, RuntimeFieldHandleInternal fieldHandle, IRuntimeMethodInfo methodHandle, RuntimeType declaringType)
   at System.Signature..ctor(IRuntimeMethodInfo methodHandle, RuntimeType declaringType)
   at System.Reflection.RuntimeConstructorInfo.GetParametersNoCopy()
   at System.Reflection.RuntimeConstructorInfo.GetParameters()
   at Ninject.Injection.DynamicMethodInjectorFactory.EmitLoadMethodArguments(ILGenerator il, MethodBase targetMethod) in c:\Projects\Ninject\ninject\src\Ninject\Injection\DynamicMethodInjectorFactory.cs:line 115
   at Ninject.Injection.DynamicMethodInjectorFactory.Create(ConstructorInfo constructor) in c:\Projects\Ninject\ninject\src\Ninject\Injection\DynamicMethodInjectorFactory.cs:line 40
   at Ninject.Planning.Strategies.ConstructorReflectionStrategy.Execute(IPlan plan) in c:\Projects\Ninject\ninject\src\Ninject\Planning\Strategies\ConstructorReflectionStrategy.cs:line 67
   at Ninject.Planning.Planner.<>c__DisplayClass1.<CreateNewPlan>b__0(IPlanningStrategy s) in c:\Projects\Ninject\ninject\src\Ninject\Planning\Planner.cs:line 109
   at Ninject.Infrastructure.Language.ExtensionsForIEnumerableOfT.Map[T](IEnumerable`1 series, Action`1 action) in c:\Projects\Ninject\ninject\src\Ninject\Infrastructure\Language\ExtensionsForIEnumerableOfT.cs:line 32
   at Ninject.Planning.Planner.CreateNewPlan(Type type) in c:\Projects\Ninject\ninject\src\Ninject\Planning\Planner.cs:line 109
   at Ninject.Planning.Planner.GetPlan(Type type) in c:\Projects\Ninject\ninject\src\Ninject\Planning\Planner.cs:line 71
   at Ninject.Activation.Providers.StandardProvider.Create(IContext context) in c:\Projects\Ninject\ninject\src\Ninject\Activation\Providers\StandardProvider.cs:line 77
   at Ninject.Activation.Context.Resolve() in c:\Projects\Ninject\ninject\src\Ninject\Activation\Context.cs:line 157
   at Ninject.KernelBase.<>c__DisplayClass10.<Resolve>b__c(IBinding binding) in c:\Projects\Ninject\ninject\src\Ninject\KernelBase.cs:line 386
   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
   at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source)
   at Ninject.Planning.Targets.Target`1.GetValue(Type service, IContext parent) in c:\Projects\Ninject\ninject\src\Ninject\Planning\Targets\Target.cs:line 197
   at Ninject.Planning.Targets.Target`1.ResolveWithin(IContext parent) in c:\Projects\Ninject\ninject\src\Ninject\Planning\Targets\Target.cs:line 165
   at Ninject.Activation.Providers.StandardProvider.GetValue(IContext context, ITarget target) in c:\Projects\Ninject\ninject\src\Ninject\Activation\Providers\StandardProvider.cs:line 114
   at Ninject.Activation.Providers.StandardProvider.<>c__DisplayClass4.<Create>b__2(ITarget target) in c:\Projects\Ninject\ninject\src\Ninject\Activation\Providers\StandardProvider.cs:line 96
   at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext()
   at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
   at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
   at Ninject.Activation.Providers.StandardProvider.Create(IContext context) in c:\Projects\Ninject\ninject\src\Ninject\Activation\Providers\StandardProvider.cs:line 96
   at Ninject.Activation.Context.Resolve() in c:\Projects\Ninject\ninject\src\Ninject\Activation\Context.cs:line 157
   at Ninject.KernelBase.<>c__DisplayClass10.<Resolve>b__c(IBinding binding) in c:\Projects\Ninject\ninject\src\Ninject\KernelBase.cs:line 386
   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
   at System.Linq.Enumerable.<CastIterator>d__b1`1.MoveNext()
   at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source)
   at Ninject.ResolutionExtensions.Get[T](IResolutionRoot root, IParameter[] parameters) in c:\Projects\Ninject\ninject\src\Ninject\Syntax\ResolutionExtensions.cs:line 37
   at UnitTest..ctor()

So my first thought was: heck, I probably did something wrong and it not so easy (Ninject registrations of components is really easy, you should try yourself). But I cannot find any references to that version of EF anywhere in my project. In fact I did not added them myself, everything was done by NuGet, so it should work, right? Yes. It should and it was working because:

1. Registration of classes from EntityFramework.dll was working perfectly.

2. Registration of classes from EntityFramework.Pattersn.dll was not working at all.

3. When I added console project registration of both types from both assemblies was working without problems.

So the problem was with EntityFramework.Patterns.dll, its internal reference to older version of EF (I was using 5.0 version). Another problem was with assembly redirecting from older version of EF to newer 5.0. In console project section in app.config:

 <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="EntityFramework" publicKeyToken="b77a5c561934e089" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
      </dependentAssembly>
   </assemblyBinding>
  </runtime>

was doing what it suppose to, forcing application to use 5.0 version despite internal reference to version 4.3.1 inside EntityFramework.Patterns.dll. So maybe in test it is not present. Nope it was. Maybe configuration is not copied into Debug dir? Nope. Maybe it is named wrong? Nope. In this moment I had to take a few minutes off.

I was thinking: everything is as it suppose to. Assemblies, references, redirecting, configuration. So... maybe test environment is not starting correctly? Maybe it is ignoring that part of app.config. When I was adding NuGet packages same day I noticed update for VS. Why not tried that? Few clicks, about 1 hour and restart of VS after I tried again. Guess what? It worked!

So it was bug with VisualStudio. I was glad that it was over and little disappointed for few hours that I have lost. But it was at least one step closer in the right direction. Smile

 

So if you encounter problem like that tried update VS 2012 with Update 2. It should work!



Line in WebGL and why you gonna do this on your own.

clock February 26, 2013 02:15 by author n.podbielski

WebGL as method for generating 3D graphic in browser is pretty powerful. You can do really awesome things with this, like porting Quake 2 to JavaScript or creating model of human body. But all of this 3D object are complex collection of hundreds or thousands triangles. What if you just want to draw a simple thin line? Luckily OpenES have support for that. So it is possible. Lets see how to do that.

I will use for that changed code from Minimum length WebGL code to draw least meaningful output - A straight line. What I changed was just removing of few unnecessary lines and putting all uninteresting boilerplate code into functions. First, initGl, initializes WebGl context from canvas tag. Second, initShaders, creates shaders program and initializes it with location of uniforms and attributes. Next initializes scene by clearing plane, creates model-view matrix and perspective matrix. I changed those matrices to those, which I think will help to understand line points coordinates, because Z axis is orthogonal to screen, so point (-1,-1,0) will actually at bottom-left part of canvas. To put it simple: scene viewer and you will look from the same point (more or less of course Smile). Model view matrix will also translates all Z coordinates by -7, so points with Z = 0, will be visible. Now code:

 

<html>
<head>
    <title></title>
    <script type="text/javascript">

        var fragShaderSource = "\
precision highp float;\
uniform vec4 u_color;\
void main(void) {\
gl_FragColor = u_color;\
}\
";

        var vtxShaderSource = "\
attribute vec3 a_position;\
uniform vec4 u_color;\
uniform mat4 u_mvMatrix;\
uniform mat4 u_pMatrix;\
void main(void) {\
gl_Position = u_pMatrix * u_mvMatrix * vec4(a_position, 1.0);\
}\
";

        function get_shader(type, source) {
            var shader = gl.createShader(type);
            gl.shaderSource(shader, source);
            gl.compileShader(shader);
            return shader;
        }

        var gl, pMatrix, mvMatrix, vbuf,ibuf;

        function initGl() {
            var canvas = document.getElementsByTagName('canvas')[0];
            gl = canvas.getContext("experimental-webgl", { antialias: true });
            gl.viewport(0, 0, canvas.width, canvas.height);
        }

        function initShaders() {
            var vertexShader = get_shader(gl.VERTEX_SHADER, vtxShaderSource);
            var fragmentShader = get_shader(gl.FRAGMENT_SHADER, fragShaderSource);
            shaderProgram = gl.createProgram();
            gl.attachShader(shaderProgram, vertexShader);
            gl.attachShader(shaderProgram, fragmentShader);
            gl.linkProgram(shaderProgram);
            gl.useProgram(shaderProgram);
            shaderProgram.aposAttrib = gl.getAttribLocation(shaderProgram, "a_position");
            gl.enableVertexAttribArray(shaderProgram.aposAttrib);
            shaderProgram.colorUniform = gl.getUniformLocation(shaderProgram, "u_color");
            shaderProgram.pMUniform = gl.getUniformLocation(shaderProgram, "u_pMatrix");
            shaderProgram.mvMUniform = gl.getUniformLocation(shaderProgram, "u_mvMatrix");
        }

        function initScene() {
            gl.clearColor(0.0, 0.0, 0.0, 0.0);
            mvMatrix =
                              [1, 0, 0, 0
                              , 0, 1, 0.00009999999747378752, 0,
                              0, -0.00009999999747378752, 1, 0,
                              0, 1.3552527156068805e-20, -8, 1];
            pMatrix =
                              [2.4142136573791504, 0, 0, 0,
                              0, 2.4142136573791504, 0, 0,
                              0, 0, -1.0020020008087158, -1,
                              0, 0, -0.20020020008087158, 0];
            gl.enable(gl.DEPTH_TEST);
            gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
            gl.uniformMatrix4fv(shaderProgram.pMUniform, false, new Float32Array(pMatrix));
            gl.uniformMatrix4fv(shaderProgram.mvMUniform, false, new Float32Array(mvMatrix));
        }

        function initBuffer(glELEMENT_ARRAY_BUFFER, data) {
            var buf = gl.createBuffer();
            gl.bindBuffer(glELEMENT_ARRAY_BUFFER, buf);
            gl.bufferData(glELEMENT_ARRAY_BUFFER, data, gl.STATIC_DRAW);
            return buf;
        }

        function initBuffers(vtx, idx) {
            vbuf = initBuffer(gl.ARRAY_BUFFER, vtx);
            ibuf = initBuffer(gl.ELEMENT_ARRAY_BUFFER, idx);
            gl.vertexAttribPointer(shaderProgram.aposAttrib, 3, gl.FLOAT, false, 0, 0);
        }

        function unbindBuffers() {
            gl.bindBuffer(gl.ARRAY_BUFFER, null);
            gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
        }

        function onready() {
            initGl();
            initShaders();    
            initScene();
            //#
            var vtx = new Float32Array(
                [-1.0, -5.0, -5.0, 
                5.0, 5.0, 5.0]
            );
            var idx = new Uint16Array([0, 1]);
            initBuffers(vtx, idx);
            gl.lineWidth(1.0);
            gl.uniform4f(shaderProgram.colorUniform, 0, 0, 0, 1);
            gl.drawElements(gl.LINES, 2, gl.UNSIGNED_SHORT, 0);
            //#
            unbindBuffers();
        }

    </script>
</head>
<body onload="onready();">
    <canvas width="400" height="300"></canvas>
</body>
</html>

As you can see code necessary to draw a line is put inside //# in onready function. What that code does? First is array of 6 numbers representing 2 points with 3 coordinates (X,Y,Z). Second array is just indexes for points from first array. We want draw line from first and second point so it is just 2 numbers: 0 and 1. After initializing buffers with those arrays, we are defining width of our line. Next is defined color of our line and lined is drawed to scene. Pretty straightforward. It will give something like in image below.

Live example and code for this you can get here.

What we can change in this code?

First color. It is just rgba format in range from 0.0 to 1.0. You can also add more points to draw now single line but whole path. Great! What about width of line? This is sadly not working how you would want it to. In mozilla you can set whatever value you want and width still be constant. Why?

Answers can be found in OpenGL ES specification:

"There is a range of supported line widths.  Only width 1 is guaranteed to be supported; others depend on the implementation. To query the range of supported widths, call glGet with argument GL_ALIASED_LINE_WIDTH_RANGE"

So if you are in browser development just implement line with width = 1 and you are done. Not very helpfull. So if you are looking into using this part of WebGL extensively I bet you will write your own library for lines anyway.

Just out of curiosity I have tried to 'query range' of available widths:

gl.getParameter( gl.ALIASED_LINE_WIDTH_RANGE)

and not for big suprise I got this:

 
So... range is from 1 to 1. Not very wide I must say (I tested it in FF 18.0.2).
 
I wanted to have control of width of my lines so I ended up doing it on my own. Next time I will write how I complished that.


Cartezian coordinate system in HTML 5 canvas

clock February 23, 2013 14:35 by author n.podbielski

Normally canvas 2D context is using custom coordinate transform where Y coordinates are flipped vertically. Here is image with example (taken from http://diveintohtml5.info/canvas.html; it is great book and you should read it Smile)

 

It is a bit inconvinient to use if you are drawing some shapes with points given in classic Cartezian coordinate system.

It is convienient that we can change it with setTransform function of canvas context object. How? It is pretty easy:

__context.setTransform(1, 0, 0, -1, 0, currentHeight);

where __context is canvas context and currentHeight is actual height of a canvas element.

I used this in my little library for drawing 2d graphs, which I described in mine previous post http://internetexception.com/post/2013/02/16/Simple-2D-graphs.aspx. You can see example of this little snippet in action right there.

I hope this will help someone. Smile



Simple 2D graphs

clock February 17, 2013 02:26 by author n.podbielski

While writing application for my Masters Degree diploma I was required to came up with simple library for creating simple 2D graphs in the browser. Today I decided to share it with the rest of the world. Smile

My lib uses HTML5 tag canvas and jQueryUI library, which is used for creating dialogs for every figure.

Using is really simple. All you need to have is some data in four arrays:

XAxis - it's array with 2 values, start and end of XAxis range. Those values are also drawn as a legend for X values

XData - it's just array of X values

YAxis - same as XAxis but for Y axis

YData - Y values

It's important to have same number of items in XData and YData arrays. But it's common sense anyway. Smile

Those 4 arrays are values of object, figure representation in JS. This object should also have Type property with value 'line'. This is because I am planning to have unified start point for drawing 2D and 3D graphs. About three dimensional graphs I will post soon.

Object for single figure should look something like this:

{ Type: 'line', XAxis: [0, 1], XData: [...], YAxis: [0, 1], YData: [...]}

This is one figure, but my library can show multiple graphs at once so this figure-data-object must be added to dictionary. Keys from this dictionary will also serve as figure names and canvas ids so this cannot be anything that also is not permitted as DOM element id.

Dictionary with single figure named 'Test1' should resemble following example:

{ "Test1": { Type: 'line', XAxis: [0, 1], XData: [...], YAxis: [0, 1], YData: [...]} }

Dictionary with figures data should be send as param to figures figuresDrawer.draw function. And that is all you need to know before start using my library.

As a example I written JavaScript white noise generator Smile:

$(function () {
            YData = [];
            XData = [];
            length = 100;
            for (var i = 0; i < length; i++) {
                YData.push(Math.random());
                XData.push(i / length);
            }
            figuresDrawer.draw({ "Test1": { Type: 'line', XAxis: [0, 1], XData: XData, YAxis: [0, 1], YData: YData} });
        });

As result we will see graph in jQueryUI dialog:

 

For more configuration of graph you can change values in figuresConfig.js file.

As jQueryUI library allows to resize dialogs, graphs can be resized to. In this config file you can choose default values of width and height of new dialog.

this.default2dHeight = 400;
this.default2dWidth = 600;

'partialCanvasId' values is just template for graphs canvas tags ids. You can change it, but it has not impact on graphs functionality. I decided to put this here because I needed it in one place for 2D graphs and 3D graphs.

More interesting configuration values are in Figures2d.js file.

__axis_numbers_size  - size of font for drawing axes ranges

__axis_numbers_style - here you can change font of those numbers

So  changing code to:

var __axis_numbers_size = 20;
var __axis_numbers_style = __axis_numbers_size.toString() + "pt Times New Roman";

will set font to 20p size Times New Roman font.

 

Next 4 variables are colors of:

__figure_bg_color - background color for axis ranges description; in image above it's gray strips around graph space itself.

__figure_grid_bg_color - this is background color for graphs space; white color above

__axes_color - it is color of axes lines, color of black rectangle separating gray strips and white graph space, but it is also color of axis numbers

__plot_color - color of plot lines; blue color in example

 After cnahging code:

var __figure_bg_color = "black";
var __figure_grid_bg_color = "gray";
var __axes_color = "White";
var __plot_color = "#FF0000";

we can  see black figure background with white axes and red plot lines on gray background.

 

You can change it but I think that default are much nicer Smile

 Another thing that can be worht mentioning is that after resizing graphs are redrawn after some time after resizing. Without it it would looking strange because resizing of drawn canvas tag work like resizing an image. You can try this for example resizing to small window (it will be not readable in that size), and then again to bigger dialog window (when you will see eventually big pixels with lite smooth effect). After 2 seconds graphs will automatically resize itself to stretch to new size.

I understand that there are plenty of better libraries for this, but maybe this one will suit somebody. It's really simple and lite, less then 300 lines. And without jQueryUI which can be slow sometimes it could be really fast. And it can starting point for someone that would want to write something on their own.

 

2Dgraph2.zip (190.06 kb)



Curious Case of Visual Studio project compatibility.

clock February 12, 2013 08:06 by author n.podbielski

Recently I was asked at work for quick review of small project. It was created (or updated) in newest version of Visual Studio - 2012. I don't have installed VS 2012.

I could install it, yes, but it would be just waste of time since browsing through code in that project took me only few hours.

So I decided to try to open that in VS 2010.

It was not surprised that didn't work entirely. I was expected that I won't have possibility of building it - .NET 4.5 was not even installed on my machine. But to see "incompatible" next to project name was surprise to me indeed. It was strange I was suspecting that lack of .NET 4.5 binaries could cause that. But installation of framework did not help. I still was seeing this:

 

That is strange. I would thought that Microsoft at least would allow me to browse through files and see contents of project. I guess they would try every little thing they can to sell they newest software Smile.

So I thought to try to open this project in version 2008. Just for fun and this was surprised it worked Cool. I even get message 'build succeeded' when I tried it, but I have to mention that was only once and after opening files with errors (non existent namespaces and classes) it no longer worked Smile. But it was ok since I was only required to look at the code inside.

After 'build succeeded' info I tried to open project properties of project and get this:

 

 

So if project had no framework at all it could skip building entirely and since there was not errors It succeeded Smile

Nevertheless I done my work using VS2008.

Why Microsoft would block something in VS2010 and no in 2008. Maybe users of second are considerably less numerous so it was just to expensive to do such thing.



Why I don't like Python anymore.

clock February 7, 2013 06:45 by author n.podbielski

It was few years back on my first year of studies, when my friend told me about Python. Then it was great for me. One-liners could read ftp folders, web pages, interact with operation system, list comprehension, injecting code into life programs, nested functions, procedural as object oriented programming styles etc. etc. All of this in bultin libraries with simple but yet quite functional editor, supported with great documentation. I wrote my first studies project in Python and I was proud with it a little Wink. During next years I was using Python for writing simple scripts to automate my proffesional work as PHP programmer. Python was and I still think is better language then PHP. After that I started to work as .NET/C# developer. It has diffrent syntax but C similarities let me to learn it quite quick. Framework .NET is powerfull tool also so I didn't touch Python for 2 or 3 years at least for anything longer then few lines.

But a week or so ago I decided to write a simple script to automate reading whole RSS channel. I wanted it to filter it for only those news that I was interested in. I decided to use Python for it. I was considering also PowerShell since it is bultin into Windows and it an benefit from .NET. But I don't like it's weird syntax, and since I wanted to just write this script and not struggle with syntax errors I chose Python. I don't want to say that I made an mistake. I still powerfull language and I manage to write this script quickly, but... there was some misunderstanding. Maybe I am more experienced. Or spoiled with C#, or used to it. Or just picky. Nonetheless I decided to share this with the world.

 

One of this things was global versus local scope clash. I probablye would get over it if not other things.

Let us consider little program like this:

global_var= 1

def func_with_local_scope():
    print(global_var)

func_with_local_scope()
print(global_var)


I does really simple thing: prints value '1' two times. Despite the fact that func has it's own local scope aside from global scope, it will work cause interpreter will think about as 'global_var' variable as global. It is correct behavior. Now let is change a bit:

global_var= 1

def inc():
    print(global_var)
    global_var+=1

inc()
print(global_var)

And... it will fail. Why?

  File "test.py", line 4, in inc
    print(global_var)
UnboundLocalError: local variable 'global_var' referenced before assignment

My first reaction was: "Huh?" How it is not assigned? It is done right before this function. Let's inspect scopes inside 'inc' function:

GLOBALS:

{'__name__': '__main__', 'global_var': 1, '__package__': None, '__doc__': None, 'inc': <function inc at 0x00000000031EC488>, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__file__': 'F:\\skrypty\\music_rss\\test.py', '__builtins__': <module 'builtins'>}

LOCALS:

{}

 

It is perfectly fine! Our variable is defined in global scope and it has value! And local scope is empty since I did not declared any local variables. Why system that is resolving variables names do not check for global scope when it is trying to find value? Because doing any assignment in function tells interpreter that this variable WILL be assigned in function and without declaring it with 'global' keyword it WILL be local variable. I know that. I understand that. And I think that is inconsistent and it should be done better. I would agreed to use always 'global' keyword or always not using and just letting interpreter do the job. Either way would be fine since it is consistent and desinger of the laguage decided to this that way. I his call. I could not be ideal but it would be intuitive.

Let's do one test:

global_var = 1

class Incrementer:
    print(global_var)
    global_var+=1
    print(global_var)
    def inc(self):
        print(global_var)
        print(self.global_var)

i = Incrementer()
i.inc()
print(global_var)

When I was writing this I was expecting it to fail with my knowledge of scopes in functions. But I also was suspecting that this actually might work and I will find more scope inconsistencies. And there it is. I work just fine. I mean it run but it certainly do that like Spanish Inquisition. Result will be:

1
2
1
2
1

First '1' is print(global_var) inside class declaration. Despite the fact that variable with this name is defined later in class and since this would cause an error in function I would expect it to fail here also. Here comes another 'Huh?'. Instead it is resolved to global variable.

Second print is done after incrementing variable with the same name. Which is it? It is global variable? Or it is new local class variable? If code would be end here it would be good, tricky question for interview for Python job (maybe it is I don't know). Simple programmer like me would expect (if you reference variable with the same name in the same way it SHOULD be the same variable). No. It is not.

Third print show that to us. It is global variable with the same name and it is still simple '1'. Doing incrementation in class scope of global variable (as I would expect) creates new local class variable and assign to it value of global variable PLUS one. How in hell this is incrementation?

Forth print shows us value of two and actual place of incremented value. It is know in class variable with same name as global variable. I will call this inrementation with displacement. Python-like.

Last print shows us global unchanged variable. It still there, not touched.

Uhm... I don't know. Maybe this is explained somethere in documentation. Maybe it is logical somewhere in bowels of interpreter. Or whatever magic thing make this work. I don't know. I don't have time and will to dig in few hundres pages of documentation for specifics of inner workings of something so basic like arithmetical operators. And frankly I don't care. Throw and error, when you trying to increment value that is not there - like C. Resolve it to global variable like in JS. Prevent to name the variable just like another variable in scope level above - like C#. Just pick one please. And be consistent.

Another one exist only in Python 3, contrary to previous. It begins with decision that all strings should be unicode. That is great. Resolving encodings is pain in the ass. But... console have it's encoding too. I don't know how this work in other systems then Windows but I suspect it's problem too since when googling for answer I found that in happened not only to me. So what happens when you get some unicode char that can't be encoded in console specific encoding? It suppose to show some not readable characters like │┐čŠč╣˝ˇ│ or just ? sings, don't you think? No. It throws exception. Program crash. End of story. It is command line. It is tool to interacting with users. If user will have to make something from information that 10% of it is giberish that is bad not it is not critical. When application is throwing an error when encoding string to some specific encoding when saving data to for example to DB, it probably be desired to throw error. But not in output! It is even more horrible because writing an app in Python you cannot know for sure what will be user interface encoding so you cannot be prepared on anything with tool like this.

So script below will work fine in Python Shell fine and will fail in cmd.exe:

string = 'показано'
print(sys.stdout.encoding)
print(string)

With exception like that:

  File "C:\Python33\lib\encodings\cp852.py", line 19, in encode
    return codecs.charmap_encode(input,self.errors,encoding_map)[0]
UnicodeEncodeError: 'charmap' codec can't encode characters in position 0-7: cha
racter maps to <undefined>

I added line print(sys.stdout.encoding) so I know that Python internally know what encoding is in output. This can be used to do something like this BEFORE print:

string.encode('cp852','replace')

so every char that can't be encoded will be replaced with something else. But why this cannot be done inside print? Why print at least cannot have another param to silently pass encoding errors?

Another one that is connected with 3 version. In previous releases I used Python to debug http response of websites. It was really nice tool for it with set_http_debuglevel method of HTTPHandler class.

send: 'GET / HTTP/1.1\r\nAccept-Encoding: identity\r\nHost: www.wp.pl\r\nConnection: close\r\nUser-Agent: Python-urllib/2.7\r\n\r\n'
reply: 'HTTP/1.0 200 OK\r\n'
header: Server: aris
header: Expires: Thu, 07 Feb 2013 21:21:24 GMT
header: Last-Modified: Thu, 07 Feb 2013 21:21:24 GMT
header: Pragma: no-cache
header: Cache-Control: no-cache
header: Content-type: text/html; charset=UTF-8
header: Set-Cookie: reksticket=1360272084; expires=Sat, 09-Feb-2013 21:21:24 GMT; path=/; domain=.www.wp.pl
header: Set-Cookie: rekticket=1360272084; expires=Sat, 09-Feb-2013 21:21:24 GMT; path=/; domain=.wp.pl
header: Set-Cookie: statid=89.71.103.226.25161:1360272084:324990297:v1; path=/; expires=Sun, 07-Feb-16 21:21:24 GMT
header: Set-Cookie: statid=89.71.103.226.25161:1360272084:324990297:v1; domain=.wp.pl; path=/; expires=Sun, 07-Feb-16 21:21:24 GMT
header: Content-Length: 94719
header: Connection: close

It not working in Python 3:

import urllib.request

h=urllib.request.HTTPHandler()
h.set_http_debuglevel(1)
b=urllib .request.build_opener(h)
a=b.open('http://www.wp.pl').readall()

This feature was not documented as far as I know. I have found this in 'Dive in Python' book (http://www.diveintopython.net/). I suspect this was to non important to keep maintaint it in new versions. So much that it was not even removed.

I could go on with lack of nice function for handling dates and time. Or 'self' (non)keyword inside class declarations. But this rant is long enough as it is. Maybe I will write another script in PowerShell, after fighting with syntax it will be more usable for simple scripts.
 



Using Matlab from C# application.

clock January 20, 2013 11:25 by author n.podbielski

While writing an application for my Masters degree diploma, I wrote a simple application that was using COM Matlab server. I have found it hard to use it mainly due to lack of documentation, which is really basic with only few code examples for C#. I guess writing programs that use Matlab for calculating is not encouraged by MathWorks, you would became competition that way Smile. Nonetheless, I accomplished why I was required to do, so I decided to share this with the rest of the world.

Important: I was using R2010a version of Matlab. I realize that there is a newer version. But I had only this version at my disposal. Since interface for communicating with Matlab server is dependent on installed Matlab version and registry entries, it may have been different from yours. But I suspect not too much. I also tried with 7.1 and (if I remember correctly) it required only to swap reference in Visual Studio. But again... it was only a test so there might be other problems that I am not aware of.

Let's start with a simple console application. Let's call it MatlabTest. First, we will add DLL reference with COM interface. Click RMB on project and choose [Add Reference] option. In new window, click COM tab. In search text box, write 'Matlab'. Then choose "Matlab Application (Version 7.10) Type Library".

You should get a new reference like below:

Great. Now we should test if it is working. In order to use it, we should create our Matlab server from C# application. To do that, we can add code to our main program:

var activationContext = Type.GetTypeFromProgID("matlab.application.single");
var matlab = (MLApp.MLApp)Activator.CreateInstance(activationContext);
Console.WriteLine(matlab.Execute("1+2"));
Console.ReadKey();

This code will create a single Matlab COM server through Activator class. Program Id "matlab.application.single" means single Matlab COM server for our application. When it will try to create another Matlab, it will just return a reference to the same object. Contrary to that, we could use "matlab.application" which will create another instance of Matlab anytime Activator.CreateIntance method will be executed. In more complex applications or for web applications or other programs which run for a long time, it may create big memory leaks since 1 instance costs around 220 Mb (on 64 bit Windows 7 and Matlab R2010a).

After creating Matlab program, execute a simple sum of 2 integers, just for testing communication - we don't need anything more sophisticated. It should return also a simple string in console:

It's really simple and more importantly, it works! Smile

This way, we can send and receive string messages with MATLAB only. It's not very useful. Also, there is one way to find out if our statement had errors. It will have 'error' string in response.

Let's try to run something like this: '1*', which will result in error:

So to check our command had errors, we have to check if output string has "??? Error" in it.

To send some parameters along with our command, we have to use one of 'Put*' methods. Best is one called PutWorkspaceData. It takes three parameters. First is the desired name of our new Matlab variable. Two others are much more tricky. To set variable correctly (so you could reference it in command), you must use global workspace. But it is called? This one took much more time than I would want. It is not mentioned in the documentation of this method. If I remember it right, I found it in some code example and it should be only "base". In the end, I created in my application another method that encapsulated PutWorkspaceData and forgot about it Smile. The third parameter is the value of our variable. It should be simple. Let's change our code to:

matlab.PutWorkspaceData("a", "base", 2);
Console.WriteLine(matlab.Execute("a*a"));

The result will be as shown below:

But it is just int. What about more complicated structures? How about multiplication of two vectors? Matlab is using .NET type double to send and receive information with our application. Again, I did not find it anywhere in the documentation, but rather reverse engineered this from data returned from Matlab. So let us try to send 2 arrays of doubles. and multiply them in Matlab. First will be named 'a' and second 'b'. Matlab command will be "a'*b". Transposition will give us a nice matrix instead for a single number.

matlab.PutWorkspaceData("a", "base", new[]{2d,3d,1d});
matlab.PutWorkspaceData("b", "base", new[]{4d,3d,2d});
Console.WriteLine(matlab.Execute("a'*b"));

And in return we will get:

Next step will be to return this output to our console app. To do that, we can use GetWorkspaceData that works similar to PutWorkspaceData or... we can use GetVariable method. This one returns dynamic so our application needs to run on .NET 4. It takes two parameters - name of variable we want to return from Matlab and again name of workspace. You really should save this string as const somewhere Smile. Change our code to:

matlab.PutWorkspaceData("a", "base", new[]{2d,3d,1d});
matlab.PutWorkspaceData("b", "base", new[]{4d,3d,2d});
Console.WriteLine(matlab.Execute("c=a'*b"));
var c = matlab.GetVariable("c", "base");

After that, in our console app, we will have variable c and it will be a two dimensional array of doubles. To show values of this array in console, we can just iterate it with a simple foreach loop. But instead of that, we will iterate two of the dimensions. This will give us information about values and dimensions of this matrix.

for (var i = 0; i < c.GetLength(0); i++)
{
   for (var j = 0; j < c.GetLength(1); j++)
        Console.Write(c.GetValue(i, j) + " ");
   Console.WriteLine();
}

Ok.That was matrix. How about vectors? Luckily, vectors are for Matlab just a special case of matrix so it will spit out two dimensional array also. More complex is the case of empty matrix. No, it is not null. It would be too easy. Instead, it is a special type Missing. I guess it has some logic behind. Null would indicate that variable will have no value at all or this is not defined. But we have an empty matrix, so this is not defined nor is this a lack of value. So why not just array with zero values in it? No idea.

Let's try to run code like below to test it:

Console.WriteLine(matlab.Execute("c=a'*b"));
Console.WriteLine(matlab.Execute("d=[]"));
var c = matlab.GetVariable("c", "base");
var d = matlab.GetVariable("d", "base");
for (var i = 0; i < d.GetLength(0); i++)
{
   for (var j = 0; j < d.GetLength(1); j++)
      Console.Write(d.GetValue(i, j) + " ");
   Console.WriteLine();
}

Running those commands in Matlab will work just fine. Instead of that, error will be thrown on first for loop:

Not very nice. To prevent this error, the application will have to check if dynamic type returned from matlab is in fact empty (Missing). Not very clean it is better to wrap this in other method that will perform this check for us whenever we want to get our data from Matlab. In my project, I ended up writing few methods for returning vectors, matrices, numbers, strings, etc. Vector one looked like this:

public static Vector GetVector(this MLApp.MLApp matlabComObject, string variabla_name)
{
    var dynamicVariable = matlabComObject.GetBaseWorkSpaceVariable(variabla_name);
    var dataList = new Vector();

    if (TypeChecker.IsVector(dynamicVariable))
    {
        dataList = Vector.DynamicToVector(dynamicVariable);
    }
    else if (TypeChecker.IsNumber(dynamicVariable))
    {
        dataList.Add(dynamicVariable);
    }
    else if (TypeChecker.IsEmptyMatrix(dynamicVariable))
    {
        //do nothing empty vector or matrix ([0x0] or [1x0])
    }
    else throw new Exception(string.Format(
      "Type of dynamic variable ({0}) is not supported!", dynamicVariable.GetType()));
    return dataList;
}

TypeCheker checks for type of dynamic. It's pretty straightforward. For our Missing type, it's just one line:

public static bool IsEmptyMatrix(object dynamicVariable)
{ return dynamicVariable.GetType() == typeof(Missing); }

After checking type of dynamic, we can just cast it to another type to take advantage of static properties of language. Why use dynamic at all? First, I think that ref and out method parameters are messy and second: I prefer:

var d = matlab.GetVariable("d", "base");

from:

object e;
matlab.GetWorkspaceData("d", "base", out e);

It is only 1 line. And since object you have to create first and then cast it also, don't bother and just use dynamic. But I guess it is just what you will like better.

Strings are much more friendly and there are just string. Or null. Smile

Now we know how to put and get data from Matlab. How to execute commands and check them for errors.

If you executed any of these examples, you probably took notice of a very simple Matlab window which had opened during the life of your console app. If you terminate it by disabling debugging or it will close due to error, Matlab window will remain opened. If not, it will close nicely with console window. But still, it is a huge memory leak risk if not maintained properly. To that, I recommend creating some special class that will create an instance or instances of Matlab. It should track one of the created instances and in case anything bad happens (but dynamic variable cast is probability Smile), it will close all instances prior to application exit. Tracking should be employed through WeakReference class, so whenever Garbage Collector would want to destroy Matlab instance, it should not be stopped by our tracking class. To destroy COM instance, we can use method Marshal.FinalReleaseComObject. So with weak reference code for that will look like this:

public static void Release(WeakReference instance)
{
    if (instance.IsAlive)
    {
        Marshal.FinalReleaseComObject(instance.Target);
    }
}

Method Quit of matlab server instance does not close it immediately and the code above will.

If you want to hide that popup Matlab window, you can set this in its instance:

matlab.Visible = 0;

This way, it will fade away and run as service.

This is the most basic information about Matlab in C#, but it will get you started. So happy coding! Smile



Server controls in separete assembly part 2

clock December 24, 2012 05:14 by author n.podbielski

Yesterday I was writing about creating server controls in separete assembly. Today I will cover more complicated example then simple "Hello World!" control. My goal was to create text box that will take handler method to run when validation event will be triggered, and when validation fail will show approriate messege. Text box with bultin validation would be nice, since you always should validate user input, right? But lets start creating our control.

First create new control named TextBoxWithValidation.ascx in our yesterday web site WebSite1 project.

 

Lets now fill it with some html code.

<span>
    <asp:TextBox runat="server" ID="tbText" OnTextChanged="tbText_TextChanged"></asp:TextBox>
    <asp:CustomValidator runat="server" ID="cvValidator" ControlToValidate="tbText" 
        OnServerValidate="cvValidator_ServerValidation"
        EnableClientScript="false"
        ErrorMessage="Dummy text error message" 
        Display="None" ValidateEmptyText="true">
        <%--validator must have ErrorMessage string--%>
    </asp:CustomValidator>
    <div class="ui-widget validation-error" id="divValidationContainer" runat="server"
        visible="false">
        <div class="ui-state-error ui-corner-all">
            <span style="float: left; margin-right: .3em;" class="ui-icon ui-icon-alert"></span>
            <asp:Label ID="lValidationMessage" CssClass="validation-message" runat="server"></asp:Label>
        </div>
    </div>
</span>


This HTML is using some CSS classes as it some HTML code from jQueryUI. So it will be good if you grab newest version from http://jqueryui.com/.

 You can ofcourse use you own html for validation error message.

ASCX file contains 2 ASP.NET controls, text box and custom validator. Validator will be validating value of our text box by custom handler assigned from external page or control. We are setting ErrorMessege property with "Dummy text error message" because validator would not run validation event without it. It's some kind internal logic in .NET Framework. That's why we set it to 'dummy' to in case some um... error it would display some hint that there is something wrong with validation, and this is not validation message. Lets jump to .cs file.

 

public partial class TextBoxWithValidation : System.Web.UI.UserControl
{
    public string Text
    {
        get
        {
            return tbText.Text;
        }
        set
        {
            tbText.Text = value;
        }
    }

    public bool IsValid
    {
        get
        {
            return cvValidator.IsValid;
        }
    }
    
    public string ErrorMessage
    {
        get
        {
            return cvValidator.ErrorMessage;
        }
        set
        {
            cvValidator.ErrorMessage = value;
        }
    }

    public event ServerValidateWithMessageEventHandler ServerValidate;

    protected void cvValidator_ServerValidation(object source, ServerValidateEventArgs args)
    {
        if (ServerValidate != null && Visible)
        {
            var argsWithMessage = new ServerValidateWithMessageEventArgs(args);
            ServerValidate(source, argsWithMessage);
            argsWithMessage.ToServerValidateEventArgs(args);
            divValidationContainer.Visible = !argsWithMessage.IsValid;
            if (!argsWithMessage.IsValid)
            {
                if (string.IsNullOrEmpty(argsWithMessage.ErrorMessage))
                {
                    lValidationMessage.Text = cvValidator.ErrorMessage;
                }
                else
                {
                    lValidationMessage.Text = argsWithMessage.ErrorMessage;
                }
            }
            else
            {
                lValidationMessage.Text = "";
            }
        }
    }
}


First we are making proxy of properties IsValid and ErrorMessage, and also of property Text of TextBox. They will be handy in future Smile

Next are public event for text box value Validation ServerValidate and protected function that will run this event cvValidator_ServerValidation. Argument of this method args is defined as below:

public delegate void ServerValidateWithMessageEventHandler
            (object source, ServerValidateWithMessageEventArgs args);

public class ServerValidateWithMessageEventArgs : ServerValidateEventArgs
{

    public ServerValidateWithMessageEventArgs(ServerValidateEventArgs args)
        : base(args.Value, args.IsValid)
    { }

    public string ErrorMessage { get; set; }

    internal void ToServerValidateEventArgs(ServerValidateEventArgs args)
    {
        args.IsValid = IsValid;
    }
}

In this argument in parent control or page we can set ErrorMessege property and will obtain IsValid property value after event execution will complete. In control method cvValidator_ServerValidation we will also show or hide our custom validation message depending if value of text box is valid or not.

Let's try it out. We will publish WebControl project, and add reference to this new control by adding App_Web_textboxwithvalidation.ascx.cdcab7d2.dll file. Next add another line to web.config like yesterday:

<add tagPrefix="WebControls" namespace="ASP" assembly="App_Web_textboxwithvalidation.ascx.cdcab7d2" />


Now we can add our new control to page:

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <link href="JqueryUI/css/redmond/jquery-ui.custom.min.css" rel="stylesheet" type="text/css" />
    <link href="jQueryUI.Validation.css" rel="stylesheet" type="text/css" />
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <WebControls:helloworld_ascx runat="server" />
        <WebControls:textboxwithvalidation_ascx ID="test" runat="server" ErrorMessage="testMessage" OnServerValidate="test_ServerValidate" />
        <br />
        <asp:Button runat="server" Text="Validate" />
    </div>
    </form>
</body>
</html>

with some button to trigger postback and some method to validate:

        protected void test_ServerValidate(object source, ServerValidateWithMessageEventArgs args)
        {
            if (args.Value.Length > 5)
            {
                args.ErrorMessage = "Value is too long!";
args.IsValid = false; } }

 

As for styles first is standard jQueryUI redmond theme css file and second is custom css for jQueryUI theme which places validation message right from text box as popup with nice eye-candy effects Smile:

/*validation*/
.validation-error
{
    display: inline-block;
    position: absolute;
    z-index: 1000;
}
.validation-error .ui-icon-alert, .errorResultContainer .ui-icon-alert
{
    float: left;
    margin-right: .3em;
}
.validation-error .ui-state-error
{
    padding: 5px;
    box-shadow: 5px 5px 5px #888888;
}
.validation-error .validation-message
{
    display: none;
    position: relative;
    text-shadow: 2px 2px 2px activeborder;
}
.validation-error:hover .validation-message
{
    display: block;
}
.validation-error:hover
{
    z-index: 1001;
}
.ui-icon-alert
{
    float: none !important;
}

After running our project and clicking on button when value of text box is longer then 5 chars we will se validation popup:

 

 

when you hover on popup you will see error description:

 

 

You can validate value for more then one constraint. Just remember to set ErrorMessage property and IsValid property to false of args parameter. That is all.