Tuesday, 1 December 2009

Recently I've discovered a relatively new product from Microsoft for web development (Asp.Net or PHP) called Expression Web. The product itself looks more or less like Visual Studio with less options available ;)

The functionality that caught my eye was SuperPreview option. It allows developers to render the pages your working on using chosen browser engine within your development area. Available are all popular versions of IE and any other browser installed on your machine. It actually uses the real IE6 engine instead of any emulators. It also allows you to display the same page on multiple layers, each rendered using different engine. This allows you to find the differences much quicker.

There is also a separate version of SuperPreview which doesn't require Expression Web but it only supports IE. You can download it from here. Here is how my blog looks like when IE6 & IE8 overlay:

PS. I just wish that SuperPreview functionality was available in VS2010. The Expression Web seems as a new product only from marketing perspective. Its designer/developer area offers exactly the same options as in VS (code/design/split views), except the SuperPreview of course. Since VS already supports ASP.NET development, it would be logical to simply add PHP support to it instead of releasing a new product. When I asked tech guys from Microsoft they couldn't really explain this, which I think proves they think the same :)

Monday, 30 November 2009

According to Microsoft 70% of PHP developers are working on Windows, although the majority of PHP services are hosted on Linux (in my case this was actually true so maybe they are right about that). This leads to situation where most of the apps are being developed in an environment different than they are deployed to. This is obviously not the best way to that.

Microsoft claims there are 2 main reasons for that:

Installation process

Although there are many packages available for one-click installation of all necessary PHP components on Windows (e.g. WAMP) they are all configured to work with Apache server. Although IIS is recommended server to be used for PHP on Windows (to get most of what the system offers), developers are afraid of configuring/using it with their apps.

Microsoft decided to change it by introducing Web Platform Installer. This free tool will download, install and configure all components required to run web applications on your machine for you (both Asp.net and PHP). It also offers installation of popular OpenSource scripts/engines (e.g. for blogs, galleries, etc.) so you can start development faster.

This seems to be a step in a good direction and makes configuration of PHP and IIS easy like never before. However, there are still some some weak points in my opinion:

Developer is limited to one version of PHP (what if you need to install older version?)

The installer supports mainly Microsoft technologies e.g. drivers/extensions for MsSql. I haven't seen any option for installation of MySql extensions.

Some very popular php apps are missing e.g. phpBB (probably MS promotes an equivalent supported by them)

Performance

This one is actually more important than installation. Microsoft admits that PHP did not performed well on older versions of IIS. However, together with introduction of IIS7 most of the performance issues should have been resolved. The key aspects for improving performance are:

Microsoft contributed to creation process of PHP build for Windows e.g. rewritten parts of the code to make better use of the system

Implementation of FastCGI for Windows (can by installed with Web Platform Installer)

I asked the speaker about any reliable benchmarks comparing performance of PHP in Windows vs. Linux environment that would prove that it is worth considering deployment of my PHP apps to Windows. Unfortunately this strongly depends on the app itself so there is no simple answer to that question.

Soo, who's convinced?

BTW. When I asked the Microsoft guy about examples of large, commercial PHP applications deployed on Windows and performing well he answered that there are some but he's not allowed to name them ;)

Tuesday, 17 November 2009

Writing comments for your code is not the most interesting part of development. I admit that sometimes it's hard to follow company/project guidelines for code comments in a restrictive way, mostly because the lack of time (I know that's a pure excuse).

Some time ago somebody recommended me to use GhostDoc, which would take care of that for me. Tried it today - simple Shift+Ctrl+D combination and your code is fully commented. Some of the generated comments were even quite descriptive. After quick investigation I found out that all the descriptive comments were copied from base classes (e.g. when method overrides the one in the base class, implements interface member etc). For the new members the comments were generated basing on their names.

In my opinion this could be a handy tool if used correctly i.e. only for generating draft versions that would be corrected/extended manually. However, there is a great danger that most of generated comments would be left unchanged (especially if time is limited). Although it would cause all possible StyleCop rules to pass it would still affect the code quality. I will uninstall it right now because I don't want to be tempted when a deadline is close ;) We don't really need comments that don't introduce any new knowledge.

