Thursday, April 29, 2010

Optional parameters on C#

If you have started with C# 4.0, this feature may seem to be very exciting. You might have already used optional parameters on SQL. The new C# 4.0 has the capability to have optional parameters on our application code. Let’s look at how to use this feature.

Create a console project.

Copy the below code

static void Main(string[] args)

{
      Program.CreateUser(lastName: "padubidri", firstName: "subramanya");
      Program.CreateUser("padubidri", "subramanya");
      Program.CreateUser("padubidri", "subramanya",1001);
      Console.ReadKey();
}


private static void CreateUser(string lastName,string firstName,int userID = 0)
{
      Console.WriteLine("lastName:" + lastName + "; firstName: " + firstName + "; ID: " + userID);
}

Observe the method CreateUser where I have default value for userID. Look at the above part where this method is invoked. When we don’t send userID parameter, it takes the default value. On Main method you can observe the different ways you can call this createUser method. Just remember that if you specify parameter name when you invoke the method, your dll or exe might break if the parameter name is changed in the future. So the second and third lines on the above call are safer way to deal with.



Let’s run this code and look at the result.


The first two calls taken userID 0 which is default value.


You can also use the optional parameters on interfaces. I feel this would help us to avoid lots of overload methods but it might also have evil effect if we don’t use this correctly.

Tuesday, April 27, 2010

Conditional Compilation using C#

Consider a code where you need to enable some lines based on a condition. Let’s say all the debug logs should not be shipped along with the product but you need the log information when you develop or test the application. If you are using ASP.Net you can make use of trace or Debug. how do you do that if you need to log something from the dll  ? What is the easy method to do this?


Let’s look at C# #IF directive and see how we can make use of it.

When the C# compiler encounters #if directive, followed eventually by an #endif directive, it will compile the code between the directives only if the specified symbol is defined. i.e if my code contains something below


namespace FirstConsole
{
class Program
{
static void Main(string[] args)
{
#if DEBUG
    Console.WriteLine("My debug entries");
#endif
  Console.WriteLine("Program Ends");
  Console.ReadKey();
}
}


}

The line Console.WriteLine("My debug entries"); will be compiled only when I build the application in debug mode.

Let’s do this simple test to get the clear understanding. Now I have created console application and placed above code.

I am going to build the application in Debug mode


Here is the result.


Ok. Now let’s change our build mode to release and see the output.


We can also have our own defined symbols and use them for conditional compilation. On the build settings change as below


And change the code as


class Program
{
static void Main(string[] args)
{
#if MYTEST
   Console.WriteLine("My debug entries");
#endif
Console.WriteLine("Program Ends");
Console.ReadKey();
}
}


Check the result now!!

Ok now let’s look at another advantage. I want ship a product with 2 different versions BASIC and PROFESSIONAL. I need to differentiate some of the functionalities based on the configuration. One way to do this is by keeping system level configuration and check everywhere from the config. We can also do this by using conditional compilation. Here is my sample code snippet


class Program

{
static void Main(string[] args)
{
#if BASICEDITION
   Program.MyBsicVersionCall();
#elif PROFESSIONALEDITION
   Program.MyBsicVersionCall();
#endif
Console.WriteLine("Program Ends");
Console.ReadKey();
}


static void MyBsicVersionCall()
{
   Console.WriteLine("Basic Version");
}


static void MyProfessionalVersionCall()
{
   Console.WriteLine("Professional Version");
}
}



Change the conditional compilation symbol and check the result!!

This would definitely help developers to put their debug statements as I used it a lot on my middle layer services and dlls to enable debugging.

Friday, April 9, 2010

Webservice with httpGET and httpPOST

If you have worked on web application, you would have used GET and POST method to submit your forms. And I am sure you know the difference. Do you know if there is any such concept while calling webservice? Yes. If you have used old fashion of code in VB or asp to invoke any webservice through xmlHTTP you might have used it. When using .net, if you refer the webservice using web reference, it does all the background work for you and you don’t need to really worry about this. What I have observed is when you refer it through .Net web reference, by default it sends request with POST method.


