Tuesday, April 13, 2010

Extreme intellisense

Scott Guthrie's team is working on technology that allows to build intellisense based on executing underlying JavaScript code.
It's not available in Visual Studio yet, but looks like it would be available soon.

Sunday, April 11, 2010

Cast from float to double error

I was surprised to find out that this line of code fails:

Assert.AreEqual(0.1d, (double)0.1f);

(double)0.1f is actually the same as ... drumbeat ... 0.100000001490116

Why does it happen?
Because float and double do NOT represent fractions precisely.
Rounding is always going on.

How to deal with this?
There are several options:
1) Round double after converting float number into it.
For example:

float f = 0.1f;
double d = Math.Round(f, 8);
would assign 0.1d to d.

2) Don't use float/Single and use double only.

double d = 0.1;
would assign exactly 0.1d to d.

3) Use decimal or bigdecimal if you are dealing with money.

decimal m = 0.1m

Hope it helps.

Saturday, January 23, 2010

ASP.NET: MVC Framework vs Web Forms Framework

It looks like "MVC vs Web Forms" debate heats up.

Here's my take on it:
1) Last time I checked, MVC required 50+% overhead (relative to Web Forms) in terms of the amount of code required to implement the same functionality.
Was that fundamental problem fixed yet?

Let's consider an example of business requirements:
Create a page that allows user enter text, click "Save" button, and then call existing business layer method BusinessLayer.Save().
With Web Forms approach it would take:
- 1 line of ASPX code for textbox
- 1 line of ASPX code for Save button (including Save_Click() call).
- 3 lines of code-behind:
void Save_Click() {
BusinessLayer.Save(Input.Text);
}
Total: 5 lines of code.

How many lines of code that task would get in MVC?

2) Now about why it's important to minimize number of lines of code:
Lines of code is the best available metric of project complexity.
Yes I know that different lines have different complexity attached to it, but by default I assume that complexity of Web Forms’ line is about the same as complexity of MVC's line of code.

3) Many developers say that it's good to know MVC even if you don't use it (just to be familiar with available options to be ready to jump on it).
I agree. Sort of.
The trick is to know what to learn. There are so many technologies out there so it's not possible to learn them all.
How do I know that MVC would have good return on my time invested?
I don't know it yet. Many developers are passionate about MVC, but relying just on buzz around new technology methodology is too risky: for example, RUP (Rational Unified Process) is nowhere now after all that buzz 10 years ago. Learning it (aside of the most basic concepts) would be mostly waste of time.
And lines of code overhead really kills my enthusiasm about MVC.

I'm open to change my mind though. Especially considering that MVC is getting more mature every year.

See also: Scott Guthrie chimed in with great "About Technical Debate" post and even better follow up comments about advantages of Web Forms vs Advantages of MVC Framework

-

Saturday, September 26, 2009

Unable to obtain public key for StrongNameKeyPair

