Kategoriarkiv: Programmering

Which method called me?

I wanted a general function to log all calls to a WCF service a built, I want the calling method names without use that as a parameter and then need to hardcode that in every method. This is the solution it show how to found out the calling method using the stack trace.
 

internal static void LogRequest(IRequest request)
{
   
var callingMethod = new System.Diagnostics.StackTrace(1, false).GetFrame(0).GetMethod();
   
if(request != null)
    {
       
var applicationId = request.Header != null ? request.Header.ApplicationId : "unkown";
       
Log.Info(string.Format("{0} called by {1} Application ", callingMethod.Name, applicationId));
    }
   
else
   
{
       
Log.Error(string.Format("{0} called by Application with a null request, thats not allowed", callingMethod.Name));
    }
}


PainKiller C# Corner

Jag skall sluta tortera mina icke programmerande vänner med bloggar som berör detta ämne. Jag har startat en ny blogg där allt som handlar om programmering i synnerhet då C# hamnar.
 

Generic and Reflection magic

I´m proud to present my Crud class, CRUD (Create, Read, Update, Delete) so far I´ve implemented Read. It´s maps any class derived from my Crud class to a DataTable without any coding at all (no mapping code no loop etc). BUT the datatable column name and datatypes must match the class properties. If you have tried NUnit or Entity Framwork you know that you have to write XML files that descibes the matching between every column in the table and every property in the class. With this class you can skip that, and it is a good idea to name the column and property with same name.

public class Crud
    {
        public virtual List<T> Read<T>(DataRowCollection rows) where T: Crud, new()
        {
            List<T> retVal = new List<T>();
            T temp = new T();
            foreach(DataRow row in rows)
                retVal.Add(temp.RowToInstance<T>(row));
            return retVal;
        }

        protected virtual T RowToInstance<T>(DataRow row) where T : new()
        {
            T item = new T();
            Type t = item.GetType();
            foreach (PropertyInfo propInfo in t.GetProperties())
            {
                propInfo.SetValue(item, row[propInfo.Name], null);               
            }
            return item;
        }
    }

The Crud class does the magic using reflection to dynamically build an object that represents the generic type and sets it´s properties with values from the DataRow. Now a sample that show how to use it, a simple class that represents a User, it has a table tblUser thats identical towards the class properties. First the script to create the table.

CREATE TABLE [dbo].[tblUser](
    [UserId] [int] IDENTITY(1,1) NOT NULL,
    [UserName] [nvarchar](50) NOT NULL,
    [Created] [datetime] NOT NULL,
    [LastChanged] [datetime] NOT NULL,
    [ChangedBy] [int] NOT NULL
)

Then the sourcecode for the User class. I highligt the interesting stuff.

public class User : Crud
    {
        public User(){}
        public User(string userName) { this.UserName = userName; }

        private static readonly User _user = new User();
        public int UserId { get; set; }
        public string UserName { get; set; }
        public DateTime Created{ get; set; }       
        public DateTime LastChanged{ get; set; }
        public int ChangedBy { get; set; }

        public static User Select(int UserId)
        {
            return _user.RowToInstance<User>(UserData.Select(UserId));
        }

        public static List<User> Select() { return _user.Read<User>(UserData.Select()); }
        public static void Create(User newUser, User administrator)
        {
            UserData.Create(newUser.UserName, DateTime.Now, DateTime.Now, administrator.UserId);
        }
    }

One single row to get a DataTable and convert it to an Generic list of User type (or any type deriving from Crud), that is pretty amazing. Generic is something that takes a little time to understand. The UserData class has an static method to get the DataRowCollection (it´s another story). To try this sample you need to create a method to Select from the tblUser table, I using generics also for this therefore I´m not show you thoose classes it would be to much. Or not? I give you the code for that also but with no futher comments help yourself.

