theKindOfMe

July 19, 2009

Sri Lankan Online Shopping Sites Selling Computers and related stuff

Filed under: Uncategorized — yasi8h @ 9:59 am

There are only a few online shopping sites here in lanka that sells computer related stuff. and even within those sites only a very few are actively maintained. i am compiling a list of sites here, as i didn’t find a list anywhere else(i asked google). these consists of sites that actually let you buy online and the ones that only publishes a price list.

If you know any more sites please let me know(put a comment please).

Online Shopping Sites

http://www.memory.lk

As the name sugguest this one sells all things memory related. mostly(if not exclusively) everything they have is kingston.

http://www.laptop.lk/

Has a lot of stuff. looks like a well maintained site. but the web designing is… errr let’s just not talk about that. pricing seems ok.

http://www.slmega.com

This seems to be the only decent online shopping site over here. but then it too can improve a lot. i feel that their prices are a bit high, at least on some items. still have a huge list of products and they will virtually import anything from USA to SL. neat, but expensive.

http://winsoftsl.com

Don’t know much about these guys. they are located in unity, have been there for a while. the site looks ok. can use as a price list/ product catalog…etc.

http://www.abc.lk – this is down

Has a good set of products. this is a online shop front and it looks pretty ok. They has a lot of Apple products as well so if you are looking for something Apple don’t forget to look here.

http://www.techgsmsl.com

has a limited product range but the site seems to be updated and maintained.

http://www.barclays.lk/

ultra slow site. badly designed(oh well almost every site in this list is badly designed. basically they suck. but still its better than not having a site at all). have a good range of usual products. prices seems ok.

http://www.ibuy.lk

This is an online store run by Dialog. they do have some computer realted stuff for sale. Asian Computer Systems are offering the products. The range of products is pretty limited though.

http://www.computer.lk

have a decent range of products. prices seems to be a bit high… may be they weren’t updated in a while 🙂

http://www.epsi.lk/

If you want something Asus this would be a good place to look in. but most of their products are not in their web site’s product list. they don’t have a price list their either. but they do have a catalog of products. prices tend to be very high with epsi.

http://www.istore.lk

EPSI’s Apple wing. you can find iPods, iMacs…. with their local prices on this site. it’s usual for Apple products to be high priced 🙂 but when you buy them off epsi its even more high priced. i don’t know may be they are keeping a  huge profit margin.

http://www.bhavik.com/techwarehouse

This is another new site on the block. well it’s domain name looks fishy to me… whatever the products mainly compose of Asus stuff(em… i thought EPSI was the Asus distributor for SL). prices are high… but this one has a decent web application running.

http://www.nunet.lk/

Has some good high end vga cards, memory and foxconn mother boards. you should check them out if you are out to buy something for your gaming rig.

http://www.eglobesl.com

A bit Gamer and Server side hardware supplier. expect the prices to  be higher.

http://www.sh-technologies.com/

This one looks more like web site! 🙂 Have gaming accessories, laptops and laptop skins. Some sections are still under development. its not an online shop, just list the products with their prices.

http://www.salaent.com

Have a decent amount of Chinese/Taiwanese…etc brands. and obviously the prices are cheaper for these goods. these guys do Prolink stuff in SL. they aren’t a online shopping site but they do have a product listing on their (crappy) site.

http://www.digitalhouse.lk

Has a lot of Mercury products. and other stuff. Either this site is not updated as of date or their prices are too high.

http://www.metropolitan.lk

Have some computer related stuff like printers and scanners…etc. this is not an online store just a products listing.

http://www.futureworld.com.lk

All Apple here. looks fine. Just a products listing, no online store.

http://www.buyabans.com/phones_computers.php

yeah it’s Abans. they have a decent set of products, prices aren’t cheap. they do have some logitech gaming gear. worth a look if you are on the lookout for something.

www.lankanet.org

don’t have a lot of products but still worth looking in to. contain a price list no online store.

Junk Sellers

these sites are of companies that sell used computer/parts.

http://www.japansoft.tk/

www.microdevices.lk

http://www.usedcomputer.lk – Caution: You might vomit when you see this site. It has such a horrible look and feel.

Other

http://www.thesrilankantechguide.com

nice site! this site sort of integrates price lists from different sites together and try to provide us a with a unified set of products available in sri lanka. good effort. hope these guys can add more stores.

