Dev Blog - Johan Danforth
I'm Johan Danforth and this is my dev blog - a mix of .NET, ASP.NET, Rest, Azure and some other random coding stuff.
-
WCF Client Calling ASMX Service with Soap Headers
Need to send soap headers from WCF (Service Reference) clients to older ASMX services? The ASMX service not handling the header properly? It may have to do with namespaces being set in the soap header XML in a way differently from what the ASMX service is expecting.
So, how do you create and add the same type of headers, with the correct namespace, in a WCF client? For every outgoing call?
First, a simple ASMX service for your pleasure to play with:
[WebService(Namespace = "http://tempuri.org/")]
public class Service1 : WebService
{
public MyHeader myHeader;
[WebMethod]
[SoapHeader("myHeader")]
public string HelloWorld()
{
if (myHeader != null)
return "Got header: " + myHeader.MyFirstValue + " " + myHeader.MyOtherValue;
return "Got no header!!";
}
}
That's it on the server side. Over to the client side... Well, the header itself can be either a class which implements the MessageHeader class, but I prefer to use a normal class decorated with DataContract attribute. Notice the namespace property which matches the one on the service above:
[DataContract(Namespace = "http://tempuri.org/")]
public class MyHeader
{
[DataMember]
public string MyFirstValue { get; set; }
[DataMember]
public string MyOtherValue { get; set; }
}
In ASMX clients you normally create a soap extension to add the header to every outgoing call, but here the ASMX soap extension is replaced by a (Client)MessageInspector in WCF, which is added to a client endpoint via a behavior. I'm cramming the whole sample implementation into one class:
public class AddSoapHeaderBehavior : BehaviorExtensionElement, IClientMessageInspector, IEndpointBehavior
{
#region IClientMessageInspector Members
public void AfterReceiveReply(ref Message reply, object correlationState) { }
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
var myHeader = new MyHeader { MyFirstValue = "Yeeehaaaw!!", MyOtherValue = "Gaaah!" };
var messageHeader = new MessageHeader<MyHeader>() { Actor = "Anyone", Content = myHeader };
request.Headers.Add(messageHeader.GetUntypedHeader("MyHeader", "http://tempuri.org/"));
return null;
}
#endregion
#region IEndpointBehavior Members
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { }
public void ApplyClientBehavior(ServiceEndpoint serviceEndpoint, ClientRuntime behavior) { behavior.MessageInspectors.Add(this); }
public void ApplyDispatchBehavior(ServiceEndpoint serviceEndpoint, EndpointDispatcher endpointDispatcher) { }
public void Validate(ServiceEndpoint serviceEndpoint) { }
#endregion
#region BehaviorExtensionElement Members
protected override object CreateBehavior() { return new AddSoapHeaderBehavior(); }
public override Type BehaviorType { get { return GetType(); } }
#endregion
}
The endpointbehavior and behaviorextensionelement member implementations are just boilerplate stuff that should be hidden as default behavior by WCF if you ask me, but you need to type this out.
Finally, the behavior must be loaded in the config (or via code):
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="MyEndpointBehaviors">
<ClientSoapHeaderAdderBehavior />
</behavior>
</endpointBehaviors>
</behaviors>
<extensions>
<behaviorExtensions>
<add name="ClientSoapHeaderAdderBehavior"
type="MyBehavior.AddSoapHeaderBehavior, MyBehavior, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</behaviorExtensions>
</extensions>
<client>
<endpoint name="Service1Soap"
address="http://localhost:4221/Service1.asmx"
binding="basicHttpBinding"
behaviorConfiguration="MyEndpointBehaviors"
contract="ClientProxy.Service1Soap" />
</client>
</system.serviceModel>
</configuration>
Hope it helps someone.
-
WPF Learnings - Animated Screen Glint Effect
To learn some WPF I wrote this full screen editor called Writespace, which is now open source on Codeplex. I wanted to add some bling to the editor when it was loaded up, so I created a simple animated "screen glint" effect which is totally useless but looks kind of nice (IMHO). Basically it's a semi-transparent gradient, in a rectangle, on a canvas, the size of the screen, which animates over the screen from left to right.
I had a question about the best way to do this over at Stackoverflow, so check it out if you want some sample code which produces the test-output you see above (which is in mid-animation :)
-
LINQ to XML in VB.NET and Using the Right Language for the Job
I'm almost always using C# in my .NET projects, unless I'm doing Office automation where the VB-way of dealing with optional parameters helps out making the code a bit cleaner.
The last week we've been upgrading ASMX-clients to become WCF-clients for a number of old .NET 1.1 and 2.0 projects, and we ended up with a bunch of app.config files with loads and loads of WCF client endpoint sections, each of them pointing at their own binding configuration. To manually clean this up would take hours and hours of tedious work which would probably result in more than a few errors.
So I thought maybe I could do search/replace with a regexp-capable editor... or try out XML Literals in VB.NET. I wanted to remove old behaviors, extensions and bindings, then add my own behaviors and extensions and finally change some attributes on each client endpoint. Doing this with XML Literals and XDocument/XElement in VB.NET was quite straight forward and didn't result in too many lines of code:
Imports System Imports System.Xml.Linq Imports System.IO Imports System.Linq
Sub FixupConfig(ByVal infile As String, ByVal outfile As String) Dim defaultBindingConfigurationXml = <binding name="defaultBindingConfiguration" maxBufferSize="1065536" maxBufferPoolSize="524288" maxReceivedMessageSize="1065536"/> Dim behaviorsXml = <behaviors> <endpointBehaviors> <behavior name="FacadeSoapEndpointBehavior"> <SetMaxFaultSizeBehavior size="100000"/> <ClientExceptionHandlerBehavior/> </behavior> </endpointBehaviors> </behaviors> Dim extensionsXml = <extensions> <behaviorExtensions> <add name="SetMaxFaultSizeBehavior"
type="SomeType.SetMaxFaultSizeBehavior, SomeAssembly, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=null"/> <add name="ClientExceptionHandlerBehavior"
type="SomeType.ClientExceptionHandler, SomeAssembly, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=null"/> </behaviorExtensions> </extensions> Dim xdoc = XDocument.Load(infile) xdoc...<system.serviceModel>.<behaviors>.Remove() xdoc...<system.serviceModel>.<extensions>.Remove() xdoc...<system.serviceModel>.Single().AddFirst(extensionsXml) xdoc...<system.serviceModel>.Single().AddFirst(behaviorsXml) xdoc...<system.serviceModel>.<bindings>.<basicHttpBinding>.Descendants.Remove() xdoc...<system.serviceModel>.<bindings>.<basicHttpBinding>.Single().Add(defaultBindingConfigurationXml) Dim elems = xdoc...<client>.<endpoint> For Each element In elems element.@bindingConfiguration = "defaultBindingConfiguration" element.@behaviorConfiguration = "FacadeSoapEndpointBehavior" Next xdoc.Save(outfile) End SubI've heard people recommend to use VB.NET when dealing with XML and I agree - use the right language for the job. When doing this - remember to import System.Linq or you'll miss some vital extensions like the .Add() and .Single() methods ;)
-
Windows Home Server Learnings - Don't Install the HP Add-Ons
This is a general warning to Windows Home Server owners in general and HP Media Smart Server owners in particular. The "Power Pack 1" update to WHS comes with 2 add-ons:
- McAfee’s Total Protection Service (anti-virus/anti-malware)
- PacketVideo’s PVConnect Media Server (media sharing)
But unless you've gone through the hard work to actually upgrade the memory from 521MB to 2GB, don't install these add-ons because you may end up with a totally unusable home server. The hardware just isn't up to it! PVC alone requires 512 MB.
I actually tried to installed PVConnect and the first thing I noticed was that the WHS Console was quite non-responsive and sluggish it it's behavior. Then I clicked the PVConnect "tab" and got this, in spanish!?!
After a while I got tired of it and went to install it, which wasn't easy because of the non-responsive console. Eventually I got rid of it, but not without blood shed:
Like the missing/transparent/black features? :) Anyway, I clicked the white (that I presume said "OK") button and the Console got reset. Now I was soon greated by the "Your WHS Network is at Risk" notification:
What risk? I log on to the WHS and to see what's wrong:
This health warning thingy in WHS is not making sense to me. What is there to warn about? Will this list be a mile long in a year? I need to clean this list up... does anyone know how to do it? BTW. The AV software on my mediacenter server IS NOT out of date...
There's a good story about this on Rafael's Within Windows blog.
-
Writespace - Fullscreen Writing Environment Add-in for Word
I just published this open source project on Codeplex, and this information is available on the Writespace Codeplex home page as well.
Writespace is a fullscreen writing environment, developed with WPF (Windows Presentation Foundation) as a ClickOnce installed add-in for Word 2007 . Unfortunately Codeplex cannot host ClickOnce applications, so to install the add-in you will have to download and run the installer locally until I've found a site to host it.
Writespace is inspired by Dark Room (http://they.misled.us/dark-room) for Windows and Write Room (http://www.hogbaysoftware.com/product/writeroom) for OS X. One advantage of Writespace is the built in spellcheck support (English, French, Spanish and German).
The program is quite simple, but I've been missing a plug-in for Word like this one. I've been using the excellent Dark Room editor, but unfortunately it doesn't have support for spell checking or Word integration.IMPORTANT NOTE
Always, always, always keep a copy of your orginal document or text before you try out or use Writespace so you can revert if things go bad. Writespace is work in progress and has not yet been tested enough to be called "stable".System Requirements
NOTE: I need help with specifying the requirements to run this, but personally I'm on Vista, .NET 3.5 SP1 and Word 2007.
Downloads and Installation
The add-in is installed as a ClickOnce application, but it's not possible to host ClickOnce installers on Codeplex, so you will either have to download the binaries as a zip or download the source and run it from Visual Studio 2008.Shortcuts
Writespace supports the following shortcuts from within the writing environment:
CTRL+Mousewheel - Zoom in/out
CTRL+F - Search
F3 - Find next
CTRL+G - Go to line
ESC- Exit to Word
CTRL+S - Save
Writespace also supports the standard Undo/Redo/Select/Cut/Paste functionality you are used to.Word Integration
Writespace is started from the View-tab of the Word 2007 Ribbon, just click the "Writespace" button and the text of the current document is grabbed and put into the Writespace full screen editor. When you escape from Writespace, the text in the Word document is updated with the text from Writespace. Note that Writespace removes all formating of the text, so italics, font size, bold text, is removed and converted into the font, color and size Writespace uses. Word documents containing tables, pictures and other "non-text" content will not be possible to move to the Writespace editor, and you will get an error dialog if you try this. This is to protect you from messing things up.Text Formatting
Writespace does not have any support for formatting the text. You can select the size, color and type of font, which will affect the whole editor, but that's it. This may change in the future though. Note that if you enter the Writespace editor from an existing document in Word, the formatting of that text will be removed and converted to plain Writespace text.Spell Check
Writespace uses the built in spell checking support which comes with WPF. Language is set from the options dialog. Unfortunately WPF only supports English, French, German and Spanish at the moment. If you still want to spell check your text, just escape back to Word and let it handle that for you.Drag/drop Margin
The left and right side margin can be changed without leaving Writespace. Just move the mouse over the left margin until it lights up, and adjust the size of the margin until you are satisfied.
Drag the margin with left mouse button and release. The new margin size will be saved to settings automatically.Find
Press CTRL+F to display the find dialog. Press F3 to find next, next, next... as you are probably used to.Goto Line
Press CTRL+G to display the goto dialog which helps you go to a specific line in the text.Status Bar
The editor has a descrete status bar to show information about file saved and it also displays the current row and column in an animated, fade-out way. Feedback about the status bar and the row/col informaiton is appreciated.Mousewheel Zoom
The font size can also be changed without leaving the writing environment. Just hold CTRL and use the mouse wheel to zoom in our out of the text. The current size will also be saved to the settings.Options
It's possible to set color, font, size and margin from the options dialog. It's also possible to enable/disable spellchecking by specifying the language.
(image is shrinked down to fit in the blog)
Writespace Re-use
The Writespace editor and options dialog have public classes, methods and properties which makes it possible to run it from other .NET compatible languages. This will be better documented in the future. -
Expiring Temp ClickOnce Certificates - Create Your Own With Long Expiration
I'm looking at ClickOnce and ran into several blog posts where people were worried about expiring certificates when using a temporary PFX file created by VisualStudio. Appearently the certs issued by VS expire after a year and you will probably start running into problems with new deployments after that.
There is a KB article on MSDN that describes this problem but doesn't offer any good solutions (IMHO). Instead, if you have the Windows SDK installed you can create a certificte with much longer expiration, then create a PFX file from the cert and use with your ClickOnce application:
makecert.exe -r -pe -a sha1 -n "CN=MyClickOnceApp" -b 01/01/2000
-e 01/01/2036 -eku 1.3.6.1.5.5.7.3.3 -sv MyClickOnceApp.pvk MyClickOnceApp.cerpvk2pfx.exe -pvk MyClickOnceApp.pvk -spc MyClickOnceApp.cer -pfx MyClickOnceApp.pfx
This has been described in several places out there and my initial tests with makecert/pvk2pfx seems to work well so I'm storing the steps here for later use. I'm going to use it for a Codeplex project I'm opening up soon, so stay tuned...
-
A Decent Search Replace In Multiple Files Tool
Just wanted to share this tool with you.
I needed to search/replace text strings in some 600 files, and I've been downloading a bunch of crappy utilties that doesn't deliver. TextCrawler does this one thing and it does it good. A few features listed from their homepage:
- Find and Replace across files
- Fast searching, even on large files.
- Simple to use interface
- Flexible search parameters
- Text Extractor - rip text into a new file
- Search and replace using Regular Expressions.
- Regular Expression test tool
- Regular Expression library - Save your searches.
- Create backup files
- Highlighted search results
- Export Results
- Batch find and replace operations
Also, it's freeware :)
-
Status of Messenger Services
Yeah sure :)
Is it just me or has the Messenger service been kind of flunky the last couple of days? I keep getting these 81000314 error codes all the time. Not even WebMessenger is working.
-
Better Log Formatting for CruiseControl.NET and MSBuild
This is just a blog post to bump the topic on search engines to help people using MSBuild and CruiseControl.NET to get to the right place. I personally recommend to use the "Improved MSBuild Integration" logging option by Christian Rodemyer. If you follow the instructions on this page, you'll get it right.
You may also have to change the dashboard stylesheet somewhat if you want to add or remove smileys or other GUI-related things depending on the results from unit testing etc, but the output in the CruiseControl dashboard is nice and clean.
-
How to Update Google Chrome
So you've downloaded and installed the beta of Google Chrome and found that that Ajax story of Chrome isn't the best? You're thinking that the Google guys must have fixed it by now and you start looking for news related to Chrome on *.google.com but finds nothing... a bit frustrating to me at least.
Then you find out there's no obvious way to "Check for update..." in the Chrome app itself - unless there's actually a new version available! The trick is to click the "Customize and Control Google Chrome" button and look at the "About Google Chrome..." dialog, which will check to see if there's a new version available. If there is, it'll look something like this down at the bottom of said dialog:
Dave Taylor has written a nice detailed blog post about it, that's how I found out. Thanks Dave!
If anyone knows of an RSS feed, or official site to get news about Chrome updates, I'd love to get that URL.
UPDATE: It seems that the best URL is "The Official Google Blog" on http://googleblog.blogspot.com/ which unfortunately doesn't seem to use categories or tags unless I'm not blind. Would have been nice to have a Chrome category/tag as I'm not that interested in Picasa and the Democratic National Convention... :/
Now I just hope the introduction of Google Chrome doesn't lead into another browser war with website-breaking features like those we've had so many problems with before.