public class UserData
    {
        private UserData() { }

        public static DataRow Select(int UserId)
        {
            string sqlString = String.Format("SELECT [UserId],[UserName],[Created],[LastChanged],[ChangedBy] " +
                "FROM [dbo].[tblUser] WHERE [UserId]={0}", UserId);
            return DbHelper.Select(sqlString);
        }

        public static DataRowCollection Select()
        {
            string sqlString = "SELECT [UserId],[UserName],[Created],[LastChanged],[ChangedBy] " +
                "FROM [dbo].[tblUser]";
            return DbHelper.SelectRows(sqlString);
        }

        public static void Create(string UserName, DateTime Created, DateTime LastChanged, int ChangedBy)
        {
            string sqlString = String.Format("INSERT INTO [dbo].[tblUser] " +
                "([UserName], [Created], [LastChanged],[ChangedBy]) " +
                "VALUES (”{0}’,'{1}’,'{2}’,{3})", UserName, Created, LastChanged, ChangedBy);
            DbHelper.Create(sqlString);
        }
    }

//Now the DbHelperClass that dynamically builds the datatable, you can look at the public static DataTable ReaderToTable(SqlDataReader reader) method (ripped from MSDN Help)

public class DbHelper
    {
        private static DbHelper helper;
        private SqlConnection cn;
        private DbHelper(string connectionString)
        {
            this.cn = new SqlConnection(connectionString);
        }

        static DbHelper()
        {
            helper = new DbHelper(ConfigurationManager.ConnectionStrings["DbConnectionString"].ConnectionString);
        }

        public static SqlConnection Connection
        {
            get
            {
                if (helper.cn.State != System.Data.ConnectionState.Open) { helper.cn.Open(); }
                return helper.cn;
            }
        }

        public static SqlCommand GetCommand(CommandType cmdType, string cmdText)
        {
            SqlCommand retVal = new SqlCommand(cmdText);
            retVal.CommandType = cmdType;
            retVal.Connection = Connection;
            return retVal;
        }

        public static DataRow Select(string sqlString)
        {
            SqlCommand cmd = GetCommand(CommandType.Text, sqlString);
            SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.SingleRow);
            return ReaderToTable(dr).Rows[0];
        }

        public static DataRowCollection SelectRows(string sqlString)
        {           
            SqlCommand cmd = DbHelper.GetCommand(CommandType.Text, sqlString);
            SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.SingleResult);
            return ReaderToTable(dr).Rows;
        }

        public static DataTable ReaderToTable(SqlDataReader reader)
        {
            DataTable newTable = new DataTable();
            DataColumn col = null;
            DataRow row = null;
            for (int i = 0; i < reader.FieldCount; i++)
            {
                col = new DataColumn();
                col.ColumnName = reader.GetName(i);
                col.DataType = reader.GetFieldType(i);
                newTable.Columns.Add(col);
            }
            while (reader.Read())
            {
                row = newTable.NewRow();
                for (int i = 0; i < reader.FieldCount; i++)
                {
                    row[i] = reader[i];
                }

                newTable.Rows.Add(row);
            }
            return newTable;
        }

        public static void Create(string sqlString)
        {
            SqlCommand cmd = DbHelper.GetCommand(CommandType.Text, sqlString);
            cmd.ExecuteNonQuery();
        }
    }


XML Encode problem change it on the fly

Ni som jobbar med XML, DataSet och .NET har säkert haft bekymmer med xml data som är av fel encoding type, det kan man lätt sjystera i xml dokumentet men ibland har man inte tillgång till det. Ett problem jag löste nyligen var att ta emot ett DataSet via en webservice men som en sträng, jag löste det så här (jag tror/hoppas det kan hjälpa någon stackare):

DataSet ds = new DataSet("dsKund");

string xmlData = customer.HamtaDataSetString(personNr);

ds.ReadXml(

new MemoryStream(System.Text.Encoding.UTF8.GetBytes(xmlData)));


Property in java Vs C#

It was a long time ago i wrote something in this blog that references to my work as an developer but here we go again. Properties is an interesting subject for programmers, What is it? When should I use it? How does it work or why dont use public variables instead?
 
Well first things first what is it?
 
To make it short you could say that properties in the .NET world is used to represent an objects data, while function and method´s are used to perform some kind of action(calculation, writing to file etc). Property simplifies what in the OO world is called encapsulation to protect private data members. The Java language don´t support this automated but it´s stilled used in a different way, some code to see this in action.
 