that’s it. there is a lot of space available for a decent site in this market segment. the ideal site would provide us customers with a wide range of products for decent prices. and also a decent web application that let us sort/search/filter/links to reviews and ratings from other sites…etc. they could do the distribution via some trasnport service, i don’t know. or else they can have a store front in colombo. let’s hope that one day we lankans will have something like newegg or atleast a decent auctioning site like ebay 🙂

Advertisements

July 10, 2009

Ever got a exception like “_COMPlusExceptionCode = x” in .net?

Filed under: Uncategorized — Tags: , , — yasi8h @ 6:05 am

In Short:

if you ever get a exception like “_COMPlusExceptionCode = x” in a .net application while you are debugging it in visual studio, look at the following screenshots.

Long Story:

While working on a asp mvc project i got a exception when the EF was trying to save some changes to the db. so i examined the exception object via visual studio’s visual aids. it said _COMPlusExceptionCode = -532459699 ! now what is that?

complusexception while debugging in visual studio

complusexception while debugging in visual studio

after some googling… i felt a bit lost. but by accident i came across the following error message in the same application, in the same line no, for the same exception. a usual ‘exception icon’ or whatever you call it.

a exception icon displayed in visual studio

a exception icon displayed in visual studio

now when i click on that…

visual studio exception infomation dialog been displayed for a update exception

visual studio exception infomation dialog been displayed for a update exception

viola! there is my exception. it seems that visual studio decodes these COM Plus Exception Codes to meaningful exceptions. but at times its easy to miss this way of viewing the exception.

July 1, 2009

Using Custom T4 templates To Generate Better Controllers in ASP MVC

Filed under: Uncategorized — Tags: , , , , — yasi8h @ 7:52 am

While working on this asp.net mvc project at work i couldn’t help notice that there are lots of code that is getting copy-pasted from one controller to the other, when i am adding a new controller. now as you know mvc fm comes with a set of T4 templates that lets you add views and controllers in such a way that some code in these views and controllers are generated for you. this is grate. but you can customize the original templates to your needs and make them generate more of the code for you. (please note that i am talking about controllers that are responsible for mostly CURD on a given single model.)

First of all you will need to identify what code gets repeated from controller to controller in your asp.net mvc project. and then you can get these stuff out in to a template and start working on it.

Locating the T4 Templates

you can find your original templates in [Visual Studio Install Directory]\Common7\IDE\ItemTemplates\[CSharp | VisualBasic]\Web\MVC\CodeTemplates\ and the you can copy them to your project folder. you can start editing these copies and they will be used when you invoke your templates(ex:- by clicking on the Add Controller sub menu within the IDE). for more info please refer to T4 Templates: A Quick-Start Guide for ASP.NET MVC Developers )

Customizing

In my case i wanted my controllers to have all the basic actions like List, Details, Create, Edit and my custom actions like Grid, GridData(take a look at A Grid with Ajax/Pagination/Sorting/Filtering on ASP.net MVC with ExtJS and Enitiy Framework).

i needed to get the type of the model that a given controller is associated with. and then i have to traverse it’s properties(through reflection…etc) and do some string manipulation to generate custom method signatures and custom anonymous types. i also wanted to filter the list of properties that will be used in these parameters and anon types.

Action method signatures

action method signatures can be different from controller to controller. as in…

//Different Properties, in different models
//
//Create action of a Product Controller
public ActionResult Create(string ID, string Name, string Description, string Price)
//
//Create action of a User Controller
public ActionResult Create(string ID, string Name, string Age)

//Different Primary Keys in different models
//
public ActionResult Details(int UID)
//
public ActionResult Details(int UID, int SiteUID)

Method calls to models

//Different Primary Keys
//
public ActionResult Details(int UID)
        {
            return View(Category.GetModelByPrimaryKey(new {UID}));
        }
//
public ActionResult Details(int UID, int SiteUID)
        {
            return View(Category.GetModelByPrimaryKey(new {UID, SiteUID}));
        }

//Different Properties for different models
//
public ActionResult Create(string ID, string Name)
        {
            Category.Create(new {ID,Name}, User.Identity.Name)
            return View();
        }