I had very interesting problem recently. Our webservice was written on cold fusion and client was on .Net. The webserivice was working alright and returning the output whatever we were expecting. But when we tried referring the same service from .Net, the client was throwing error.

org.xml.sax.SAXParseException: Document root element is missing

It seemed to be common problem while parsing xml so I was thinking it would be problem with soap body which is not able to convert the data from cold fusion to format that was expected from .Net. The return from the webservice was a string and I tried creating a test method which does not accept any data and return some test value. Even that simple webservice method had the same problem. Here is my coldfusion webservice method..









When I did some more analysis, the error message was something like this

The remote server returned an error: (500) Internal Server Error.



soapenv:Server.userException
org.xml.sax.SAXParseException: Document root element is missing.





Error was internal server error from IIS. I tried calling the same method from one of my cold fusion page and that worked fine.

Here is what I found, when the method was invoked from cold fusion page, it was invoking with GET method by default. When I referred the same service from .Net client, it was invoking with POST. I found this from IIS log. All the log entries with POST method for this service had 500 Internal errors. So I had option to fix the webservice to get it working with POST method or change the client to request webservice using GET. I am not an expert in cold fusion so I opeted for second option of invoking webservice with GET method.

When the client code changed to invoke the webservice using GET method, the output came out right and all the functionalities worked very well. I still think making change on the webservice to fix this problem is better but I may have to spend some more time to do that..

Monday, April 5, 2010

Computed column in Sql Server

Have you ever come across any requirement which required saving data in a column that depends on the data of other columns? For example, the total amount of a transaction which would depend on billed amount and the tax amount. But you might need many reports to show the total. There is one way that you would get these two fields in your select query and add them. If you need to store the total on one more column so that you can use it for some other purpose, you could add that on your store proc. Another way would be by using trigger. But I found Computed columns more efficient and decent approach if we don’t have much logic involved storing the calculated data.

Let’s look at how to create these columns.

CREATE TABLE [dbo].[Billing](

[BillID] [int] NOT NULL,
[CustomerName] [varchar](50) NOT NULL,
[City] [varchar](50) NULL,
[BillAmount] [float] NULL,
[Tax] AS (([BillAmount]*(10))/(100)),
[TotalAmount] AS ([BillAmount]+([BillAmount]*(10))/(100)))

If you look at above table, the columns Tax and TotalAmount do not have any datatype assosiated but it depends on BillAmount field.

You can also create this by using SQL table editor as shown below



Now lets insert some data to our table and see the values


insert into Billing values (1,'ABC','Blr',100)
insert into Billing values (2,'XYZ','NY',200)



The data is inserted and now lets look at our table to see how is our computed columns.

Here we go

 



The columns has the data what we had expected.




What happens if you try to insert data tp computed columns? Let’s try that

insert into Billing (BillID,CustomerName,City,BillAmount,Tax,TotalAmount) values (3,'XYZ','NY',200,10,110)


Msg 271, Level 16, State 1, Line 1
The column "Tax" cannot be modified because it is either a computed column or is the result of a UNION operator.
Msg 271, Level 16, State 1, Line 1
The column "TotalAmount" cannot be modified because it is either a computed column or is the result of a UNION operator.



Error!!!! Yes you need to remember that you cannot insert or update computed column data.



We can also create index on these columns. To create index on these column, you need to specify the column as PERSISTED. For more details on this http://msdn.microsoft.com/en-us/library/ms191250.aspx



We can also add the case statements on the computed columns. Let’s try that


CREATE TABLE MyTable (

number1 INT,
number2 INT,
operatoration CHAR,
total AS CASE operatoration
WHEN '+' THEN number1+number2
WHEN '-' THEN number1-number2
ELSE number1*number2
END

) ;



I am going to insert few records to the table

insert into MyTable values(10,10,'+')
insert into MyTable values(20,10,'-')
insert into MyTable values(20,10,'')



Look at the result now


 Cool isn’t it?




I found one more interesting article on computed columns. http://www.mssqltips.com/tip.asp?tip=1682 Take a look at it.