//encapsulation with property the C# (.NET) style
private int mSize;
public int Size {
   
get { return mSize; }
   
set {
       
if (value < 0)
            mSize = 0;
       
else
           
mSize = value;
        }
    }
}

//same but now in Java style
private int mSize;
public int getSize() { return mSize; }
public void setSize(int value) {
   
if (value < 0)
       
mSize = 0;
   
else
       
mSize = value;
}
 

Notice that Java uses methods instead so called getters and setters but it´s all up to the programmer to follow this, he/she could develop own standards (bad idea) for encapsulation, you could of course do the same thing with .NET if you want. In fact it´s exactly what the compiler does when it compiles the source code to IL code later on in this article I will show how that works. Using properties style instead of get/set methods is prettier if you ask me even if the compiled result is just the same.
 
When should I use it?
 
Well it is a heavy subject but to also also make this short think this way. If you use a property, it should be a signal that it´s just a way to read and write an objects datamember. The value should be pretty persistence for example if you read the property twice in a row it should return the same thing.  If the write or read operation includes calculation or other processing get and set functions are better. This signals an clear distinction between what´s happening. If you for example want to change the speed of a car don´t use a property called speed, use a function called SetSpeed or even better in this case maybe it should be called SpeedUp( what else is there? Brake? No :-)  ) instead. The Car´s weight is better suited for a property. In Java you don´t really have so many options in this car scenario the difference could be to change the datamember speed you use a function called SpeedUp, while changing the weight member using getWeight and setWeight signals that it don´t process anything just read or writes the datamember.
 
How does it work or why don´t use public variables instead?
 
Before I digging in on this subject some light at a new feature in .NET 3.5 many properties don´t use any kind of validation or other control it´s just this simple:
 
private int _size;
public int Size {
   
get { return _size; }
   
set { _size = value; }
}
 
A new feature in 3.5 makes this even more simpler and with less code (same style as in interface)
 
public int Size {
   
get;
   
set;
}
 
The private variable _size is gone (notice this magic only work with both get and set accessor included) Wow you may think, but?

Back to the subject this is no encapsulation is it? If the only thing that matters is to save code rows I could just declare a public variable instead or could I? Well just because no validation is needed when you design and code the class don´t men that it´s gonna be like this forever, later on maybe a project leader or some other smart ass want some validation implemented, Size can´t be negative for instance :-)
Okej then you just change the public variable to a property problem solved or? Maybe not if the assembly that this class belongs to is used by other assemblys or applications you have a big problem changing a public variable to a property is breaking the assembly´s binary compabillity you could very easy see this using the first class SDK tool ILDASM ($VS 2005 install path$\SDK\v2.0\Bin\ildasm.exe)
 
First see the image below it shows the class Shoe with public variable style (sorcecode below)

public class Shoe {
   
public int Size;
}

It´s the field Size that´s interesting this class as the image show ( a bit blurry sorry for that) has a datamember named Size with the datatype int

In client code you can change the datamember like this 
myShoe.Size  = 45;

Okay now changing the public variable to using property instead let´s see the big picture below
public class Shoe {
   
private int _size;
   
public int Size {
       
get { return _size; }
       
set { _size = value; }
    }
}
 

What happened? The compiler converts the property to two methods Get_Size and Set_Size, now you see how it works under the hood, notice that In client code there is no difference at all it still works the same myShoe.Size  = 45; but in the assembly it dont works the same way and this could be critical so my advice is use properties from the beginning.

Harri Klingten
Software Engineer at Extenda


ORM & CRUD

Två rätt hypade ord inom programmeringsvärlden, hypade och spännande.
 

”Patrition Magic” Magic

Visste ni att???
 
Det går att storleksförändra partitioner ifrån båda hållen!!!

Problem med åäö

Ett tips till alla stackars webutvecklare som råkat ut för problemet med att åäö inte hanteras korrekt på en ASP sida. Lägg till denna meta tag i headern på sidan och problemet är löst.
 
<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1" >
 