//
public ActionResult Create(string ID, string Name, int PropOne, string PropTwo)
        {
            Category.Create(new {ID,Name, PropOne, PropTwo}, User.Identity.Name)
            return View();
        }

But unlike in the view here in the controller you can’t just access the model’s type through MvcTextTemplateHost.ViewDataType. when you are generating a controller this property is null. so i thought of using reflection get the model for the current controller. you can use the ControllerRootName property of MvcTextTemplateHost(available through mvcHost variable in the default template) to get the model name(ex: ProductController would give Product).

<#
Type controllerType = Assembly.LoadFile("D:\\path\\to\\your\\model\\assemblys\\dll\\file.dll").GetType("Example.Models." + mvcHost.ControllerRootName);
#>

Following is the full source code of a generated controller and the modified template that was used to generate it. I have reused some methods like IsBindableType and GetEntityKeyProperties(i have modified this a bit) that can be found in some View templates in mvc framework. The generated controller can be used to do CURD operations on the model and provide a backend(providing data to the grid through json) for a ExtJS grid! 🙂 (A Grid with Ajax/Pagination/Sorting/Filtering on ASP.net MVC with ExtJS and Enitiy Framework)

Generated Controller

//
//A Generated Controller
//
using System;
using System.Collections;
using System.Web.Mvc;
using ExampleInc.Filters;
using ExampleInc.Lib.Helpers;
using ExampleInc.Models;
using ExampleInc.Models.UoW;

namespace ExampleInc.Controllers
{
	[Authorize]
    [NavigationFilter]
    public class ExampleModelController : Controller
    {
        //
        // GET: /ExampleModel/
        public ActionResult Index()
        {
            return RedirectToAction("List");
        }

        //
        // GET: /ExampleModel/Details/5
        public ActionResult Details(Int32 SiteUID,Int32 UID)
        {
            return View(ExampleModel.GetModelByPrimaryKey(new {SiteUID,UID}));
        }

        //
        // GET: /ExampleModel/Create
        public ActionResult Create()
        {
            return View();
        } 

        //
        // POST: /ExampleModel/Create
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Create(Int32 SiteUID ,Int32 UID ,String ID ,String Name ,Decimal Turnover ,String StreetAddress ,String City ,String PostalCode ,String Telephone1 ,String Telephone2 ,String Email ,String Fax ,String Notes ,String Capacity ,Int16 NumberOfMealsPerDay ,Decimal SellingPricePerMeal ,Decimal BudgetPricePerMeal ,String BestTimeToCall ,Byte TradingDaysPerWeek ,Byte TradingWeeksPerYear ,Boolean AccountActive ,Int32 PrimaryContact_SiteUID ,Int32 PrimaryContactUID ,DateTime LastCallStartTime ,Boolean IsProfileCall )
        {
            if (ViewData.ModelState.IsValid)
            {
                // Attempt to add the user

                if (ExampleModel.Create(new {SiteUID ,UID ,ID ,Name ,Turnover ,StreetAddress ,City ,PostalCode ,Telephone1 ,Telephone2 ,Email ,Fax ,Notes ,Capacity ,NumberOfMealsPerDay ,SellingPricePerMeal ,BudgetPricePerMeal ,BestTimeToCall ,TradingDaysPerWeek ,TradingWeeksPerYear ,AccountActive ,PrimaryContact_SiteUID ,PrimaryContactUID ,LastCallStartTime ,IsProfileCall }, User.Identity.Name))
                {
                    TempData["StatusBar"] += "ExampleModel '" + ID + "' successfully added.";
                    return RedirectToAction("List");
                }

                ModelState.AddModelError("_FORM", "Error");
            }

            // If we got this far, something failed, redisplay form
            return View();
        }

        //
        // GET: /ExampleModel/Edit/5
        public ActionResult Edit(Int32 SiteUID,Int32 UID)
        {
            return View(ExampleModel.GetModelByPrimaryKey(new {SiteUID,UID}));
        }