You are using Visual Studio 2008 (SP1 or not -- doesn't matter).
You have test project that is signed with strong key and that strong key has a password on it.
You are trying to create a unit test for private method and are trying to create accessor.
You have an error like that:
"Creation of the private accessor for Xyz failed"

You have that error because you excluded "Test References" folder and YourProject.accessor file from your test project.

The reason why you excluded YourProject.accessor file from your project is that you were getting a compilation error:
"Unable to obtain public key for StrongNameKeyPair".

The reason why you are getting that error is that VS 2008 SP1 and even VS 2010 Beta 1 have a bug.

Workaround for that bug is to turn off strong key signing on your test project.

Read more here:
Unable to obtain public key for StrongNameKeyPair

Friday, May 29, 2009

SQL_Latin1_General_Cp850_BIN

While working on Auto-Moderator for PostJobFree.com I encountered the following problem: my C# code considered ‘3’ and ‘3’ as different words, but SQL Server considered them the same.
That expressed itself in the following error:
Cannot insert duplicate key row in object 'dbo.Word' with unique index 'IX_Word'.

That was a little bit surprising, considering that I defined Word as Unicode column (nvarchar).

While searching for the solution, my first thought was to make 'IX_Word' index not unique. That worked, but would have introduced other problems with spam filtering business logic down the road.

The solution should have been about making SQL Server to compare strings exactly the same way C# code does.

I started to look into SQL Server Collations, and finally found the solution: use SQL_Latin1_General_Cp850_BIN collation.

Basically the solution is about to declaring 'Word' column with SQL_Latin1_General_Cp850_BIN collation:
Create Table Word(
WordId bigint identity(1,1) not null,
Word nvarchar(50) COLLATE SQL_Latin1_General_Cp850_BIN not null,
JobPostCount int not null DEFAULT 0,
JobLogSpamCount int not null DEFAULT 0,
CreateDate datetime not null,
UpdateDate datetime not null,
CONSTRAINT PK_Word Primary Key Clustered
(
WordId ASC
)
)
GO

Create Unique Index IX_Word ON Word
(
Word
)
GO

Possible drawbacks of the solution: using SQL_Latin1_General_Cp850_BIN collation may cause weird sorting in SQL queries, but sorting collation can be easily redefined like this:
select * from Word
order by Word COLLATE SQL_Latin1_General_CP1_CI_AS


Moreover, the sorting it provided by binary collation (SQL_Latin1_General_Cp850_BIN) looks quite reasonable.

You may also use SQL_Latin1_General_Cp850_BIN2 collation for better sorting.


Here’s SQL sample to you to play with:
--drop table t;
select N'3' as Word
into t;

insert into t
select '3' as Word;

select * from t
where Word = N'3';

select * from t
where Word = N'3'

select * from t
where Word = N'3' collate SQL_Latin1_General_Cp850_BIN;

select * from t
where Word = N'3' collate SQL_Latin1_General_Cp850_BIN

Enjoy!

Sunday, April 05, 2009

web.config in IIS 7.0

IIS 7.0 treats Web Application differently from how IIS 6.0 treats Virtual Directory connected to Application pool.
The difference is in how web.config properties are inherited from parent application.
If Virtual Directory in IIS 6.0 is physically located outside of parent web application, then web.config properties are not inherited. Even if logically Virtual Directory is inside parent web application.
So, even if from end user URL looks like this:
http://www.parentwebapp.com/virtualdirectory -- virtualdirectory web app does not inherit web.config properties from parentwebapp.com

IIS 7.0 is smarter than IIS 6.0.
Even if parentwebapp.com and virtualdirectory from above example are mapped to different physical folders like this:
http://www.parentwebapp.com/ -- c:\parentwebapp
http://www.parentwebapp.com/virtualdirectory/ -- c:\virtualdirectory

IIS 7.0 still recognizes that http://www.parentwebapp.com/virtualdirectory/ inherits all web.config settings from http://www.parentwebapp.com/

Such inheritance sometimes causes undesired effects.
For example, if you added HttpModules to parent web app code, but didn't add them to child virtual directory, you may end up with "Could not load type ..." run-time error.

In order to get rid of this error you need from inherited settings.
You can do it like this:

<system.web>
<httpModules>
<remove name="DenyIpAddressModule"/>
</httpModules>
</system.web>
<system.webServer>
<pages theme="">
<modules>
<remove name="DenyIpAddressModule" />
</modules>
</system.webServer>

Note, that in this example I remove "DenyIpAddressModule" twice.
The reason for that is that I added "DenyIpAddressModule" module to parent web.config twice: once as regular httpmodule, and another time as integrated pipeline module.

Wednesday, April 01, 2009

Google Maps API team joke

Google Maps API rolled out unpleasant joke on April 1st day.
Google Maps javascript stopped working today.

There is a quick fix available: switching back to older, more carefully tested version.
(from "v=2.x" to "v=2").

There is a good lesson here: don't use the latest "bleeding edge" version of the code in production environment. Even if it comes from Google.

Technical details are here:
http://groups.google.com/group/Google-Maps-API/browse_thread/thread/193fbebd8066f19f/7fecbfed5908d29e

Followers

About Me

My photo
Email me: blog@postjobfree.com