I'm wondering if there are any positive aspects of using them that I didn't think of? Are there any developers who admit that they're using them and can give some examples proving that this can be very useful?

Friday, 30 October 2009

CompareValidator, as the name says, is mainly used to compare value of specified control against value of another control, constant, etc. You can specify the operator that can be used in comparison so you are not limited to checking equality. The following example demonstrates simple comparison of int values (max > min):

Validating data typeExcept the basic functionality CompareValidator supports validation of data types. Except the regular operators (Equal, GreaterThan, GreaterThanEqual, LessThan & LessThanEqual) CompareValidator supports an additional one called "DataTypeCheck". It can be used to validate the type of provided value against the type specified in validator. The supported types are: String, Integer, Double, Currency & Date. The validator mainly checks the format of the provided value. In case of Date type it also checks the range (e.g. to ensure that 31st of April is not valid). I like this feature, especially that I've already seen a quite complex custom validator written to do exact this task. Example:

Using right formatWhen validating the type Asp.Net uses the current Page Culture. If you'd like only to accept inputs in specified format you can set the Page Culture property manually. The same date "11.30.2009" will be validated differently for UK and US Cultures (in UK "DD.MM.YYYY" is used, in US it's "MM.DD.YYYY"):

UK:

<%@ Page ... Culture="en-GB"%>

US:

<%@ Page ... Culture="en-US"%>

You can also set the page Culture from your code by overriding InitializeCulture() method:

Monday, 19 October 2009

I've deployed a WCF service to IIS with security mode set to "Message":

When I tried to called it from my client app I got the following error:

The HTTP request is unauthorized with client authentication scheme 'Anonymous'. The authentication header received from the server was 'Negotiate,NTLM'.

I googled out that this is caused by security settings of the service virtual directory. I configured it to use Integrated Windows Authentication rather than allowing Anonymous access. I did so because I wanted to restrict the access to my service.

Solution:It came out that using Anonymous Access in this particular case (WCF service in Message security mode) doesn't mean that anyone is allowed to use the service. The authentication is performed by WCF rather than IIS, but it still takes place.

Tuesday, 28 July 2009

By default the client-side validation is triggered when submitting forms using buttons. However, sometimes you may want to trigger client-side validation on your ASP page manually from custom Javascript. You can achieve that by calling Javascript validation functions provided by the ASP.Net framework directly from your custom code.

The following page source example displays a TextBox and its validation controls (RequiredFieldValidator & ValidationSummary). The validation controls have the same ValidationGroup defined, which allows us to validate different page elements independently. The page displays also a DIV element that will cause the Validation action when clicked:

Friday, 3 July 2009

Recently I needed to convert an Array of DictionaryEntry<object,object> items into a Dictionary<string,string> object. Here is simple code using LINQ and ToDictionary method for doing that with 1 command:

Friday, 26 June 2009

Windows could not start the IIS Admin Service on Local Computer. For more information, review the System Event Log. If this is a non-Microsoft service, contact the service vendor, and refer to service-specific error code -2147417831.

Event log is not much help:

The IIS Admin Service service terminated with service-specific error 2147549465 (0x80010119).

Solution:Kill the inetinfo.exe process and start IIS again - that's it :)

Thursday, 18 June 2009

In one of my previous posts I've already mentioned how to handle exceptions that occur within UpdatePanel on client side (see post). However, this did not cover server side error handling nor multiple UpdatePanels on one page.

Sometimes you may want to have on your ASP page multiple update panels or a large one containing multiple controls. The problem is that when an error occurs on update action you may find hard to localize the actual control that generated the error causing event. This may be required in some situations e.g. to display error message next to the control responsible for the exception.

Let's take a look at some code. Here is a sample ASP page with a ScriptManager and 2 UpdatePanels. Each of the panels contains a button and a label for displaying errors:

Clicking on any of the buttons will cause an Exception. The exception message varies for each button. In my example the error handler for script manager does nothing but you can do whatever you need with the caught error e.g. log it.