        //
        // POST: /ExampleModel/Edit/5
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Edit(Int32 SiteUID ,Int32 UID ,String ID ,String Name ,Decimal Turnover ,String StreetAddress ,String City ,String PostalCode ,String Telephone1 ,String Telephone2 ,String Email ,String Fax ,String Notes ,String Capacity ,Int16 NumberOfMealsPerDay ,Decimal SellingPricePerMeal ,Decimal BudgetPricePerMeal ,String BestTimeToCall ,Byte TradingDaysPerWeek ,Byte TradingWeeksPerYear ,Boolean AccountActive ,Int32 PrimaryContact_SiteUID ,Int32 PrimaryContactUID ,DateTime LastCallStartTime ,Boolean IsProfileCall )
        {
            if (ViewData.ModelState.IsValid)
            {
                if (ExampleModel.Update(new {SiteUID,UID}, new {SiteUID ,UID ,ID ,Name ,Turnover ,StreetAddress ,City ,PostalCode ,Telephone1 ,Telephone2 ,Email ,Fax ,Notes ,Capacity ,NumberOfMealsPerDay ,SellingPricePerMeal ,BudgetPricePerMeal ,BestTimeToCall ,TradingDaysPerWeek ,TradingWeeksPerYear ,AccountActive ,PrimaryContact_SiteUID ,PrimaryContactUID ,LastCallStartTime ,IsProfileCall }, User.Identity.Name))
                {
                    TempData["StatusBar"] += "ExampleModel '" + ID + "' successfully updated.";
                    return RedirectToAction("List");
                }

                ModelState.AddModelError("_FORM", "Error");
            }

            // If we got this far, something failed, redisplay form
            return View(ExampleModel.GetModelByPrimaryKey(new {SiteUID,UID}));
        }

        public ActionResult Delete(Int32 SiteUID,Int32 UID)
        {
            if (ExampleModel.Delete(new {SiteUID,UID}))
            {
                TempData["StatusBar"] += "ExampleModel successfully deleted.";
            }
            else
            {
                TempData["StatusBar"] += "ExampleModel delete operation failed!.";
            }
            return RedirectToAction("List");
        }

        public ViewResult List()
        {
            return View();
        }

        public ViewResult Grid(string RowClickEventHandlerFunctionName)
        {
            ViewData["RowClickEventHandlerFunctionName"] = RowClickEventHandlerFunctionName;
            return View();
        }

        public JsonResult GridData()
        {
            int totalOjectCount;
            var ExampleModelsList = EmExtJSGridFilterHelper.GetResults(Request, DataMan.ObjectContext.ExampleModel, out totalOjectCount);
            var list = new ArrayList();
            foreach (var ExampleModel in ExampleModelsList) //populate data containers with read data
            {
                list.Add(new
                             {
                                 ExampleModel.SiteUID ,ExampleModel.UID ,ExampleModel.ID ,ExampleModel.Name ,ExampleModel.Turnover ,ExampleModel.StreetAddress ,ExampleModel.City ,ExampleModel.PostalCode ,ExampleModel.Telephone1 ,ExampleModel.Telephone2 ,ExampleModel.Email ,ExampleModel.Fax ,ExampleModel.Notes ,ExampleModel.Capacity ,ExampleModel.NumberOfMealsPerDay ,ExampleModel.SellingPricePerMeal ,ExampleModel.BudgetPricePerMeal ,ExampleModel.BestTimeToCall ,ExampleModel.TradingDaysPerWeek ,ExampleModel.TradingWeeksPerYear ,ExampleModel.AccountActive ,ExampleModel.PrimaryContact_SiteUID ,ExampleModel.PrimaryContactUID ,ExampleModel.LastCallStartTime ,ExampleModel.IsProfileCall
                             });
            }
            return Json(new {dataitExampleInc = list.ToArray(), totalItExampleInc = totalOjectCount});
        }
    }
}

T4 Template used to Generate the Controller

<#@ template language="C#" HostSpecific="True" #>
<#@ output extension="cs" #>
<#@ assembly name="System.Data.Entity" #>
<#@ assembly name="System.Data.Linq" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.Reflection" #>
<#@ import namespace="System.Data.Objects.DataClasses" #>
<#@ import namespace="System.Data.Linq.Mapping" #>
<#
MvcTextTemplateHost mvcHost = (MvcTextTemplateHost)(Host);
#>
<#
Type controllerType = Assembly.LoadFile("D:\\work_items\\ExampleInc\\ExampleInc-Alt-21\\ExampleInc.Models\\bin\\Debug\\ExampleInc.Models.dll").GetType("ExampleInc.Models." + mvcHost.ControllerRootName);

