BeFruit

Monday, September 8, 2008

WCF error: "This collection already contains an address with scheme http"

I met this error, and wondered what this could be. The explanation is that "WCF services hosted in IIS can have only one Base Address", meaning that in IIS the website hosting the service can not be associated to http://www.example.com and http://example.com at the same time.

I don't know why this prevents a service to work, but I know this is annoying.
I found a couple of bloggers like Rob suggesting a solution with a coded custom ServiceHostFactory, which sounds terribly complicated to me as a workaround.

Fortunately there is a much simpler solution, just by touching the web.config file. Just add the following lines in the system.serviceModel section:
<serviceHostingEnvironment>

    <baseAddressPrefixFilters>

        <add prefix="http://www.example.com"/>

    </baseAddressPrefixFilters>

</serviceHostingEnvironment>

to only keep the service address.

Labels:

Tuesday, July 22, 2008

Clone objects in C#

It is simple to clone objects (i.e. make an exact copy of an object) that implement the IClonable interface. It has the Clone() method that you just have to call.

When the method is not available and the class is serializable (has the Serializable attribute), it is possible to use this feature. There are some examples over the Internet, here is a variant I adapted as a templated method:
private static T Clone<T>(T original)
{
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
bf.Serialize(ms, original);
ms.Flush();
ms.Position = 0;
return (T)bf.Deserialize(ms);
}

You call it this way:
MyClass copy = Clone<MyClass>(original);


But what to do with a non serializable object? The only way is to use reflection. Here is a simplified but working example. One should take care of readable and writable properties.
private static T Clone<T>(T original)
{
T copy = (T)(typeof(T).GetConstructor(System.Type.EmptyTypes).Invoke(null));
foreach (PropertyInfo pi in typeof(T).GetProperties())
{
object originalValue = pi.GetValue(original, null);
pi.SetValue(copy, originalValue, null);
}
return copy;
}

Labels:

Friday, May 30, 2008

Corrupted applicationHost.config file in IIS 7

IIS7 stores its parameters in an XML file, located typically at C:\Windows\System32\inetsrv\config\applicationHost.config. This is a nice solution as every parameter is clearly readable. Unfortunately, there are still some bugs (maybe in IIS 7, but some problems with anti virus programs have also been reported) and this file may be corrupted.
What to do when this file is truncated? Reset it and loose all of your settings?
Luckily IIS makes a backup each time you make a change. All those versions are stored in the folder C:\inetpub\history\. All you have to do is to copy a former applicationHost.config file into the C:\Windows\System32\inetsrv\config\ working directory.

Labels:

Wednesday, May 7, 2008

WPF is all about Panels

Have you noticed how most applications' windows behave badly when it comes to adapt their dimensions to content or screen size? When you resize a window, only the center resizes and the other elements (toolbars, menus, ...) remain unchanged. Most popups have fixed size. It is true for local applications and also for HTML pages. HTML is supposed to be flexible and adapt its layout to content, but in real life, it is really difficult to control how HTML behaves. Apart from fixing elements' size, the result is unpredictable.

Fortunately today we have XAML, and the numerous Panels. Panels are in my opinion the most important contribution to complex application screens. But not every panel is equally useful. Forget about Canvas, which is the old fashioned way of placing element giving coordinates. It is all but flexible. Even the Grid panel that represents a table of cells is not as flexible as my favorite: the DockPanel. It fills up the window space starting from borders, and leaving the center for the main content. Be sure to fully understand how each kind of panel behaves, to be able to choose the correct one. Other useful panels are StackPanel, WrapPanel, ...

Panels come with another important notion: min/max width and height. Instead of fixing a column width, set its MinWidth value. It ensures that it will not render too thin if empty. Avoid at all cost fixing Width or Height, as you never know on what screen your application will be displayed. Test your interface with few or plenty of data, on tiny or huge screens. It should look great in every situation. Panels make it possible.

Labels: ,

Thursday, April 17, 2008

WCF on Vista raises an AddressAccessDeniedException

I was trying the example from the excellent book by Michele Leroux Bustamante about WCF, and cound not start them getting the exception AddressAccessDeniedException on ServiceHost.Open().
The solution is to start a console as an administrator (right click on the cmd.exe icon and select "Run as administrator") and execute:
netsh http add urlacl url=http://+:8080/ user=username
  • The + is a wildcard for any domain
  • 8080 is the port I used for my WCF services, use your own
  • username is the user you logged in with, and can be preceded by DOMAIN\username
The problem happens only on Vista (and probably on Windows Server 2008) and not on former systems.

Labels:

Wednesday, April 2, 2008

WPF is the future of HTML

I think that all the demos that can be found about WPF and Silverlight are wrong. They are showing how you can make funky animations, include videos and gradient colors everywhere.
But we are professionals and what our clients need is a powerful and robust client, so let's make classical layouts with normal checkboxes and tabbed screens. Nobody needs 3D interfaces where you have to scratch your head to guess how to use it.

Former HTML interfaces were poor and fragile, mixing many languages and standards. How to validate an e-mail input control? Add a server-side validation after postback or use Ajax? Or write a custom JavaScript? Do it on control blur or on keypress? Depending on the context, one of these solutions may do the job so you end up mixing all of them.

With WPF and XBAP, everything is clear. Keep all the client logic on the client, and in the same language as the rest of your code: C#. If you need some info from your database, call a remote procedure using a Web Service. Designing a perfect interface has never been easier: use panels wisely and drop your controls. Bind the numerous events to your actions and the result is there.

I intentionally did not talk about Adobe Air, which is having a similar approach to the light client problem. It is clearly promising and the example you can find on the Internet are much better and mature than those of WPF. However, even if Flash will keep its advance compared to Silverlight, the fact that Adobe Air uses JavaScript and the efforts Microsoft put into WPF makes me think that it is the right choice to make for most client developments.

Labels:

Friday, March 21, 2008

COMException when opening WebApplication project

I recently go the following error while opening a Visual Studio solution: "System.Runtime.InteropServices.COMException". Not very explicit, is it?

I found a page in VisualStudio feedback explaining that this is a bug in Visual Studio 2008, that should be corrected "in the next release"...

The explanation is that VS is trying to locate your Web Application in IIS. Look into your project file *.csproj in the <WebProjectProperties> section, the searched URL is indicated in the <IISUrl> tag.

The solution is simple: in the <UseIIS> tag change "True" to "False" and your project will open like a charm.

Labels: ,