Now, let's handle the error on client side. The following code will register client side error handler, which will display a message from the thrown exception next to appropriate button:

function EndRequestHandler(sender, args) { // If there is an unhandled error if (args.get_error() != undefined) { // Get id of the control that fired the error-causing action var senderControlId = sender._postBackSettings.sourceElement.id;

// Get Label next to the source control var errorLabel = document.getElementById(senderControlId). nextSibling.nextSibling;

// Set error message in appropriate control. // You may want to remove the user-unfriendly part of the // message that was added by Script Manager errorLabel.innerHTML = args.get_error().message.replace ('Sys.WebForms.PageRequestManagerServerErrorException: ', '');

Thursday, 11 June 2009

Recently I decided to add Adsense ads on my blogger page to earn zillions of $$$$. Blogger dashboard offers easy to use Adsense integration (Monetize tab). It helps you to create Adsense account and automatically places the ads on your blog page. The problem is that it doesn't offer much control over the way the ads are displayed, soe you can't e.g. center your ad, align it in to the right etc. To achieve that you'll need to create the ad manually through the Adsense page (see Adsense help) and then paste the code into your blogger template:

From blogger dashboard got to: Layout > Edit Html

Check the "Expand Widget Templates" checkbox to see the detailed view of your template

Find the place in the template where you'd like to place the ad.

Create a div element that would store your ad and style it as much as you want (center it, add padding, etc.)

Monday, 4 May 2009

A piece of code that I've been working on lately started to throw exceptions when calling a web service using a generated client. The log file contained only the exception message:

"The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state."

Most of the suggestions found in Web blamed the invalid code, giving examples similar to the following one:

using (MyWebServiceClient service = new MyWebServiceClient()){ service.DoSomeOperation(); service.Close(); service.DoAnotherOperation();}

Since I was sure this was not the case I had to discover the real exception reason by myself.

Solution:

The using statement in the form presented above will mask any errors coming from the web service client and throw the "faulted state" exception instead, which may be irrelevant to the actual problem. To find out the real issue you can examine the InnerException property of the exception thrown (e.g. by logging it or debugging your app).

Alternatively you can add an additional try/catch to ensure that the real exception is thrown by your application rather than the "faulted state" one:

Tuesday, 14 April 2009

I'm recently working mainly on .NET projects but would like to stay on top of Java technology stack as well. That's why I've just joined the Java Black Belt community.It offers many free java exams created by community users. In order to get the black belt you need to contribute to the portal so the amount of testing material is still growing. It's a great way to refresh your java knowledge. I hope that this belt-system will keep me motivated so I not only prove my current skills but also learn something new. After I get to the certain level (let's say the blue belt) I'll update my blogger profile to display the belt icon so you can see my progress directly from this page.

Tuesday, 24 March 2009

Recently I attended C2C conference in Warsaw. I signed up for the .NET track. The session I was really looking forward to was “Hardcore Production Debugging” by Ingo Rammer. I hoped to learn something that I could use right away in my every day work. Remote debugging may be very painful and it is not easy to find the best approach. I was keen to learn about new easy-to-use tools that would make my life much easier. Unfortunately, the word “Hardcore” in session’s title was there for a reason…

The biggest part of the session was dedicated to WinDBG tool. Its interface is very poor and user-unfriendly. However, Ingo demonstrated that once you learn how to use it, it can be very helpful in finding the reason for application failures.

At first Ingo simulated situation where the developer has access to production machine (with no Visual Studio installed) where they can run WinDBG. Once he started this tool he attached it to the process of sample application that was throwing unhandled exceptions. With a few commands he was able to find out the exception message and the reason for failure. With the same tool Ingo was able to find out the reason for unexpected application exit by attaching breakpoint at the end of app’s process.

Ingo showed us also that remote debugging can be achieved with the WinDBG installed on developers machine and its console version – CDB – on client’s machine. After you configure the port for CDB you can access it from outside using WinDBG (option “Connect to remote session”).

Next, Ingo explained what to do when WinDBG and CDB are also not available on the production machine. He proved that we can find the same error as in the first part by studying the memory dump created for that application. To get the memory dump we can ask the client to create it manually using a simple program (Adplus) or OS built-in functionality (only on Vista) immediately after the error occurs. Then, all we need to do is load the dump into WinDBG (option “Open crush dump”) on the developer’s machine and examine it using the same commands as in the first case.

Finally, Ingo presented simple program GFlags for Windows registry keys modifications that would allow launching CMD/WinDBG immediately after specified process is started and attaching the debugger to this process. This can be handy when an error does not occur regularly and it’s not easy to reproduce. He warned us that you have to be very careful when using that tool and change system’s default settings only if you’re absolutely sure what you’re doing. Registry modifications can cause a lot of damage to your OS if the are not done correctly.

To sum up - the pase of presentation was high so it was not possible to learn all the commands that Ingo was using. The goal of this session was to show to the audience what is possible if we use the presented tools and that it doesn't require much work once you learn how to use them.

The session itself came out to be the highlight of the conference. Mixture of Ingo’s knowledge and charm proved to be the formula for perfect presentation. I just wish Ingo had some more time so we could study the examples more carefully.

Wednesday, 4 March 2009

As mentioned in my previous post I'm using Syntax Highlighter now to display code snippets. Appart slow loading it's working fine and it's doing its job. The only thing that was annoying to me was that the highlighter's toolbar was covering part of the first code line if it was too long:

Solution:Solution is quite simple: I decided to lift it up a bit by overwritting toolbar's style:

Place this style definition anywhere in <head> and the result should be similar to that:

To be honest, I would like the toolbar to be displayed below the code snippet, aligned to the bottom border but this would require bit more styling. Let me know if you achieve that!

Monday, 2 March 2009

I decided to adjust the way I display code snippets on my blog. The old way of displaying wasn't very good and required some additional formatting. I've found a perfect solution for that: Syntax Highlighter. This allows you to easily display code snippets in a nice and accessible way. The code is colorised according to its type: e.g.

Sunday, 1 March 2009

Recently one of my old php apps was moved to different server.After the move it came out that some pages didn't work as expected i.e. some redirections were failing. The redirections were implemented using header function e.g.

header('Location: http://www.targetpage.com/');

When I checked the php logs I found common error "Headers already sent". Don't want to explain here what does it mean - there's plenty of answers here ;) The only thing that made me wonder was why it was working on the old server. When I compared the php.ini files from both servers I found out that the new one was configured not to useoutput buffering. The temporary fix was enabling this by setting in php.ini:

output_buffer=On

This is not the cleanest solution and may affect application's performance but works immediately. The long-term solution is to ensure that your app is not sending any output before calling the header method.

Friday, 20 February 2009

Copying entire folder content (with subfolders) using standard MsBuild is not as straightforward as I'd imagine this to be. The only solution I've found uses recursion. Following example copies all files from source to dest folder:

Thursday, 19 February 2009

Sometimes, when buidling/deploying your projects standard MsBuild tasks are not enough. I've found a very handy SDC tasks library which allows you to do much more from your build script.

The following example demonstrates creation of application pool and website using this AppPool on IIS. Normally this would need to be done manually. Thanks to SDC we can automate the whole process to eliminate possible errors that can occure during manual deployment.

Wednesday, 11 February 2009

I had a problem with asp.net app losing session data. The same app was working like a charm on my local machine but after deploying to dev server it was throwing exceptions from time to time caused by missing session variables.

My webapp was using default sessionState settings with mode set to 'InProc' and it was configured to use default application pool. The problem was caused by the application pool using Web Garden with 5 worker processes. When using InProc mode the worker processes DO NOT share session data!

Monday, 9 February 2009

Sometimes you want to ensure that your settings (e.g. connection strings) in web.config file are encrypted so nobody except the app iteslf can read/understand them. ASP.Net offers tool called aspnet_regiis which allows that. It can be found in the %WINDOWSDIR%\Microsoft.Net\Framework\version directory.

Solution:Let's say we have a web app deployed on IIS called 'MyApp'. The app uses connection string defined in web.config:

The encrypted information in the web.config can still be accessed by your app without any explicit decoding. Aspnet_regiis tool can be also used to descrypt information, encrypt different sections etc. You can learn more about it here.

WarningIf the encoding succeeds but tha app cannot read the encrypted section because of following error: "Failed to decrypt using provider 'RsaProtectedConfigurationProvider'. Error message from the provider: The RSA key container could not be opened."

If the code executed during update causes an error the browser may warn you about JS error (caused by actual server side error) but the panel will remain faded out. Browser's warning is usually hard to notice or even not displayed at all.

Solution:The following JS code allows you handling update errors on client side. It assumes that there is a span element defined on that page for displaying error messages (with ID=ErrorMsg).

Monday, 2 February 2009

I have an aspx page using standard FileUpload control. When I tried to upload a file bigger than 4MB the page was not displayed or the following error message appeared: "Maximum request length exceeded". This is caused by maximal allowed size of request accepted by the server. Since the uploaded file is sent in request's body the whole request is even bigger than the file itself.

I've seen some solutions using Application_Error handler defined in Global.asax. This approach is quite straightforward and seems to be a way to go but unfortunately it didn't work for me - the page was still not displayed and the error was not handled.

Solution:First, set the size of request accepted by the server to maximum (1GB) in web.config. Then, define a custom HttpModule that would check request's length (also in web.config):

I've found this piece of code here. It works perfect. The only thing I don't understand is why the whole request needs to be read for this to work? I've tried to make the redirection right after wr.GetTotalEntityBodyLength(); but it didn't work. Anybody knows why?

Sometimes you want to disable all page elements at one time. There are many ways to achieve that. I'm using an additional div displayed on the top layer of the page. It covers the whole page content and makes clicking elements on lower layers impossible. The div can be totally transparent so the user still sees the content of the lower layers.

First, you need to place the additional div on your page, right behind the <body> tag:

...</head><body> <div id="disablingDiv" ></div>...

Then, you need to create appropriate style for that div. This element needs to be displayed on the top layer:

#disablingDiv{ /* Do not display it on entry */ display: none;

/* Display it on the layer with index 1001. Make sure this is the highest z-index value used by layers on that page */ z-index:1001;

Now it is ready to use but not displayed. If you want to enable the div (to disable all underlaying page elements) just invoke the following JS code:

document.getElementById('disablingDiv').style.display='block';

To disable it again:

document.getElementById('disablingDiv').style.display='none';

You can also play with background color and opacity to create different effects. The div itself can contain some additional elements e.g. button allowing enabling, pictures, etc. I've created this simple style basing on more complex example of lightbox described here.

Thursday, 22 January 2009

Strangely guys from Microsoft did not implement (forgot???) support for optgroup tag in their standard DropDownList asp control so it's not possible to group items on the list.

Most of the workarounds found in Web suggest use of Control Adapter, like this one. However, there are couple things I don't like in this solution:

Doesn't work correctly when DataSource, AutoPostBack or OnSelectedIndexChanged attributes are set

Overrides regular regular behaviour & rendering of DropDownList items

Works for all DropDownList controls on the page (cannot be switched off for some lists)

Instead, I propose to create our own custom control that extends the standard DropDownList class. We need to override the method RenderContents inherited by DropDownList from System.Web.UI.WebControls.ListControl. When overriding it is very useful to base on original implementation so the default behaviour is preserved. To get the original RenderContents method's code you can use .NET Reflector:

Saturday, 17 January 2009

I'm using standard ASP.NET FileUpload control and had some troubles changing its width. For almost all browsers the regular width attribute does the job (as expected). However, for some strange reasons it is completely ignored by FF.

Solution:To change the width of FileUpload control in FF you have to use size attribute instead. Example:

<asp:FileUpload ... size="50" />

The units used by size attribute are characters. Remember to use both size (for FF) and width (for all other browsers) to make the change visible for all users. Sometimes it may be tricky to make this field have the same width on all browsers.

I'm not sure why Mozilla did it this way but I don't like it at all. Any Ideas?