PropertyInfo&#91;&#93; piArray = controllerType.GetProperties(BindingFlags.Public|BindingFlags.Instance|BindingFlags.DeclaredOnly);

string actionMethodParamerters = "", anonTypePropValString = "", gridDataAnonTypePropValString = "";
foreach (PropertyInfo pi in piArray)
		{
			Type currentPropertyType = GetUnderlyingType(pi.PropertyType);

			if(IsBindableType(currentPropertyType) && IsNeededProp(pi.Name))
			{
				actionMethodParamerters += currentPropertyType.Name + " " + pi.Name + " ,";
				anonTypePropValString += pi.Name + " ,";
				gridDataAnonTypePropValString += mvcHost.ControllerRootName.ToLower() + "." + pi.Name + " ,";
			}
		}
actionMethodParamerters = actionMethodParamerters.Remove(actionMethodParamerters.Length - 1); //remove the last extra ","
anonTypePropValString = anonTypePropValString.Remove(anonTypePropValString.Length - 1); //remove the last extra ","
gridDataAnonTypePropValString = gridDataAnonTypePropValString.Remove(gridDataAnonTypePropValString.Length - 1); //remove the last extra ","
#>
using System;
using System.Collections;
using System.Web.Mvc;
using ExampleInc.Filters;
using ExampleInc.Lib.Helpers;
using ExampleInc.Models;
using ExampleInc.Models.UoW;