Det är just charset=iso-8859-1 som är teckenkodningen för svenska tecken. Detta gäller inte bara html sidor även xml filer kan kodas fel om fel teckenuppsättning används. Ändra då UTF-8 som brukar vara standard till iso-8859-1. I XML filen ser deklareringen lite annurlunda ut:
 
<?xml version="1.0" encoding="iso-8859-1"?>
 
Läs mera om teckenkodning här
 
 

SQL tips – Använd Unicode

När man skall välja att lagra text i en kolum står man oftast inför valet hur många tecken skall man lagra, mitt tips för att standarniera och underlätta de valet är att skapa UDT för saker som man oftast lagrar i en databas.
Exempel kan vara en egendefinerad datatyp man kallar PhoneNumber den lagrar upp till 20 Unicode tecken det ser då ut så här i scriptet för att skapa den.
 
EXEC sp_addtype N’PhoneNumber’, N’nvarchar (20)’, N’null”
 
Nu slipper man fundera nästa gång ett telefonnummer skall in i en tabell, observera här att jag använder Nvarchar och inte varchar. Det är en rekomendation att alltid använda Unicode att lagra text, men tyvärr är det väldigt lätt hänt att man av gammal vana använder varchar och char istället för Nvarchar och Nchar.
 
Att lagra text i Unicode spar eventuella problem som kan uppstå med olika internationella tecken, de flesta moderna programeringsspråk hanterar text som Unicode och måste därför ändå casta till Unicode. MS Sql server 2000 arbetar internt med Unicode.
 
Ett exempel på detta är om man testar att köra denna procedur som är en intern sql procedure
 
EXEC sp_ExecuteSQL ”SELECT 1′
 
–Returns
Server: Msg 214, Level 16, State 2, Procedure sp_executesql, Line 1
Procedure expects parameter
”@statement” of type ”ntext/nchar/nvarchar’.
 
Detta funkar bättre
 
EXEC sp_ExecuteSQL ”SELECT 1′
–Returns
1
 
Viktigt att inte glömma N prefixet vid tilldelning av unicode strängar annars kan man få oväntade resultat.

SQL tips ladda in många rader med xml

Att uppdatera en databas ifrån en DataSet ifrån t ex en ASP.NET sida kan ibland kostsamt vad gäller kommunikationen emellan webserver och databasen. Om det t ex rör sig om några hundra rader data körs DataAdaptern sin insert några hundra gånger en bra variant för att undvika detta är att köra en procedur som tar emot hela tabellen i XML istället på detta vis.

Först koden i C# bara de kodrader som är inblandande i att köra en stored procedure DS är ett DataSet med en DataTable med ca 10 000 rader (Jo då det går alldeles utmärkt)

myParam.Value = this.DS.GetXml();
insertCommand.Parameters.Add(myParam);
insertCommand.ExecuteScalar();

Sedan själva proceduren i sin helhet som tar hand om xml datat

CREATE PROC painkiller.spArchiveAddXmlData
 @Xml NTEXT
  AS
BEGIN
 SET NOCOUNT ON
 SET XACT_ABORT ON — Vid ev. fel, bryt SP-exekv. & gör rollback. Slipper @@error kontroller :-)  

 DECLARE @XmlID INT
 EXEC sp_xml_preparedocument @XmlID OUTPUT, @Xml

 BEGIN TRAN
  INSERT painkiller.tblArchive ([FileName],[FilePath])
   SELECT x.[FileName], x.[FilePath]
     FROM OPENXML(@XmlID, ”/archive/tblArchive’, 2) WITH (
     [FileName] varchar(255) ”FileName”
     ,[FilePath] varchar(1500) ”FilePath”
    ) AS x
   IF(@@rowcount < 1)
    BEGIN
     RAISERROR(”Coult not read xml file please ensure that the input file is valid.’, 16, 1)
     EXEC sp_xml_removedocument @XmlID
     ROLLBACK TRAN
     RETURN(1) 
    END

 COMMIT TRAN

 EXEC sp_xml_removedocument @XmlID
END

GO

 


Följ

Få meddelanden om nya inlägg via e-post.