namespace <#= mvcHost.Namespace #>
{
	[Authorize]
    [NavigationFilter]
    public class <#= mvcHost.ControllerName #> : Controller
    {
        //
        // GET: /<#= mvcHost.ControllerRootName #>/
        public ActionResult Index()
        {
            return RedirectToAction("List");
        }

<#
if(mvcHost.AddActionMethods) {
#>
        //
        // GET: /<#= mvcHost.ControllerRootName #>/Details/5
        public ActionResult Details(<#= GetMethodParamertersString(controllerType) #>)
        {
            return View(<#= mvcHost.ControllerRootName #>.GetModelByPrimaryKey(new {<#= GetDataAnonTypePropValString(controllerType) #>}));
        }

        //
        // GET: /<#= mvcHost.ControllerRootName #>/Create
        public ActionResult Create()
        {
            return View();
        } 

        //
        // POST: /<#= mvcHost.ControllerRootName #>/Create
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Create(<#= actionMethodParamerters #>)
        {
            if (ViewData.ModelState.IsValid)
            {
                // Attempt to add the user

                if (<#= mvcHost.ControllerRootName #>.Create(new {<#= anonTypePropValString #>}, User.Identity.Name))
                {
                    TempData["StatusBar"] += "<#= mvcHost.ControllerRootName #> '" + ID + "' successfully added.";
                    return RedirectToAction("List");
                }

                ModelState.AddModelError("_FORM", "Error");
            }

            // If we got this far, something failed, redisplay form
            return View();
        }

        //
        // GET: /<#= mvcHost.ControllerRootName #>/Edit/5
        public ActionResult Edit(<#= GetMethodParamertersString(controllerType) #>)
        {
            return View(<#= mvcHost.ControllerRootName #>.GetModelByPrimaryKey(new {<#= GetDataAnonTypePropValString(controllerType) #>}));
        }

        //
        // POST: /<#= mvcHost.ControllerRootName #>/Edit/5
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Edit(<#= actionMethodParamerters #>)
        {
            if (ViewData.ModelState.IsValid)
            {
                if (<#= mvcHost.ControllerRootName #>.Update(new {<#= GetDataAnonTypePropValString(controllerType) #>}, new {<#= anonTypePropValString #>}, User.Identity.Name))
                {
                    TempData["StatusBar"] += "<#= mvcHost.ControllerRootName #> '" + ID + "' successfully updated.";
                    return RedirectToAction("List");
                }

                ModelState.AddModelError("_FORM", "Error");
            }

            // If we got this far, something failed, redisplay form
            return View(<#= mvcHost.ControllerRootName #>.GetModelByPrimaryKey(new {<#= GetDataAnonTypePropValString(controllerType) #>}));
        }

        public ActionResult Delete(<#= GetMethodParamertersString(controllerType) #>)
        {
            if (<#= mvcHost.ControllerRootName #>.Delete(new {<#= GetDataAnonTypePropValString(controllerType) #>}))
            {
                TempData["StatusBar"] += "<#= mvcHost.ControllerRootName #> successfully deleted.";
            }
            else
            {
                TempData["StatusBar"] += "<#= mvcHost.ControllerRootName #> delete operation failed!.";
            }
            return RedirectToAction("List");
        }

        public ViewResult List()
        {
            return View();
        }

        public ViewResult Grid(string RowClickEventHandlerFunctionName)
        {
            ViewData["RowClickEventHandlerFunctionName"] = RowClickEventHandlerFunctionName;
            return View();
        }

        public JsonResult GridData()
        {
            int totalOjectCount;
            var <#= mvcHost.ControllerRootName.ToLower() #>sList = EmExtJSGridFilterHelper.GetResults(Request, DataMan.ObjectContext.<#= mvcHost.ControllerRootName #>, out totalOjectCount);
            var list = new ArrayList();
            foreach (var <#= mvcHost.ControllerRootName.ToLower() #> in <#= mvcHost.ControllerRootName.ToLower() #>sList) //populate data containers with read data
            {
                list.Add(new
                             {
                                 <#= gridDataAnonTypePropValString #>
                             });
            }
            return Json(new {dataitems = list.ToArray(), totalItems = totalOjectCount});
        }
<#
}
#>
    }
}
<#+
public static List<PropertyInfo> GetEntityKeyProperties(Type type)
{
	List<PropertyInfo> keyProperties = new List<PropertyInfo>();

	PropertyInfo[] properties = type.GetProperties();

	foreach (PropertyInfo pi in properties)
	{
		System.Object[] attributes = pi.GetCustomAttributes(true);

		foreach (object attribute in attributes)
		{
			if (attribute is EdmScalarPropertyAttribute)
			{
				if ((attribute as EdmScalarPropertyAttribute).EntityKeyProperty == true)
				{
					keyProperties.Add(pi);
				}
			} else if(attribute is ColumnAttribute) {
				if ((attribute as ColumnAttribute).IsPrimaryKey == true)
				{
					keyProperties.Add(pi);
				}
			}
		}
	}

	return keyProperties;
}

public bool IsBindableType(Type type)
{
	bool isBindable = false;

	if (type.IsPrimitive || type.Equals(typeof(string)) || type.Equals(typeof(DateTime)) || type.Equals(typeof(decimal)) || type.Equals(typeof(Guid)) || type.Equals(typeof(DateTimeOffset)) || type.Equals(typeof(TimeSpan)))
	{
		isBindable = true;
	}

	return isBindable;
}

public bool IsNeededProp(string propName)
        {
            switch (propName)
            {
                case "CreationDate":
                case "LastModifiedDate":
                case "LastModifiedBy":
                case "EffectiveDate":
                case "ExpiryDate":
                case "ServerEntryDate":
                    return false;
            }
            return true;
        }

public string GetMethodParamertersString(Type viewDataType)
        {
			List<PropertyInfo> primaryKeys = GetEntityKeyProperties(viewDataType);

			if(primaryKeys.Count > 0) {
				string result = "";
				foreach(PropertyInfo pk in primaryKeys)
				{
					result += String.Format("{0} {1},", GetUnderlyingType(pk.PropertyType).Name , pk.Name);
				}

				return result.Remove(result.Length - 1); //remove the last extra ","
			} else {
				return "UID=Model.PrimaryKey";
			}
        }

public string GetDataAnonTypePropValString(Type viewDataType)
        {
			List<PropertyInfo> primaryKeys = GetEntityKeyProperties(viewDataType);

			if(primaryKeys.Count > 0) {
				string result = "";
				foreach(PropertyInfo pk in primaryKeys)
				{
					result += String.Format("{0},", pk.Name);
				}

				return result.Remove(result.Length - 1); //remove the last extra ","
			} else {
				return "UID=Model.PrimaryKey";
			}
        }

public Type GetUnderlyingType(Type type)
{
	Type currentPropertyType = type;
			Type currentUnderlyingType = System.Nullable.GetUnderlyingType(currentPropertyType);
			if(currentUnderlyingType != null) {
				currentPropertyType = currentUnderlyingType;
			}

			return currentPropertyType;
}
#>

hope this will help someone/myself in the feuture 🙂

Blog at WordPress.com.