<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0"><id>tag:blogger.com,1999:blog-6908201609754153877</id><updated>2012-05-20T18:08:00.048+02:00</updated><category term="Visual Studio" /><category term="Unittest" /><category term="MVC" /><category term="OLAP" /><category term="REST" /><category term="SharePoint" /><category term="Sandcastle" /><category term="WorkItemQueries" /><category term="CCNET" /><category term="ClickOnce" /><category term="Swedish" /><category term="Windows Media Center" /><category term="Winforms" /><category term="Generics" /><category term="Oracle" /><category term="IIS" /><category term="ASP.NET" /><category term="C#" /><category term="Vista x64 .Net" /><category term="Tfs" /><category term="WCF" /><category term="Linq" /><category term="Resource manager" /><category term="Lambda" /><category term="WorkItem" /><category term="EPiServer" /><category term="log4net" /><category term="Debugging" /><category term="fun" /><category term="Macros" /><category term="Transaction" /><title type="text">Developing dotnet architect</title><subtitle type="html" /><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://dhvik.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://dhvik.blogspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/6908201609754153877/posts/default?start-index=26&amp;max-results=25" /><author><name>Dan</name><uri>http://www.blogger.com/profile/14787263872119403136</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_BktCNuR9VXg/S_W8rNV-5hI/AAAAAAAABC0/BP4nWl1EXzc/S220/2009+-+Dan+H%C3%A4ndevik+80_80.jpg" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>35</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/DevelopingDotnetArchitect" /><feedburner:info uri="developingdotnetarchitect" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry><id>tag:blogger.com,1999:blog-6908201609754153877.post-2283046007214772785</id><published>2011-06-24T01:00:00.008+02:00</published><updated>2011-06-24T02:21:16.470+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="REST" /><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><category scheme="http://www.blogger.com/atom/ns#" term="WCF" /><title type="text">Supporting Cross Origin Resource Sharing (CORS) requests in a WCF Rest service - Part 4</title><content type="html">&lt;div&gt;For background information, see &lt;a href="http://dhvik.blogspot.com/2011/06/supporting-cross-origin-resource.html"&gt;part 1&lt;/a&gt;&lt;/div&gt;&lt;div&gt;For message inspection code, see &lt;a href="http://dhvik.blogspot.com/2011/06/supporting-cross-origin-resource_23.html"&gt;part 2&lt;/a&gt;&lt;/div&gt;&lt;div&gt;For operation dispatcher code, see &lt;a href="http://dhvik.blogspot.com/2011/06/supporting-cross-origin-resource_24.html"&gt;part 3&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;To include the message inspection in our wcf service for our service we need to bind it to our service. This is done using behaviors. To bind the IDispatchMessageInspector that works on the ServiceEndpoint level we need to implement an IEndpointBehavior and assign it to our endpoint. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;To bind the IOperationInvoker and IDispatchMessageFormatter we need to implement the IOperationBehavior that works on the operation level.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This class also works as an attribute so you can decorate your contract and operations with it if need be. It also contains some properties if you want to control the header values.&lt;br /&gt;&lt;br /&gt;&lt;a href="https://github.com/dhvik/Wcf-cors-behavior/blob/master/CorsBehaviorAttribute.cs"&gt;https://github.com/dhvik/Wcf-cors-behavior/blob/master/CorsBehaviorAttribute.cs&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Assigning can be done in many ways. By declarations on the contract (attribute), configuration in the applications configuration file or direct using code. I'm using code since I host the services in a windows service.&lt;/div&gt;&lt;pre class="csharp:nocontrols:nogutter" name="code"&gt;var host = new WebServiceHost2(serviceType, false,&lt;br /&gt;new Uri(serviceBaseUrl + serviceName));&lt;br /&gt;var endpoint = host.AddServiceEndpoint(contractType,&lt;br /&gt;new WebHttpBinding(WebHttpSecurityMode.None), "");&lt;br /&gt;//add support for cors (both for the endpoint to detect and create reply)&lt;br /&gt;endpoint.Behaviors.Add(new CorsBehaviorAttribute());&lt;br /&gt;&lt;br /&gt;foreach (var operation in endpoint.Contract.Operations) {&lt;br /&gt;//add support for cors (and for operation to be able to not&lt;br /&gt;//invoke the operation if we have a preflight cors request)&lt;br /&gt;operation.Behaviors.Add(new CorsBehaviorAttribute());&lt;br /&gt;}&lt;/pre&gt;When we now have all pieces in place we don't need to bother about cross domain requests. Our endpoint and operation behaviors handles this and we don't need to litter our service code with things that don't belong there anyway.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6908201609754153877-2283046007214772785?l=dhvik.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?a=XywGXsdcqSU:NgqWwh42PJY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?a=XywGXsdcqSU:NgqWwh42PJY:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?i=XywGXsdcqSU:NgqWwh42PJY:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://dhvik.blogspot.com/feeds/2283046007214772785/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://dhvik.blogspot.com/2011/06/supporting-cross-origin-resource_9123.html#comment-form" title="11 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6908201609754153877/posts/default/2283046007214772785" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6908201609754153877/posts/default/2283046007214772785" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DevelopingDotnetArchitect/~3/XywGXsdcqSU/supporting-cross-origin-resource_9123.html" title="Supporting Cross Origin Resource Sharing (CORS) requests in a WCF Rest service - Part 4" /><author><name>Dan</name><uri>http://www.blogger.com/profile/14787263872119403136</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_BktCNuR9VXg/S_W8rNV-5hI/AAAAAAAABC0/BP4nWl1EXzc/S220/2009+-+Dan+H%C3%A4ndevik+80_80.jpg" /></author><thr:total>11</thr:total><feedburner:origLink>http://dhvik.blogspot.com/2011/06/supporting-cross-origin-resource_9123.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-6908201609754153877.post-1079613362748054917</id><published>2011-06-24T00:37:00.012+02:00</published><updated>2011-06-24T02:22:18.373+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="REST" /><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><category scheme="http://www.blogger.com/atom/ns#" term="WCF" /><title type="text">Supporting Cross Origin Resource Sharing (CORS) requests in a WCF Rest service - Part 3</title><content type="html">&lt;div&gt;For background information, see &lt;a href="http://dhvik.blogspot.com/2011/06/supporting-cross-origin-resource.html"&gt;part 1&lt;/a&gt;&lt;/div&gt;&lt;div&gt;For message inspection code, see &lt;a href="http://dhvik.blogspot.com/2011/06/supporting-cross-origin-resource_23.html"&gt;part 2&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;When a cors request is identified we now have the CorsState object available on our operation level and can act upon this. To be able to skip calling the service method in case of a preflight request we need to implement two extension points in the operation level. Message formatting and operation invocation. Since the preflight request won't have the correct requests message format, we skip the deserializing process and  the message using the normal deserializator can results in errors. So in that case we skip both serialization and deserialization.&lt;/div&gt;&lt;br /&gt;&lt;a href="https://github.com/dhvik/Wcf-cors-behavior/blob/master/CorsFormatter.cs"&gt;https://github.com/dhvik/Wcf-cors-behavior/blob/master/CorsFormatter.cs&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;When it comes to the IOperationInvoker we just skip invoking the operation if we have a preflight request. All other requests uses the original invoker.&lt;/div&gt;&lt;br /&gt;&lt;a href="https://github.com/dhvik/Wcf-cors-behavior/blob/master/CorsInvoker.cs"&gt;https://github.com/dhvik/Wcf-cors-behavior/blob/master/CorsInvoker.cs&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;In the &lt;a href="http://dhvik.blogspot.com/2011/06/supporting-cross-origin-resource_9123.html"&gt;part 4&lt;/a&gt; we will see how we bind all these extension points together for our service.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6908201609754153877-1079613362748054917?l=dhvik.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?a=27wAU63qc50:pFCuqMbfGBw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?a=27wAU63qc50:pFCuqMbfGBw:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?i=27wAU63qc50:pFCuqMbfGBw:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://dhvik.blogspot.com/feeds/1079613362748054917/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://dhvik.blogspot.com/2011/06/supporting-cross-origin-resource_24.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6908201609754153877/posts/default/1079613362748054917" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6908201609754153877/posts/default/1079613362748054917" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DevelopingDotnetArchitect/~3/27wAU63qc50/supporting-cross-origin-resource_24.html" title="Supporting Cross Origin Resource Sharing (CORS) requests in a WCF Rest service - Part 3" /><author><name>Dan</name><uri>http://www.blogger.com/profile/14787263872119403136</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_BktCNuR9VXg/S_W8rNV-5hI/AAAAAAAABC0/BP4nWl1EXzc/S220/2009+-+Dan+H%C3%A4ndevik+80_80.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://dhvik.blogspot.com/2011/06/supporting-cross-origin-resource_24.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-6908201609754153877.post-9125331008898546922</id><published>2011-06-23T23:55:00.006+02:00</published><updated>2011-06-24T02:15:08.241+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="REST" /><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><category scheme="http://www.blogger.com/atom/ns#" term="WCF" /><title type="text">Supporting Cross Origin Resource Sharing (CORS) requests in a WCF Rest service - Part 2</title><content type="html">For a background in the subject please see &lt;a href="http://dhvik.blogspot.com/2011/06/supporting-cross-origin-resource.html"&gt;part 1&lt;/a&gt;.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;To handle &lt;a href="http://www.w3.org/TR/access-control/"&gt;Cors&lt;/a&gt; requests we can take advantage of the extensibility mechanism that is embedded in WCF. There are many extension points that we can use and the cors problem can be issued in more than one way.&lt;/div&gt;&lt;div&gt;There is a &lt;a href="http://msdn.microsoft.com/en-us/magazine/cc163302.aspx"&gt;great article&lt;/a&gt;, written by Aaron Skonnard, published in the Dec 2007 issue of MSDN magazine, that covers many parts of this mechanism that I can recommend for further reading.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Our main problem is that we need to analyse the incoming request and determine if it is a cors preflight request, cors normal request or a normal request. Preflight request should not reach the service method at all since we don't want to invoke the service method. The other requests should invoke the method but for all cors responses we should add extra headers.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I found a reply by Carlos Figueira in a &lt;a href="http://social.msdn.microsoft.com/Forums/eu/wcf/thread/55ef7692-25dc-4ece-9dde-9981c417c94a"&gt;msdn thread&lt;/a&gt; that solves the "analyse message and skip invoking the service method"-part that I used as a start. (as a side note Richard Blewett stated (in the same thread) that we could intercept the message before it reaches the dispatcher by writing a protocol channel. I will leave that excercise to the reader or for another day.)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://i.msdn.microsoft.com/cc163302.fig03%28en-us%29.gif"&gt;&lt;img style="float:right; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 400px; height: 305px;" src="http://i.msdn.microsoft.com/cc163302.fig03%28en-us%29.gif" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div&gt;So to analyse the incoming message we use the first avaliable extension point in the dispatcher (server) that would be the Message inspection stage.&lt;/div&gt;&lt;div&gt;To use this extension point we implement an IDispatchMessageInspector. In this stage we are at the service endpoint and haven't decided wich method of the service that we should call. What we do here is that we look for a cors request (checking if the Origin header is present). If so we create a Cors state object and adds a property to the message so we can use this later on in other extension points.&lt;/div&gt;&lt;div&gt;If it is a preflight request we also create a response message that we should use.&lt;/div&gt;&lt;div&gt;When the message inspector receives the reply we add the headers (and if it was a preflight request, we replace the whole response. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In part 3 we will continue to the operation level where we check the property and omits the call to the service method in case of a preflight request.&lt;br /&gt;&lt;br /&gt;&lt;a href="https://github.com/dhvik/Wcf-cors-behavior/blob/master/CorsDispatchMessageInspector.cs"&gt;View code on github &lt;/a&gt;&lt;a href="https://github.com/dhvik/Wcf-cors-behavior/blob/master/CorsDispatchMessageInspector.cs"&gt;https://github.com/dhvik/Wcf-cors-behavior/blob/master/CorsDispatchMessageInspector.cs&lt;/a&gt;&lt;a href="https://github.com/dhvik/Wcf-cors-behavior/blob/master/CorsDispatchMessageInspector.cs"&gt; &lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In &lt;a href="http://dhvik.blogspot.com/2011/06/supporting-cross-origin-resource_24.html"&gt;part 3&lt;/a&gt; we will see how we handle things on the operation level.&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6908201609754153877-9125331008898546922?l=dhvik.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?a=B-bad18rYHc:U6DW3hIA6Ro:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?a=B-bad18rYHc:U6DW3hIA6Ro:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?i=B-bad18rYHc:U6DW3hIA6Ro:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://dhvik.blogspot.com/feeds/9125331008898546922/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://dhvik.blogspot.com/2011/06/supporting-cross-origin-resource_23.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6908201609754153877/posts/default/9125331008898546922" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6908201609754153877/posts/default/9125331008898546922" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DevelopingDotnetArchitect/~3/B-bad18rYHc/supporting-cross-origin-resource_23.html" title="Supporting Cross Origin Resource Sharing (CORS) requests in a WCF Rest service - Part 2" /><author><name>Dan</name><uri>http://www.blogger.com/profile/14787263872119403136</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_BktCNuR9VXg/S_W8rNV-5hI/AAAAAAAABC0/BP4nWl1EXzc/S220/2009+-+Dan+H%C3%A4ndevik+80_80.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://dhvik.blogspot.com/2011/06/supporting-cross-origin-resource_23.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-6908201609754153877.post-8726878672616195820</id><published>2011-06-23T23:43:00.008+02:00</published><updated>2011-06-24T01:29:07.930+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="REST" /><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><category scheme="http://www.blogger.com/atom/ns#" term="WCF" /><title type="text">Supporting Cross Origin Resource Sharing (CORS) requests in a WCF Rest service - Part I</title><content type="html">&lt;p&gt;If you use try to consume a rest service using JavaScript (jquery) and are using chrome or Firefox (newer versions) you might run into cross domain issues that involves the &lt;a href="http://www.w3.org/TR/access-control/"&gt;w3c standard&lt;/a&gt; for accessing resources on other domains (or ports).&lt;/p&gt;&lt;div&gt;In short, if you try to request a resource on a page using javascript(call a rest service) that is located on another domain/port then the XMLHttpRequest object that is implemented in the browser will first try to discover if the cross-origin resource is prepared/allows to accept requests from the origin. If this preflight request succeeds then the real request will be fired.&lt;br /&gt;All this is handled by the browsers XMLHttpRequest object so from the JavaScript side this don't affect the code.&lt;br /&gt;&lt;p&gt;The server side code must support  cors though.&lt;/p&gt;&lt;p&gt;An example: we take a simple service method that only returns a string.&lt;/p&gt;&lt;pre class="csharp:nocontrols:nogutter" name="code"&gt;public string Hello() {&lt;br /&gt; return "Hello!";&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;If we want to allow cors requests, then we must detect the preflight request and reply accordingly and if it is the real request we should perform the actual method.&lt;/p&gt;&lt;pre class="csharp:nocontrols:nogutter" name="code"&gt;public string Hello(){&lt;br /&gt; //for all cors requests&lt;br /&gt; WebOperationContext.Current.OutgoingResponse.Headers&lt;br /&gt;     .Add("Access-Control-Allow-Origin","*");&lt;br /&gt; //identify preflight request and add extra headers&lt;br /&gt; if (WebOperationContext.Current.IncomingRequest.Method == "OPTIONS") {&lt;br /&gt;      WebOperationContext.Current.OutgoingResponse.Headers&lt;br /&gt;          .Add("Access-Control-Allow-Methods", "POST, OPTIONS, GET");&lt;br /&gt;      WebOperationContext.Current.OutgoingResponse.Headers&lt;br /&gt;          .Add("Access-Control-Allow-Headers",&lt;br /&gt;               "Content-Type, Accept, Authorization, x-requested-with");&lt;br /&gt;      return null;&lt;br /&gt;  }&lt;br /&gt;  return "Hello!";&lt;br /&gt;}&lt;/pre&gt;&lt;p&gt;Basically we first add the Access-Control-Allow-Origin header telling that we allow any origins (we can also specify an origin that matches the origin that the request comes from). Then we check if the request is a preflight request (method is OPTIONS). If it is we add extra headers to declare which methods and headers that we allow the real request to contain. There are a few more access-control headers that we can add if we need and these are described in the &lt;a href="http://www.w3.org/TR/access-control/"&gt;w3c spec.&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;To add this code in every method is not a great solution but in &lt;a href="http://dhvik.blogspot.com/2011/06/supporting-cross-origin-resource_23.html"&gt;part 2&lt;/a&gt; we will see how we can use WCF extensibility to do this in a more elegant way.&lt;/p&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6908201609754153877-8726878672616195820?l=dhvik.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?a=sAn0WYxjsDo:4t5eX7yJf-k:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?a=sAn0WYxjsDo:4t5eX7yJf-k:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?i=sAn0WYxjsDo:4t5eX7yJf-k:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://dhvik.blogspot.com/feeds/8726878672616195820/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://dhvik.blogspot.com/2011/06/supporting-cross-origin-resource.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6908201609754153877/posts/default/8726878672616195820" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6908201609754153877/posts/default/8726878672616195820" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DevelopingDotnetArchitect/~3/sAn0WYxjsDo/supporting-cross-origin-resource.html" title="Supporting Cross Origin Resource Sharing (CORS) requests in a WCF Rest service - Part I" /><author><name>Dan</name><uri>http://www.blogger.com/profile/14787263872119403136</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_BktCNuR9VXg/S_W8rNV-5hI/AAAAAAAABC0/BP4nWl1EXzc/S220/2009+-+Dan+H%C3%A4ndevik+80_80.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://dhvik.blogspot.com/2011/06/supporting-cross-origin-resource.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-6908201609754153877.post-3155579258068970995</id><published>2011-01-02T02:24:00.002+01:00</published><updated>2011-01-02T02:30:06.096+01:00</updated><title type="text">Alpha version of IOU tracker</title><content type="html">Have been experimenting with .net4, MVC2 and EntityFramework. The result is a IOU tracker that is available at &lt;a href="http://iou.nu"&gt;iou.nu&lt;/a&gt;.&lt;br /&gt;Service is free of charge and feel free to try it out.&lt;br /&gt;&lt;br /&gt;I know there are several other iou trackers out there, but since the most lack some features and I needed to dig deeper into net4/mvc2/EF anyway so why not give it a try!?&lt;br /&gt;&lt;br /&gt;/Dan&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6908201609754153877-3155579258068970995?l=dhvik.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?a=6QV6wjdQMdA:2EztFTebzoI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?a=6QV6wjdQMdA:2EztFTebzoI:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?i=6QV6wjdQMdA:2EztFTebzoI:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://dhvik.blogspot.com/feeds/3155579258068970995/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://dhvik.blogspot.com/2011/01/alpha-version-of-iou-tracker.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6908201609754153877/posts/default/3155579258068970995" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6908201609754153877/posts/default/3155579258068970995" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DevelopingDotnetArchitect/~3/6QV6wjdQMdA/alpha-version-of-iou-tracker.html" title="Alpha version of IOU tracker" /><author><name>Dan</name><uri>http://www.blogger.com/profile/14787263872119403136</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_BktCNuR9VXg/S_W8rNV-5hI/AAAAAAAABC0/BP4nWl1EXzc/S220/2009+-+Dan+H%C3%A4ndevik+80_80.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://dhvik.blogspot.com/2011/01/alpha-version-of-iou-tracker.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-6908201609754153877.post-3558034084517605127</id><published>2010-06-09T12:04:00.004+02:00</published><updated>2010-06-09T12:18:37.586+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="WorkItem" /><category scheme="http://www.blogger.com/atom/ns#" term="Tfs" /><category scheme="http://www.blogger.com/atom/ns#" term="OLAP" /><title type="text">TF53010: Errors in the metadata manager when rebuilding OLAP cube</title><content type="html">I was adding new fields to our TFS workitems the other day and wanted them to be part of the olap cube. But when I added them (marked them with the reportable attribute) and processed the cube, i couldn't see them in the cube.&lt;br /&gt;I went reading the Event log on the Data tier of the TFS and found log entries like below&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;TF53010: The following error has occurred in a Team Foundation component or extension:&lt;br /&gt;Date (UTC): 2010-06-09 09:31:26&lt;br /&gt;Machine: MyTfsServer&lt;br /&gt;Application Domain: /LM/W3SVC/830720315/Root/Warehouse-3-129205184075330719&lt;br /&gt;Assembly: Microsoft.TeamFoundation.Warehouse, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; v2.0.50727&lt;br /&gt;Process Details:&lt;br /&gt; Process Name: w3wp&lt;br /&gt; Process Id: 9316&lt;br /&gt; Thread Id: 8484&lt;br /&gt; Account name: DOMAIN\admin&lt;br /&gt;&lt;br /&gt;Detailed Message: The pending configuration changes were not successfully added to&lt;br /&gt;the cube because of the following error: Microsoft.AnalysisServices.OperationException: &lt;br /&gt;XML parsing failed at line 1, column 0: A document must contain exactly one root element.&lt;br /&gt;.&lt;br /&gt;Errors in the metadata manager. An error occurred when instantiating a metadata &lt;br /&gt;object from the file, '\\?\C:\Program Files\Microsoft SQL Server\MSSQL.3\OLAP\Data&lt;br /&gt;\TfsWarehouse.0.db\Team System.63837.cub.xml'.&lt;br /&gt;&lt;br /&gt;  at Microsoft.AnalysisServices.AnalysisServicesClient.SendExecuteAndReadResponse(ImpactDetailCollection impacts, Boolean expectEmptyResults, Boolean throwIfError)&lt;br /&gt;  at Microsoft.AnalysisServices.AnalysisServicesClient.Alter(IMajorObject obj, ObjectExpansion expansion, ImpactDetailCollection impact, Boolean allowCreate)&lt;br /&gt;  at Microsoft.AnalysisServices.Server.Update(IMajorObject obj, UpdateOptions options, UpdateMode mode, XmlaWarningCollection warnings, ImpactDetailCollection impactResult)&lt;br /&gt;  at Microsoft.AnalysisServices.Server.SendUpdate(IMajorObject obj, UpdateOptions options, UpdateMode mode, XmlaWarningCollection warnings, ImpactDetailCollection impactResult)&lt;br /&gt;  at Microsoft.AnalysisServices.MajorObject.Update(UpdateOptions options, UpdateMode mode, XmlaWarningCollection warnings)&lt;br /&gt;  at Microsoft.AnalysisServices.MajorObject.Update(UpdateOptions options)&lt;br /&gt;  at Microsoft.TeamFoundation.Warehouse.OlapCreator.CreateOlap(WarehouseConfig whConf, String accessUser, String[] dataReaderAccounts, Boolean dropDB, Boolean processCube)&lt;br /&gt;  at Microsoft.TeamFoundation.Warehouse.AdapterScheduler.EnsureCubeIsUpToDate()&lt;br /&gt;&lt;br /&gt;For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I searched the path in the error message above (on the database server, little bit confusing since the path seems to be a local one, but since the error originates from the database server it makes sense).&lt;br /&gt;&lt;br /&gt;I the folder i found several files named Team System.xxxx.cub.xml (where xxxx is digits) and some where 0 bytes long and some contained error xml (seemed to be cut in the middle of writing).&lt;br /&gt;I removed these files and processed the cube again. (I used the Warehousecontroller webservice on the tfs server, https://mytfsserver:8143/Warehouse/v1.0/WarehouseController.asmx?op=Run)&lt;br /&gt;&lt;br /&gt;This time the processing went through without any problems and the fields apperared in my cube.&lt;br /&gt;&lt;br /&gt;I wonder how these error xml files where created, perhaps if the cube was instructed to reprocess while the iis was restarted or for some other reason.&lt;br /&gt;I'll better check the folder once and a while....&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6908201609754153877-3558034084517605127?l=dhvik.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?a=W-smQeKciUE:ZmRT8YVmVmE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?a=W-smQeKciUE:ZmRT8YVmVmE:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?i=W-smQeKciUE:ZmRT8YVmVmE:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://dhvik.blogspot.com/feeds/3558034084517605127/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://dhvik.blogspot.com/2010/06/tf53010-errors-in-metadata-manager-when.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6908201609754153877/posts/default/3558034084517605127" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6908201609754153877/posts/default/3558034084517605127" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DevelopingDotnetArchitect/~3/W-smQeKciUE/tf53010-errors-in-metadata-manager-when.html" title="TF53010: Errors in the metadata manager when rebuilding OLAP cube" /><author><name>Dan</name><uri>http://www.blogger.com/profile/14787263872119403136</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_BktCNuR9VXg/S_W8rNV-5hI/AAAAAAAABC0/BP4nWl1EXzc/S220/2009+-+Dan+H%C3%A4ndevik+80_80.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://dhvik.blogspot.com/2010/06/tf53010-errors-in-metadata-manager-when.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-6908201609754153877.post-2479008046459397958</id><published>2010-05-21T00:51:00.016+02:00</published><updated>2010-06-18T23:31:59.244+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><category scheme="http://www.blogger.com/atom/ns#" term="CCNET" /><title type="text">Writing a custom trigger for CruiseControl.Net</title><content type="html">&lt;p&gt;I’ve had some problems regarding the triggering of our nightly builds and has not been able to solve this with the standard triggers that comes with ccnet (using v1.4.4). So finally I took some time (night time, kids are sleeping and there is peace and quiet in the house :) and wrote a trigger that fixed the issue at hand. I will come to the trigger in just a moment but I’ll take some time to explain our ccnet setup.&lt;/p&gt;&lt;h3&gt;Interval builds&lt;/h3&gt;&lt;p&gt;All our projects are built using CruiseControl.Net and for each project we setup two builds. One interval build that triggers when the source has been changed. This build uses the intervalTrigger that checks the source repository at regular intervals. The interval build compiles the project and performs unit testing and provides feedback to the programmer. This is quite standard setup I guess so there’s no rocket science here…&lt;/p&gt;&lt;h3&gt;Nightly builds&lt;/h3&gt;&lt;p&gt;The other build is a nightly build that (in addition to the tasks for the interval build) performs analysis, generates documentation and installation packages ready to deploy to a target system. It also creates deliverable folder in a specific ”drop zone” for the project. This folder is named using the label of the nightly build.&lt;/p&gt;&lt;h3&gt;Labels&lt;/h3&gt;&lt;p&gt;All projects uses the project name and build no as label (like MyProject – 234). We reuse the build number of the interval build for the nightly build so if the last interval build was ”MyProject – 234”, the next time the nightly build is triggered the label for the nightly build is  ”MyProject-Nightly – 234”. This creates a side effect that if the nightly build is triggered twice and the interval build hasn’t been triggered, the label is the same. If you remember the drop zone folder it uses the label of the nightly build as a name so if it is triggered twice using the same label, it tries to overwrite the drop zone folder. &lt;/p&gt;This is a big no-no and to solve this I added a nant task that fires in the beginning of the nightly build that fails if the drop zone folder exists.&lt;br /&gt;&lt;h3&gt;Triggering the nightly build&lt;/h3&gt;&lt;p&gt;So to avoid failing the nightly build, it should only be triggered if an interval build has successfully been completed and the nightly build for that interval build hasn’t been performed.&lt;/p&gt;&lt;p&gt;Normally nightly triggers are defined to run at a specific time every night using a ScheduleTrigger that fires at that time if any changes to the source has been made during the day. In combination with a projectTrigger that only fires if the interval build has been successful we can accomplish the trigger to fire only if the interval is successful.&lt;/p&gt;&lt;h3&gt;Problem with projectTrigger&lt;/h3&gt;&lt;p&gt;There is a limitation to the projectTrigger that affects our setup severely. It doesn’t remember the project status after the ccnet server has restarted. This causes the nightly projects to be rebuilt after a server restart. Since we have lots of projects on the server, we need to restart it atleast once a week and this causes the nightly builds to fail.&lt;/p&gt;&lt;h3&gt;New trigger?&lt;/h3&gt;&lt;p&gt;To solve this we need another way to trigger the build. The first solution that comes to mind is if there was a trigger that could check if a specific folder (the drop zone folder in this case) was missing, we could replace the projectTrigger with a ”Missing folder trigger”.&lt;/p&gt;&lt;p&gt;Perhaps could look like this.&lt;/p&gt;&lt;pre class="xml:nocontrols:nogutter" name="code"&gt;&amp;lt;missingFolderTrigger path="Z:\PublishedBuilds\MyProject-Nightly\1.0.0.234"/&amp;gt;&lt;/pre&gt;Problem here is that we don’t know the last folder name. The ”1.0.0.234”comes from the file version for our compiled assemblies.&lt;br /&gt;The first part of the version number can be any numbers and the 234 refers to the build number of the project. This changes for each build so we need a way to look this up.&lt;br /&gt;&lt;h3&gt;Final design&lt;/h3&gt;I speak highly of the KISS principle, but I’m also great at creating generic things and sometimes this ”generic gene” gets some overhand (and sometimes also get way out of hand, but I think I found a good level this time :)&lt;br /&gt;So the final design was a trigger syntax like below:&lt;br /&gt;&lt;pre class="xml:nocontrols:nogutter" name="code"&gt;&amp;lt;fileExistsTrigger&lt;br /&gt; triggerOnMissing="true"&lt;br /&gt; seconds="30"&lt;br /&gt; path="Z:\PublishedBuilds\MyProject-Nightly\"&lt;br /&gt; match="\d+\.\d+\.\d+\.[Regex.Match([Projects(MyProject).LastSuccessfulBuildLabel],\d+$)]"/&amp;gt;&lt;/pre&gt;&lt;ul&gt;&lt;li&gt;This trigger is now a more ”generic” one allowing us to trigger on both files and directories.&lt;/li&gt;&lt;li&gt;The ”triggerOnMissing” allows us to trigger on both exists and not exists.&lt;/li&gt;&lt;li&gt;It’s based on an interval trigger and the ”seconds” parameter allows us to set on how often a file/directory should be checked.&lt;/li&gt;&lt;li&gt;The ”path” allows us to set the path that should be checked. If we only need to check a file/directory that we know the name of, this is enough. End with a \ to check a directory.&lt;/li&gt;&lt;/ul&gt;&lt;h4&gt;The match attribute&lt;/h4&gt;The ”match” allows us to perform a regular expression search that searches for a match for a directory/file in the supplied path.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The \d+ will match one or more digits &lt;/li&gt;&lt;li&gt;The \. will match a dot.&lt;/li&gt;&lt;li&gt;Repeating this match three times \d+\.\d+\.\d+\. will match the ”1.0.0.” part of the file (or any other valid version major.minor.build. combo)&lt;/li&gt;&lt;/ul&gt;Now the fun part begins :). I added some syntax to perform string operations and replacements. Any valid command is surrounded by [] and are replaced before the file/directory regex matching begins.&lt;br /&gt;In this example we have two commands, one property and one method call. Properties are evaluated first so &lt;strong&gt;[Projects(MyProject).LastSuccessfulBuildLabel]&lt;/strong&gt; allows us to instruct the trigger to lookup the project named ”MyProject” and return the LastSuccessfulBuildLabel. In this case this would be ”MyProject – 234”.&lt;br /&gt;The method call would look like this after the property replacement. &lt;strong&gt;[Regex.Match(MyProject - 234,\d+$)]&lt;/strong&gt;. This will call the Regex.Match method and return the matched pattern. In this case \d+$ will match the last digits in the ”MyProject – 234” and would return ”234”.&lt;br /&gt;So the final match attribute will be \d+\.\d+\.\d+\.234 and would in this case find a folder named 1.0.0.234. If the folder is missing, the build will be triggered, but if it is there, no trigger is fired. If the interval build fires and is successful, the LastSuccessfulBuildLabel increases and is 235. When the nightly build is triggered again, the folder is missing and the trigger will fire.&lt;br /&gt;&lt;h3&gt;Writing the trigger&lt;/h3&gt;The first part to think about when writing extensions/plugins to ccnet is that the assembly must be named ccnet.*.plugins.dll otherwise ccnet wont find it. Secondly, the trigger class needs to be decorated with the ReflectionTypeAttribute to tell the class what the xml element name for the class looks like (like [ReflectorType("fileExistsTrigger")]). Every field/property that should be read into the trigger should also be decorated with the ReflectorPropertyAttribute (like [ReflectorProperty("path", Required = true)]). I mainly looked at the ProjectTrigger that comes with ccnet and added stuff along the way.&lt;br /&gt;Beware that the code don't fix all special cases, like if your project name contains , ) or other characters that messes up the expressions, but this is what I needed (remember TDD).&lt;br /&gt;You can use the code below as it is or modify it to your needs. If you want the whole solution (including unit tests), just drop me a mail.&lt;br /&gt;Good luck :)&lt;br /&gt;&lt;pre class="c-sharp:nocontrols:nogutter" name="code"&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.Linq;&lt;br /&gt;using ThoughtWorks.CruiseControl.Remote;&lt;br /&gt;using ThoughtWorks.CruiseControl.Core.Triggers;&lt;br /&gt;using ThoughtWorks.CruiseControl.Core.Util;&lt;br /&gt;using Exortech.NetReflector;&lt;br /&gt;using System.Text.RegularExpressions;&lt;br /&gt;using System.IO;&lt;br /&gt;&lt;br /&gt;namespace Meridium.CruiseControl.Net.Triggers {&lt;br /&gt;    [ReflectorType("fileExistsTrigger")]&lt;br /&gt;    public class FileExistsTrigger : IntervalTrigger {&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// If the trigger should be active if the file is missing, default is false&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        [ReflectorProperty("triggerOnMissing", Required = false)]&lt;br /&gt;        public bool TriggerOnMissing;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// The url to the ccnet server, defaults to a local ccnet installation tcp://localhost:21234/CruiseManager.rem&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        [ReflectorProperty("serverUri", Required = false)]&lt;br /&gt;        public string ServerUri;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// The file/directory path to see if it exists or not&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        [ReflectorProperty("path", Required = true)]&lt;br /&gt;        public string Path;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Optional parameter to use if a regular expression should be used to match a file or directory in the path. Default is an empty string.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        [ReflectorProperty("match", Required = false)]&lt;br /&gt;        public string Match;&lt;br /&gt;&lt;br /&gt;        private readonly ICruiseManagerFactory _managerFactory;&lt;br /&gt;&lt;br /&gt;        public IDictionary&amp;lt;string, ProjectStatus&amp;gt; ProjectStatus {&lt;br /&gt;            get {&lt;br /&gt;                lock (ProjectStatusLock) {&lt;br /&gt;                    //if cache has timed out, clear cache.&lt;br /&gt;                    if (_projectStatus != null &amp;&amp; DateTime.Now &amp;gt; _cacheValidUntil) {&lt;br /&gt;                        _projectStatus = null;&lt;br /&gt;                        Log.Debug("Cache was deleted, was valid until " + _cacheValidUntil.ToString("yyyy-MM-dd HH:mm:ss,fff"));&lt;br /&gt;                    }&lt;br /&gt;                    if (_projectStatus == null) {&lt;br /&gt;                        Log.Debug("Updating ProjectStatus cache from server: " + ServerUri);&lt;br /&gt;                        _projectStatus = new Dictionary&amp;lt;string, ProjectStatus&amp;gt;();&lt;br /&gt;                        foreach (ProjectStatus status in _managerFactory.GetCruiseManager(ServerUri).GetProjectStatus()) {&lt;br /&gt;                            _projectStatus.Add(status.Name, status);&lt;br /&gt;                        }&lt;br /&gt;                        _cacheValidUntil = DateTime.Now + CacheTime;&lt;br /&gt;                        Log.Debug("Cache valid until " + _cacheValidUntil.ToString("yyyy-MM-dd HH:mm:ss,fff"));&lt;br /&gt;                    }&lt;br /&gt;                    return _projectStatus;&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        private static DateTime _cacheValidUntil = DateTime.MinValue;&lt;br /&gt;        private static readonly TimeSpan CacheTime = new TimeSpan(0, 10, 0);&lt;br /&gt;        private static Dictionary&amp;lt;string, ProjectStatus&amp;gt; _projectStatus;&lt;br /&gt;        private static readonly object ProjectStatusLock = new object();&lt;br /&gt;&lt;br /&gt;        public FileExistsTrigger()&lt;br /&gt;            : this(new DateTimeProvider(), new RemoteCruiseManagerFactory()) {&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public FileExistsTrigger(DateTimeProvider dtp, ICruiseManagerFactory managerFactory)&lt;br /&gt;            : base(dtp) {&lt;br /&gt;            ServerUri = "tcp://localhost:21234/CruiseManager.rem";&lt;br /&gt;            _managerFactory = managerFactory;&lt;br /&gt;        }&lt;br /&gt;        public override IntegrationRequest Fire() {&lt;br /&gt;            //only check on intervals&lt;br /&gt;            if (base.Fire() != null) {&lt;br /&gt;                try {&lt;br /&gt;                    Log.Debug(string.Format("More than {0} seconds since last integration, checking url.", IntervalSeconds));&lt;br /&gt;                    if (FileExists() != TriggerOnMissing) {&lt;br /&gt;                        Log.Debug("Trigger matched, fire IntegrationRequest");&lt;br /&gt;                        return new IntegrationRequest(BuildCondition, Name);&lt;br /&gt;                    }&lt;br /&gt;                } catch (Exception ex) {&lt;br /&gt;                    Log.Error(ex);&lt;br /&gt;                } finally {&lt;br /&gt;                    IncrementNextBuildTime();&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;            return null;&lt;br /&gt;        }&lt;br /&gt;        private string HandleProjectPropertyMatches(Match m) {&lt;br /&gt;            string projectName = m.Groups["projectName"].Value;&lt;br /&gt;            string property = m.Groups["property"].Value;&lt;br /&gt;            var ps = GetCurrentProjectStatus(projectName);&lt;br /&gt;            switch (property.ToLower()) {&lt;br /&gt;                case "lastsuccessfulbuildlabel":&lt;br /&gt;                    return ps.LastSuccessfulBuildLabel;&lt;br /&gt;                case "name":&lt;br /&gt;                    return ps.Name;&lt;br /&gt;                case "buildstatus":&lt;br /&gt;                    return ps.BuildStatus.ToString();&lt;br /&gt;                default:&lt;br /&gt;                    throw new NotImplementedException(string.Format("Support for property {0} is not implemented yet!", property));&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        private static string HandleRegexMatchMatches(Match m) {&lt;br /&gt;            string input = m.Groups["input"].Value;&lt;br /&gt;            string pattern = m.Groups["pattern"].Value;&lt;br /&gt;            Match match = Regex.Match(input, pattern);&lt;br /&gt;            return match.Success ? match.Value : string.Empty;&lt;br /&gt;        }&lt;br /&gt;        private bool FileExists() {&lt;br /&gt;            string fp = TranslateValue(Path);&lt;br /&gt;            string match = TranslateValue(Match);&lt;br /&gt;            if (!string.IsNullOrEmpty(match)) {&lt;br /&gt;                if (!fp.EndsWith(@"\"))//"&lt;br /&gt;                    fp += @"\";//"&lt;br /&gt;                var dir = new DirectoryInfo(fp);&lt;br /&gt;                if (!dir.Exists) {&lt;br /&gt;                    Log.Debug(string.Format("Matching path {0} failed. Directory does not exist.", fp));&lt;br /&gt;                    return false;&lt;br /&gt;                }&lt;br /&gt;                foreach (var fs in dir.GetFileSystemInfos().Where(fs =&amp;gt; Regex.IsMatch(fs.Name, match))) {&lt;br /&gt;                    Log.Debug(string.Format("Match successful with fileSystemInfo {0}", fs.FullName));&lt;br /&gt;                    return true;&lt;br /&gt;                }&lt;br /&gt;                Log.Debug(string.Format("No match for {0}", match));&lt;br /&gt;                return false;&lt;br /&gt;&lt;br /&gt;            }&lt;br /&gt;            bool isDirectory = fp.EndsWith(@"\");//"&lt;br /&gt;            bool exists = isDirectory ? Directory.Exists(fp) : File.Exists(fp);&lt;br /&gt;            Log.Debug(string.Format("Checking if {0} {1} exists: {2}", (isDirectory ? "directory" : "file"), fp, exists));&lt;br /&gt;            return exists;&lt;br /&gt;        }&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Translates the supplied value and expands all methods and variables&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="val"&amp;gt;The value to translate&amp;lt;/param&amp;gt;&lt;br /&gt;        /// &amp;lt;returns&amp;gt;The translated value&amp;lt;/returns&amp;gt;&lt;br /&gt;        private string TranslateValue(string val) {&lt;br /&gt;            //handle replacements...&lt;br /&gt;            //like [Projects(MyProject).LastSuccessfulBuildLabel]&lt;br /&gt;            val = Regex.Replace(val, @"\[Projects\((?&amp;lt;projectName&amp;gt;[^\)]+)\)\.(?&amp;lt;property&amp;gt;[^\]]+)\]", HandleProjectPropertyMatches, RegexOptions.IgnoreCase);&lt;br /&gt;            //handle Regexp&lt;br /&gt;            //like [Regex.Match(string,pattern)]&lt;br /&gt;            val = Regex.Replace(val, @"\[Regex\.Match\((?&amp;lt;input&amp;gt;[^,]+),(?&amp;lt;pattern&amp;gt;[^\)]+)\)\]", HandleRegexMatchMatches, RegexOptions.IgnoreCase);&lt;br /&gt;&lt;br /&gt;            return val;&lt;br /&gt;        }&lt;br /&gt;        private ProjectStatus GetCurrentProjectStatus(string project) {&lt;br /&gt;            if (!ProjectStatus.ContainsKey(project)) {&lt;br /&gt;                throw new NoSuchProjectException(project);&lt;br /&gt;            }&lt;br /&gt;            return ProjectStatus[project];&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6908201609754153877-2479008046459397958?l=dhvik.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?a=AxVFl79V6wI:fmdoLq5fnGs:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?a=AxVFl79V6wI:fmdoLq5fnGs:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?i=AxVFl79V6wI:fmdoLq5fnGs:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://dhvik.blogspot.com/feeds/2479008046459397958/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://dhvik.blogspot.com/2010/05/writing-custom-trigger-for.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6908201609754153877/posts/default/2479008046459397958" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6908201609754153877/posts/default/2479008046459397958" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DevelopingDotnetArchitect/~3/AxVFl79V6wI/writing-custom-trigger-for.html" title="Writing a custom trigger for CruiseControl.Net" /><author><name>Dan</name><uri>http://www.blogger.com/profile/14787263872119403136</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_BktCNuR9VXg/S_W8rNV-5hI/AAAAAAAABC0/BP4nWl1EXzc/S220/2009+-+Dan+H%C3%A4ndevik+80_80.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://dhvik.blogspot.com/2010/05/writing-custom-trigger-for.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-6908201609754153877.post-6970722856974633778</id><published>2010-04-13T10:49:00.007+02:00</published><updated>2011-11-02T05:06:21.408+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="EPiServer" /><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><title type="text">Adding buttons to the TinyMce editor in EPiServer 6 programmatically</title><content type="html">While developing ImageVault we needed to add buttons to insert images in the TinyMce editor that ships with EPiServer CMS 6. The buttons are decorated with a TinyMCEPluginButtonAttribute and they can be added manually by entering admin mode and modifying the settings for the XHTML property (see &lt;a href="http://www.meridiumkalmar.se/sv/blogg/2010/03/23/add-functionality-to-the-rich-text-editor-in-episerver-cms-6"&gt;Oskars post "Add functionality to the rich text editor in EPiServer cms 6"&lt;/a&gt;).&lt;br /&gt;To do this by code this was rather simple since EPiServer has a great Api (even that it could contain more examples)...&lt;br /&gt;&lt;br /&gt;The settings are stored in the EPiServer database and is accessed using the PropertySettingsRepository class.&lt;br /&gt;To get the current settings for the TinyMce editor, just create a repository and use the GetDefault method&lt;br /&gt;&lt;pre class="c-sharp:nocontrols:nogutter" name="code"&gt;&lt;br /&gt;PropertySettingsRepository p = new PropertySettingsRepository();&lt;br /&gt;PropertySettingsWrapper defaultSettings = p.GetDefault(typeof(TinyMCESettings));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The PropertySettingsWrapper contains metadata for the settings, like DisplayName, Id etc.&lt;br /&gt;It also contains the specific setting for the TinyMce editor in the property PropertySettings.&lt;br /&gt;&lt;br /&gt;To create a new settings for the TinyMce editor with some buttons added we can use the code below.&lt;br /&gt;&lt;pre class="c-sharp:nocontrols:nogutter" name="code"&gt;&lt;br /&gt;PropertySettingsRepository p = new PropertySettingsRepository();&lt;br /&gt;PropertySettingsWrapper defaultSettings = p.GetDefault(typeof(TinyMCESettings));&lt;br /&gt;&lt;br /&gt;//create a copy of the default settings&lt;br /&gt;PropertySettingsWrapper copy = defaultSettings.Copy();&lt;br /&gt;copy.DisplayName+="(My copy)";&lt;br /&gt;TinyMCESettings settings = copy.PropertySettings as TinyMCESettings;&lt;br /&gt;&lt;br /&gt;//create a new toolbar row for my buttons&lt;br /&gt;ToolbarRow row = new ToolbarRow();&lt;br /&gt;settings.Toolbars.Add(row);&lt;br /&gt;&lt;br /&gt;//the buttons are added using the name defined in the&lt;br /&gt;//ButtonName property of the TinyMCEPluginButtonAttribute.&lt;br /&gt;row.Buttons.Add("mybutton1");&lt;br /&gt;row.Buttons.Add("separator");&lt;br /&gt;row.Buttons.Add("mybutton2");&lt;br /&gt;&lt;br /&gt;//Save the copy as a global setting&lt;br /&gt;p.SaveGlobal(copy);&lt;br /&gt;&lt;br /&gt;//Set it as default&lt;br /&gt;p.SetDefault(copy.Id);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Quite easy. The separator button is included in EPiServer 6 the others need to be added using classes decorated with the TinyMCEPluginButtonAttribute.&lt;br /&gt;&lt;br /&gt;Note!&lt;br /&gt;To actually use this code in EPiServer you need to insert it somewhere :) The easiest way is to create a InitializationModule class (implement IInitializaionModule and mark it with the InitializationModuleAttribute). Then in the Initialize method, add your code to the InitializationEngine.InitComplete event.&lt;br /&gt;&lt;pre class="c-sharp:nocontrols:nogutter" name="code"&gt;&lt;br /&gt;public void Initialize(InitializationEngine context) {&lt;br /&gt;    context.InitComplete+=(sender,args)=&gt; MyInstallButtonsMethod();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;a href="http://world.episerver.com/Documentation/Items/Tech-Notes/EPiServer-CMS-6/EPiServer-CMS-60/Initialization/"&gt;More about EPiServer Initialization on episerver world&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6908201609754153877-6970722856974633778?l=dhvik.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?a=K1TjYLzG_n8:sEu-BQiOheE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?a=K1TjYLzG_n8:sEu-BQiOheE:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?i=K1TjYLzG_n8:sEu-BQiOheE:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://dhvik.blogspot.com/feeds/6970722856974633778/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://dhvik.blogspot.com/2010/04/adding-buttons-to-tinymce-editor-in.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6908201609754153877/posts/default/6970722856974633778" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6908201609754153877/posts/default/6970722856974633778" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DevelopingDotnetArchitect/~3/K1TjYLzG_n8/adding-buttons-to-tinymce-editor-in.html" title="Adding buttons to the TinyMce editor in EPiServer 6 programmatically" /><author><name>Dan</name><uri>http://www.blogger.com/profile/14787263872119403136</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_BktCNuR9VXg/S_W8rNV-5hI/AAAAAAAABC0/BP4nWl1EXzc/S220/2009+-+Dan+H%C3%A4ndevik+80_80.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://dhvik.blogspot.com/2010/04/adding-buttons-to-tinymce-editor-in.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-6908201609754153877.post-3663095176049954080</id><published>2009-10-16T14:46:00.009+02:00</published><updated>2010-05-11T13:40:39.219+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="CCNET" /><title type="text">Converting word doc to pdf in CruiseControl.Net</title><content type="html">Today I needed to automate the process where we create PDF files out of our client documentation in Microsoft Word format. Since up to now we have done it manually by opening the document and printing to a installed PDF printer. Quite tedious work.&lt;br /&gt;After some searching I start to realize that there are &lt;span style="font-weight: bold;"&gt;many &lt;/span&gt;PDF creators around; and most of them uses Ms word and prints using a pdf printer (just as we use to do, but by automation).&lt;br /&gt;The problem is that I don't want to install printers or the Ms Office package on our build server (if I can avoid it). Another wish is that the solution should be free and open source.&lt;br /&gt;So finally I stumbled upon &lt;a href="http://www.togaware.com/linux/survivor/Convert_MS_Word.html"&gt;this article&lt;/a&gt; by Graham J. Williams that uses &lt;a href="http://www.openoffice.org/"&gt;OpenOffice.org&lt;/a&gt; to do the conversion and a custom macro to allow the conversion to be called from the commandline.&lt;br /&gt;&lt;pre class="basic:nocontrols:nogutter" name="code"&gt;REM  *****  BASIC  *****&lt;br /&gt;&lt;br /&gt;Sub ConvertWordToPDF(cFile)&lt;br /&gt;  cURL = ConvertToURL(cFile)&lt;br /&gt;&lt;br /&gt;  ' Open the document.&lt;br /&gt;  ' Just blindly assume that the document is of a type that OOo will&lt;br /&gt;  '  correctly recognize and open -- without specifying an import filter.&lt;br /&gt;  oDoc = StarDesktop.loadComponentFromURL(cURL, "_blank", 0, Array(MakePropertyValue("Hidden", True), ))&lt;br /&gt;&lt;br /&gt;  cFile = Left(cFile, LastIndexOf(cFile,".")) + "pdf"&lt;br /&gt;  cURL = ConvertToURL(cFile)&lt;br /&gt;&lt;br /&gt;  ' Save the document using a filter.&lt;br /&gt;  oDoc.storeToURL(cURL, Array(MakePropertyValue("FilterName", "writer_pdf_Export"), ))&lt;br /&gt;&lt;br /&gt;  oDoc.close(True)&lt;br /&gt;&lt;br /&gt;End Sub&lt;br /&gt;&lt;br /&gt;Function LastIndexOf ( cText as String, cMatch as String) As Integer&lt;br /&gt;  lastIndex = 0&lt;br /&gt;  pos=0&lt;br /&gt;  Do&lt;br /&gt;    pos = InStr(pos+1,cText,cMatch)'&lt;br /&gt;    If pos &gt;0 Then&lt;br /&gt;      lastIndex = pos&lt;br /&gt;    End If&lt;br /&gt;  Loop While pos &gt;0&lt;br /&gt;  LastIndexOf()=lastIndex&lt;br /&gt;End Function&lt;br /&gt;&lt;br /&gt;Function MakePropertyValue( Optional cName As String, Optional uValue ) As com.sun.star.beans.PropertyValue&lt;br /&gt;  Dim oPropertyValue As New com.sun.star.beans.PropertyValue&lt;br /&gt;  If Not IsMissing( cName ) Then&lt;br /&gt;    oPropertyValue.Name = cName&lt;br /&gt;  EndIf&lt;br /&gt;  If Not IsMissing( uValue ) Then&lt;br /&gt;    oPropertyValue.Value = uValue&lt;br /&gt;  EndIf&lt;br /&gt;  MakePropertyValue() = oPropertyValue&lt;br /&gt;End Function&lt;br /&gt;&lt;/pre&gt;I modified it a bit to allow correct handing of extensions.&lt;br /&gt;To call it from a windows command prompt just enter&lt;br /&gt;&lt;pre class="basic:nocontrols:nogutter" name="code"&gt;c:\program files\OpenOffice.Org 3\Program\swriter.exe -invisible "macro:///Standard.Module1.ConvertWordToPDF(c:\temp\My word document.doc)"&lt;br /&gt;&lt;/pre&gt;I incorporated it in our cruisecontrol.net nant scripts so all solutions that needs pdf conversions in the build chain can have it.&lt;br /&gt;Great!&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;2010-05-11 Update: Fixed a bug with filenames that contained more than one period (.), added the LastIndexOf function&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6908201609754153877-3663095176049954080?l=dhvik.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?a=EDhEtkA_CFI:DnywY385znA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?a=EDhEtkA_CFI:DnywY385znA:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?i=EDhEtkA_CFI:DnywY385znA:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://dhvik.blogspot.com/feeds/3663095176049954080/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://dhvik.blogspot.com/2009/10/converting-word-doc-to-pdf-in.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6908201609754153877/posts/default/3663095176049954080" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6908201609754153877/posts/default/3663095176049954080" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DevelopingDotnetArchitect/~3/EDhEtkA_CFI/converting-word-doc-to-pdf-in.html" title="Converting word doc to pdf in CruiseControl.Net" /><author><name>Dan</name><uri>http://www.blogger.com/profile/14787263872119403136</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_BktCNuR9VXg/S_W8rNV-5hI/AAAAAAAABC0/BP4nWl1EXzc/S220/2009+-+Dan+H%C3%A4ndevik+80_80.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://dhvik.blogspot.com/2009/10/converting-word-doc-to-pdf-in.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-6908201609754153877.post-8454250546558814303</id><published>2009-08-06T00:10:00.006+02:00</published><updated>2009-08-06T00:20:04.881+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Visual Studio" /><category scheme="http://www.blogger.com/atom/ns#" term="Macros" /><title type="text">Bugfix for Documentator Macros (VB)</title><content type="html">&lt;div&gt;A small bug fix for the auto documentation feature for VB.Net.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Thanks for the report Sam; what has it been, nearly 2 years since you reported the bug finally I've come about... ( You said it wasn't urgent... you'll probably reconsider next time ;)&lt;/div&gt;&lt;br /&gt;&lt;div&gt; &lt;/div&gt;&lt;br /&gt;&lt;div&gt;When autodocumenting a Sub or function that is connected to an event, an error occurs.&lt;/div&gt;&lt;br /&gt;&lt;div&gt; &lt;/div&gt;&lt;br /&gt;&lt;div&gt;The fix is included in version 2.5.3.0 that can be downloaded from &lt;a href="http://dan.meridium.se/DocumentatorMacros/v2.5.3.0/Meridium.rar"&gt;http://dan.meridium.se/DocumentatorMacros/v2.5.3.0/Meridium.rar&lt;/a&gt;.&lt;/div&gt;&lt;br /&gt;&lt;div&gt; &lt;/div&gt;&lt;br /&gt;&lt;div&gt;(For more information about the Documentator Macros, see &lt;a href="http://www.codeproject.com/KB/cs/documentatormacros.aspx"&gt;http://www.codeproject.com/KB/cs/documentatormacros.aspx&lt;/a&gt; )&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6908201609754153877-8454250546558814303?l=dhvik.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?a=J7luaxUzEg0:1TQlI4uE5-g:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?a=J7luaxUzEg0:1TQlI4uE5-g:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?i=J7luaxUzEg0:1TQlI4uE5-g:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://dhvik.blogspot.com/feeds/8454250546558814303/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://dhvik.blogspot.com/2009/08/bugfix-for-documentator-macros-vb.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6908201609754153877/posts/default/8454250546558814303" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6908201609754153877/posts/default/8454250546558814303" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DevelopingDotnetArchitect/~3/J7luaxUzEg0/bugfix-for-documentator-macros-vb.html" title="Bugfix for Documentator Macros (VB)" /><author><name>Dan</name><uri>http://www.blogger.com/profile/14787263872119403136</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_BktCNuR9VXg/S_W8rNV-5hI/AAAAAAAABC0/BP4nWl1EXzc/S220/2009+-+Dan+H%C3%A4ndevik+80_80.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://dhvik.blogspot.com/2009/08/bugfix-for-documentator-macros-vb.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-6908201609754153877.post-2718870077747005393</id><published>2009-07-27T21:47:00.011+02:00</published><updated>2009-07-28T00:02:40.846+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="MVC" /><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><title type="text">Mvc for Winforms - Mapping the View event to the Controller action Part III</title><content type="html">Long time since part I and II were posted, but I've been quite busy lately so I haven't found time (or prioritized) to write the last part, but here we are :)&lt;br /&gt;&lt;br /&gt;To recap, in &lt;a href="http://dhvik.blogspot.com/2008/11/mvc-for-winforms-mapping-view-event-to.html"&gt;part I&lt;/a&gt; I explained about the background of the issue, that I was writing a small winforms MVC framework. The goal of the framework was to be able to instruct the controller to listen to a component in the view and when the component called an event, a specific method would be called.&lt;br /&gt;For example, the call below would register the click event from the saveButton&lt;br /&gt;&lt;pre class="c-sharp:nocontrols:nogutter" name="code"&gt;Controller.RegisterAction(saveButton,"Save");&lt;br /&gt;&lt;/pre&gt;(in later editions I have also added support for lamda expressions instead of method names, and thus almost abandoned the previous)&lt;br /&gt;&lt;pre class="c-sharp:nocontrols:nogutter" name="code"&gt;Controller.RegisterAction(rotateRightButton,() =&gt; Controller.Rotate(90));&lt;br /&gt;Controller.RegisterAction(rotateLeftButton,() =&gt; Controller.Rotate(-90));&lt;br /&gt;&lt;/pre&gt;In &lt;a href="http://dhvik.blogspot.com/2008/11/mvc-for-winforms-mapping-view-event-to_02.html"&gt;part II&lt;/a&gt; I wrote about how find and listen to the event of the component.&lt;br /&gt;In this section I will explain how I call the method.&lt;br /&gt;&lt;br /&gt;What we ended with in the last post was that we had registered the controllers event to call the ExecuteAction method of the Controller class.&lt;br /&gt;&lt;pre class="c-sharp:nocontrols:nogutter" name="code"&gt;public void ExecuteAction(object source, object eventArgs, ActionData actionData)&lt;br /&gt;&lt;/pre&gt; or in the latter case using lambda expressions (or action)&lt;br /&gt;&lt;pre class="c-sharp:nocontrols:nogutter" name="code"&gt;public void ExecuteAction(object source, object eventArgs, Action action)&lt;br /&gt;&lt;/pre&gt; In this case the Action is the easiest to implement. Just call the Invoke method of the Action instance and you are done.&lt;br /&gt;&lt;pre class="c-sharp:nocontrols:nogutter" name="code"&gt;public void ExecuteAction(object source, object eventArgs, Action action) {&lt;br /&gt;   action.Invoke();&lt;br /&gt;}&lt;/pre&gt;&lt;span style="font-weight: bold;"&gt;The no Action ExecuteAction method (almost abandoned way )&lt;/span&gt;&lt;br /&gt;The ActionData variant is somewhat more tedious but this is how ASP.NET MVC does it.&lt;br /&gt;First we need to find the method to call. The ActionData contains the name of the method. We now needs to find the method of the controller that matches that name. MVC for ASP.NET uses the ActionSelectorClass. The ActionSelectorClass is responsible for retrieving the MethodInfo for an action by passing in the name of the action. It support action aliases and other things so look it up for a great example.&lt;br /&gt;In short it uses reflection to get all methods, filters out irrelevant methods and returns the one that matches the name.&lt;br /&gt;Example (really shortened example, lookup ActionSelectorClass in the ASP.NET MVC framework for a complete example.)&lt;br /&gt;&lt;pre class="c-sharp:nocontrols:nogutter" name="code"&gt;//get all methods&lt;br /&gt;MethodInfo[] array = ControllerType.GetMethods(BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance);&lt;br /&gt;//convert to a dictionary&lt;br /&gt;ILookup&amp;lt;string,MethodInfo&amp;gt; methodLookup = array.ToLookup(method =&gt; method.Name, StringComparer.OrdinalIgnoreCase);&lt;br /&gt;//return the matching MethodInfo&lt;br /&gt;MethodInfo action = methodLookup[actionName];&lt;br /&gt;&lt;/pre&gt;Now we have the MethodInfo to invoke, only to calculate the parameters to pass to the method is left.&lt;br /&gt;&lt;br /&gt;The action is invoked using the Invoke method of the MethodInfo class and we need to pass the instance to invoke it on (the controller instance) and the object array containing the parameters to pass to the method/action.&lt;br /&gt;Example&lt;br /&gt;&lt;pre class="c-sharp:nocontrols:nogutter" name="code"&gt;action.Invoke(controller,parameterValues);&lt;/pre&gt;If the action don't have any parameters we just pass null, but if we do have parameters we need to assign values for them.&lt;br /&gt;Remember: we  wanted to be able to register the call&lt;br /&gt;&lt;pre class="c-sharp:nocontrols:nogutter" name="code"&gt;Controller.RegisterAction(createBoldTextButton, "CreateText", new {name="Bold", type=4}); &lt;/pre&gt;To call the action method&lt;br /&gt;&lt;pre class="c-sharp:nocontrols:nogutter" name="code"&gt;public void CreateText(string name, int type) {...}  &lt;/pre&gt;using the "Bold" as value for the name parameter and 4 as value for the type parameter.&lt;br /&gt;&lt;br /&gt;To succeed with this we need to do some parsing.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Iterate all parameters of the method info.&lt;/li&gt;&lt;li&gt;Handle special cases (like if the parameter is named source and is of type object, then the source value from the event handler method should be passed).&lt;/li&gt;&lt;li&gt;Find a property with a matching name from the value object passed in the RegisterAction.&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-weight: bold;"&gt;Iterate all parameters of the method info&lt;/span&gt;&lt;br /&gt;Using reflection it's easy to find the parameters.&lt;br /&gt;&lt;br /&gt;&lt;pre class="c-sharp:nocontrols:nogutter" name="code"&gt;List&amp;lt;object&amp;gt; objects = new List&amp;lt;object&amp;gt;();&lt;br /&gt;foreach (ParameterInfo info in method.GetParameters()) {              &lt;br /&gt;  objects.Add(GetParameterValue(info));&lt;br /&gt;}&lt;br /&gt;return objects.ToArray();&lt;/pre&gt;&lt;span style="font-weight: bold;"&gt;Handle special cases&lt;/span&gt;&lt;br /&gt;The GetParameterValue method will return the value to pass to the supplied ParameterInfo. In some cases the value to be passed as parameter is not any of the values passed to the values parameter (in the RegisterAction method), like for example, if one would need to get the EventArgs or source parameter passed from the event component, then we would need to handle them. (other customizations can be done here, this is an example)&lt;br /&gt;&lt;pre class="c-sharp:nocontrols:nogutter" name="code"&gt;Type parameterType = parameterInfo.ParameterType;&lt;br /&gt;string parameterName = parameterInfo.Name;&lt;br /&gt;&lt;br /&gt;//handle eventArgs and source parameters&lt;br /&gt;if (string.Equals(parameterName, "e", StringComparison.OrdinalIgnoreCase) &amp;amp;&amp;amp; _eventArgs != null &amp;amp;&amp;amp; parameterType.IsAssignableFrom(_eventArgs.GetType()))&lt;br /&gt;  return _eventArgs;&lt;br /&gt;if (string.Equals(parameterName, "source", StringComparison.OrdinalIgnoreCase)&amp;amp;&amp;amp; parameterType.Equals(typeof(object)))&lt;br /&gt;  return _source;&lt;br /&gt;&lt;br /&gt;//parse the values object&lt;br /&gt;return GetValuesValue(parameterType, parameterName);&lt;/pre&gt;Find a matching property of the value object&lt;br /&gt;At last we would try to find a matching property of the value object that matches the parameter type and name. (First we check that the parameter don't matches the whole value object)&lt;br /&gt;&lt;pre class="c-sharp:nocontrols:nogutter" name="code"&gt;//if we don't have a value, return null&lt;br /&gt;if (ValueType == null)&lt;br /&gt;  return null;&lt;br /&gt;//if the value is matching, use it as value&lt;br /&gt;if (type.Equals(ValueType))&lt;br /&gt;  return _actionData.Values;&lt;br /&gt;PropertyInfo[] valueProperties= ValueType.GetProperties();&lt;br /&gt;//if the value don't have any properties, return null&lt;br /&gt;if (valueProperties.Length == 0)&lt;br /&gt;  return null;&lt;br /&gt;//find matching property&lt;br /&gt;PropertyInfo[] possibleMatches = valueProperties&lt;br /&gt;     .Where(p =&gt; string.Equals(name, p.Name, StringComparison.OrdinalIgnoreCase)&lt;br /&gt;            &amp;amp;&amp;amp; type.IsAssignableFrom(p.PropertyType))&lt;br /&gt;     .ToArray();&lt;br /&gt;if (possibleMatches == null || possibleMatches.Length == 0)&lt;br /&gt;  return null;&lt;br /&gt;if (possibleMatches.Length &gt; 1)&lt;br /&gt;  throw new AmbiguousMatchException(string.Format("The value collection contains ambigous match values for the parameter {0} {1}", type, name));&lt;br /&gt;return possibleMatches[0].GetValue(_actionData.Values, null);&lt;br /&gt;&lt;/pre&gt;Ok, so now we can invoke the method with our array of parameters. (as I said, a bit tedious).&lt;br /&gt;If we compare the two variants,&lt;br /&gt;&lt;pre class="c-sharp:nocontrols:nogutter" name="code"&gt;Controller.RegisterAction(createBoldTextButton, "CreateText", new {name="Bold", type=4});&lt;br /&gt;Controller.RegisterAction(createBoldTextButton, ()=&gt; Controller.CreateText("Bold", 4);&lt;br /&gt;&lt;/pre&gt;you understand why I have abandoned this last variant and only uses Actions/lambda functions.&lt;br /&gt;The tedious method can still be used if you want to lift the connection between view and controller to a configuration layer. Then the Action method will be hard to implement.&lt;br /&gt;&lt;br /&gt;That sums up this last part of my WinForms MVC framework lessons and experiences. Hope that you learned something.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6908201609754153877-2718870077747005393?l=dhvik.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?a=kwJF6artvLo:ZW-WovmQRIQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?a=kwJF6artvLo:ZW-WovmQRIQ:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?i=kwJF6artvLo:ZW-WovmQRIQ:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://dhvik.blogspot.com/feeds/2718870077747005393/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://dhvik.blogspot.com/2009/07/mvc-for-winforms-mapping-view-event-to.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6908201609754153877/posts/default/2718870077747005393" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6908201609754153877/posts/default/2718870077747005393" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DevelopingDotnetArchitect/~3/kwJF6artvLo/mvc-for-winforms-mapping-view-event-to.html" title="Mvc for Winforms - Mapping the View event to the Controller action Part III" /><author><name>Dan</name><uri>http://www.blogger.com/profile/14787263872119403136</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_BktCNuR9VXg/S_W8rNV-5hI/AAAAAAAABC0/BP4nWl1EXzc/S220/2009+-+Dan+H%C3%A4ndevik+80_80.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://dhvik.blogspot.com/2009/07/mvc-for-winforms-mapping-view-event-to.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-6908201609754153877.post-4030078708965151168</id><published>2009-06-24T11:40:00.009+02:00</published><updated>2009-06-26T07:28:45.708+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="SharePoint" /><title type="text">The start address &lt;https://newhostname.domain.com&gt; cannot be crawled</title><content type="html">Have a SharePoint site on one of our servers and have lately added a new hostname to that server to access a new site collection. I started getting a lot of entries in the eventlog using event id 2436 stating:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;The start address &amp;lt;https://newhostname.domain.com&amp;gt; cannot be crawled.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Context: Application 'Search index file on the search server', Catalog 'Search'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Details:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Access is denied. Check that the Default Content Access Account has access to this content, or add a crawl rule to crawl this content. (0x80041205)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Another symptom on this error is that if you open a web browser on the server itself and try to navigate to the url, you'll only get an authentication dialog (symptom on a 401 error).&lt;br /&gt;&lt;br /&gt;After a bit of searching I found a solution that I recognized. The following kb article &lt;a href="http://support.microsoft.com/kb/971382"&gt;http://support.microsoft.com/kb/971382&lt;/a&gt; provided the solution to add the new hostname to the registry key &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0\BackConnectionHostNames &lt;/span&gt;&lt;/span&gt; .&lt;br /&gt;&lt;br /&gt;When I started regedit I found that the key already existed and a couple of hostnames already was present. It seems that I had implemented this fix before.&lt;br /&gt;Better to write a post about it so I don't forget it in the future :)&lt;br /&gt;&lt;br /&gt;Ps. Don't forget to restart the server after applying the registry change. Ds.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6908201609754153877-4030078708965151168?l=dhvik.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?a=bmDDfAtxFC4:6cka8LUU64E:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?a=bmDDfAtxFC4:6cka8LUU64E:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?i=bmDDfAtxFC4:6cka8LUU64E:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://dhvik.blogspot.com/feeds/4030078708965151168/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://dhvik.blogspot.com/2009/06/start-address-cannot-be-crawled.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6908201609754153877/posts/default/4030078708965151168" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6908201609754153877/posts/default/4030078708965151168" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DevelopingDotnetArchitect/~3/bmDDfAtxFC4/start-address-cannot-be-crawled.html" title="The start address &amp;lt;https://newhostname.domain.com&amp;gt; cannot be crawled" /><author><name>Dan</name><uri>http://www.blogger.com/profile/14787263872119403136</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_BktCNuR9VXg/S_W8rNV-5hI/AAAAAAAABC0/BP4nWl1EXzc/S220/2009+-+Dan+H%C3%A4ndevik+80_80.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://dhvik.blogspot.com/2009/06/start-address-cannot-be-crawled.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-6908201609754153877.post-5960759059021408684</id><published>2009-06-24T07:26:00.005+02:00</published><updated>2009-09-28T06:10:43.354+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Tfs" /><category scheme="http://www.blogger.com/atom/ns#" term="WorkItemQueries" /><title type="text">Export and Import Work item queries in TFS projects</title><content type="html">I have lately been introducing new WorkItemTypes in our TFS project to handle tests and support cases. With those new types the need for modifying the queries in the current projects was necessary. To modify a query I could have opened them in visual studio and saved them to disk and then saved them individually to each project. Since we are getting a lot of projects (60+) this would be a quite tedious task to update 10+ queries in each project individually.&lt;br /&gt;To solve this administrative plague I  wrote a small commandline program that allows you to export and import queries from a project.&lt;br /&gt;&lt;br /&gt;Example&lt;br /&gt;To list all queries in a project&lt;br /&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;TFSQueryUtil.exe /t https://tfsserver.domain.com:8143 /p "My Tfs Project"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This will list every Work Item Query by Scope, Name and description&lt;br /&gt;&lt;br /&gt;To export all queries to the current folder&lt;br /&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;TFSQueryUtil.exe /t https://tfsserver.domain.com:8143 /p "My Tfs Project" /o Export /q *&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This will export each query using the name of the query (plus the .wiq extension) as name of the exported file. If you want to only export one query, use the example below.&lt;br /&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;TFSQueryUtil.exe /t https://tfsserver.domain.com:8143 /p "My Tfs Project" /o Export /q "My query"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;To import all *.wiq files to a project as Team queries&lt;br /&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;TFSQueryUtil.exe /t https://tfsserver.domain.com:8143 /p "My Tfs Project" /o Import /f *.wiq /qs Public&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This command will use the filename (without the .wiq extension) as name for the imported query.&lt;br /&gt;You can also specify a Description of the query by using the /qd switch (best for use with one query imports)&lt;br /&gt;&lt;br /&gt;The format of the wiq files follows the &lt;a href="http://msdn.microsoft.com/en-us/library/aa721763.aspx"&gt;WorkItemQuery schema&lt;/a&gt; but since the schema only includes the query and no meta data (like name, scope or description) this has to be provided as parameter switches... (Perhaps something to fix in TFS 2010)&lt;br /&gt;&lt;br /&gt;If you need more help add the /? parameter.&lt;br /&gt;&lt;br /&gt;I haven't released the program as open source but feel free to use it if you have need for it.&lt;br /&gt;Can be downloaded from &lt;a href="http://dan.meridium.se/TfsQueryUtil.rar"&gt;http://dan.meridium.se/TfsQueryUtil.rar&lt;/a&gt;&lt;br /&gt;To use it you need to have Team Foundation Explorer 2008 installed. (needs the tfs dlls in the GAC).&lt;br /&gt;&lt;br /&gt;2009-09-28 Update; small bugfix&lt;br /&gt;* Now writes xml files as utf-8 (was an in consequence between xml notation and file encoding)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6908201609754153877-5960759059021408684?l=dhvik.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?a=xVOOVehhrI4:K4tyu9ffp2A:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?a=xVOOVehhrI4:K4tyu9ffp2A:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?i=xVOOVehhrI4:K4tyu9ffp2A:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://dhvik.blogspot.com/feeds/5960759059021408684/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://dhvik.blogspot.com/2009/06/handling-work-item-queries.html#comment-form" title="9 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6908201609754153877/posts/default/5960759059021408684" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6908201609754153877/posts/default/5960759059021408684" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DevelopingDotnetArchitect/~3/xVOOVehhrI4/handling-work-item-queries.html" title="Export and Import Work item queries in TFS projects" /><author><name>Dan</name><uri>http://www.blogger.com/profile/14787263872119403136</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_BktCNuR9VXg/S_W8rNV-5hI/AAAAAAAABC0/BP4nWl1EXzc/S220/2009+-+Dan+H%C3%A4ndevik+80_80.jpg" /></author><thr:total>9</thr:total><feedburner:origLink>http://dhvik.blogspot.com/2009/06/handling-work-item-queries.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-6908201609754153877.post-3598932492597013336</id><published>2009-05-05T14:27:00.005+02:00</published><updated>2009-05-05T15:50:36.346+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Visual Studio" /><category scheme="http://www.blogger.com/atom/ns#" term="Macros" /><title type="text">New version of DocumentatorMacros</title><content type="html">Long time since last version was released officially... (almost two years), time to make a change.&lt;br /&gt;New version can be downloaded from &lt;a href="http://dan.meridium.se/DocumentatorMacros/v2.5.2.0/Meridium.rar"&gt;http://dan.meridium.se/DocumentatorMacros/v2.5.2.0/Meridium.rar&lt;/a&gt;&lt;br /&gt;(For more information about the Documentator Macros, see &lt;a href="http://www.codeproject.com/KB/cs/documentatormacros.aspx"&gt;http://www.codeproject.com/KB/cs/documentatormacros.aspx&lt;/a&gt; )&lt;br /&gt;&lt;br /&gt;New version contains some news:&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Contains support for Resharper 4.5, Visual studio 2008 and some minor changes.&lt;/p&gt;&lt;p&gt;Enhancements /Bugfixes&lt;/p&gt;&lt;ul&gt;&lt;li&gt;No longer enters wrong type of linefeeds when applying some functions&lt;/li&gt;&lt;li&gt;PasteTemplate &lt;ul&gt;&lt;li&gt;now indents correctly&lt;/li&gt;&lt;li&gt;Handles static events&lt;/li&gt;&lt;li&gt;Handles new, virtual, override keywords when converting fields-&gt;property&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;DocumentThis - Now autodocuments thrown exceptions&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6908201609754153877-3598932492597013336?l=dhvik.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?a=zJEQGNloERs:5OHFRCCdrtY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?a=zJEQGNloERs:5OHFRCCdrtY:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?i=zJEQGNloERs:5OHFRCCdrtY:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://dhvik.blogspot.com/feeds/3598932492597013336/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://dhvik.blogspot.com/2009/05/new-version-of-documentatormacros.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6908201609754153877/posts/default/3598932492597013336" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6908201609754153877/posts/default/3598932492597013336" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DevelopingDotnetArchitect/~3/zJEQGNloERs/new-version-of-documentatormacros.html" title="New version of DocumentatorMacros" /><author><name>Dan</name><uri>http://www.blogger.com/profile/14787263872119403136</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_BktCNuR9VXg/S_W8rNV-5hI/AAAAAAAABC0/BP4nWl1EXzc/S220/2009+-+Dan+H%C3%A4ndevik+80_80.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://dhvik.blogspot.com/2009/05/new-version-of-documentatormacros.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-6908201609754153877.post-1140612338907618620</id><published>2009-05-04T13:31:00.008+02:00</published><updated>2009-05-05T15:52:13.442+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><category scheme="http://www.blogger.com/atom/ns#" term="Linq" /><category scheme="http://www.blogger.com/atom/ns#" term="Lambda" /><title type="text">AssemblyName.GetPublicKeyToken() ToString using lambda</title><content type="html">I was searching for a convenient way to get the public key token from a signed assembly and present it in an ordinary string style that is found in all FQ assembly names. The problem is that the GetPublicKeyToken() method from the Assembly type returns a byte array and using ToString() isn’t that great.&lt;br /&gt;&lt;br /&gt;I searched the net a bit and all I found was examples on how to do it with a loop and using ToString(”x2”) on every byte, or even more horrible, indexing the 8 bytes by hand...&lt;br /&gt;But if I use a linq/lambda expression, this could be a nice one-liner? ’aye?!&lt;br /&gt;&lt;br /&gt;Ok, first convert the byte array to a string array&lt;br /&gt;&lt;pre class="c-sharp:nocontrols:nogutter" name="code"&gt;GetPublicKeyToken().Select(x=&gt;x.ToString(”x2”))&lt;/pre&gt;Then aggregate (i was trying the concat first, but that didn’t make any sense) to a single string.&lt;br /&gt;&lt;pre class="c-sharp:nocontrols:nogutter" name="code"&gt;.Aggregate((x, y) =&gt; x + y)&lt;/pre&gt;With some error handling this boils down to the following method.&lt;br /&gt;&lt;br /&gt;&lt;pre class="c-sharp:nocontrols:nogutter" name="code"&gt;#region public static string GetAssemblyPublickKeyToken(Assembly assembly)&lt;br /&gt;/// &amp;lt;summary&amp;gt;&lt;br /&gt;/// Gets the public key token of the supplied argument&lt;br /&gt;/// &amp;lt;/summary&amp;gt;&lt;br /&gt;/// &amp;lt;param name="assembly"&amp;gt;The &amp;lt;see cref="Assembly"&amp;gt;to get the public key token for&amp;lt;/param&amp;gt;&lt;br /&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;br /&gt;/// &amp;lt;exception cref="ArgumentNullException"&amp;gt;If &amp;lt;paramref name="assembly"&amp;gt;is null.&amp;lt;/exception&amp;gt;&lt;br /&gt;public static string GetAssemblyPublickKeyToken(Assembly assembly) {&lt;br /&gt;    if (assembly == null) {&lt;br /&gt;        throw new ArgumentNullException("assembly");&lt;br /&gt;    }&lt;br /&gt;    byte[] token = assembly.GetName().GetPublicKeyToken();&lt;br /&gt;    if(token == null token.Length==0)&lt;br /&gt;        return null;&lt;br /&gt;    return token.Select(x =&amp;gt; x.ToString("x2")).Aggregate((x, y) =&amp;gt; x + y);&lt;br /&gt;}&lt;br /&gt;#endregion&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6908201609754153877-1140612338907618620?l=dhvik.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?a=_U_qZsChk0M:vMfB-dxUOWw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?a=_U_qZsChk0M:vMfB-dxUOWw:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?i=_U_qZsChk0M:vMfB-dxUOWw:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://dhvik.blogspot.com/feeds/1140612338907618620/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://dhvik.blogspot.com/2009/05/assemblynamegetpublickeytoken-tostring.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6908201609754153877/posts/default/1140612338907618620" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6908201609754153877/posts/default/1140612338907618620" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DevelopingDotnetArchitect/~3/_U_qZsChk0M/assemblynamegetpublickeytoken-tostring.html" title="AssemblyName.GetPublicKeyToken() ToString using lambda" /><author><name>Dan</name><uri>http://www.blogger.com/profile/14787263872119403136</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_BktCNuR9VXg/S_W8rNV-5hI/AAAAAAAABC0/BP4nWl1EXzc/S220/2009+-+Dan+H%C3%A4ndevik+80_80.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://dhvik.blogspot.com/2009/05/assemblynamegetpublickeytoken-tostring.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-6908201609754153877.post-5015030584530540449</id><published>2009-01-21T15:17:00.008+01:00</published><updated>2009-01-21T15:42:57.673+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="MVC" /><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET" /><title type="text">RadioButton helper and label</title><content type="html">When using Mvc (beta) and rendering RadioButtons using the HtmlHelper they are rendered without any text or description. The label tag is used for this but is not rendered by the RadionButtons method.&lt;br /&gt;Example;&lt;br /&gt;&lt;pre name="code" class="c-sharp:nocontrols:nogutter"&gt;&amp;lt;%=Html.RadioButton("MyRadioButton","MyValue")%&amp;gt;&lt;/pre&gt;renders&lt;br /&gt;&lt;pre name="code" class="html:nocontrols:nogutter"&gt;&amp;lt;input id="MyRadioButton" value="MyValue" name="MyRadioButton" type="radio"&amp;gt;&lt;br /&gt;&lt;/pre&gt;To get the label we just add the label tag and uses the input tags id as reference for the label.&lt;br /&gt;&lt;pre name="code" class="html:nocontrols:nogutter"&gt;&amp;lt;label for="MyRadioButton"&amp;gt;My description&amp;lt;/label&amp;gt;&lt;/pre&gt;This will allow us to check the radio button by clicking on the label as well.&lt;br /&gt;&lt;br /&gt;Then the problem occurs if we should use multiple radio buttons with the same name.&lt;br /&gt;Example;&lt;br /&gt;&lt;pre name="code" class="c-sharp:nocontrols:nogutter"&gt;&amp;lt;%=Html.RadioButton("IsItRaining","Yes")%&amp;gt;&lt;br /&gt;&amp;lt;%=Html.RadioButton("IsItRaining","No")%&amp;gt;&lt;/pre&gt;This will render&lt;br /&gt;renders&lt;br /&gt;&lt;pre name="code" class="html:nocontrols:nogutter"&gt;&amp;lt;input id="IsItRaining" value="Yes" name="IsItRaining" type="radio"&amp;gt;&lt;br /&gt;&amp;lt;input id="IsItRaining" value="No" name="IsItRaining" type="radio"&amp;gt;&lt;/pre&gt;&lt;br /&gt;This it not so well since we need different id attributes to be able to bind the label tags.&lt;br /&gt;To fix this we need to add different ids to the input tags.&lt;br /&gt;Example:&lt;br /&gt;&lt;pre name="code" class="c-sharp:nocontrols:nogutter"&gt;&amp;lt;%=Html.RadioButton("IsItRaining", "Yes", new {id="IsItRaining_Yes"})%&amp;gt;&amp;lt;label for="IsItRaining_Yes"&amp;gt;Yes&amp;lt;/label&amp;gt;&lt;br /&gt;&amp;lt;%=Html.RadioButton("IsItRaining", "No", new {id="IsItRaining_No"})%&amp;gt;&amp;lt;label for="IsItRaining_No"&amp;gt;No&amp;lt;/label&amp;gt;&lt;/pre&gt;That will produce the intended output;&lt;br /&gt;&lt;pre name="code" class="html:nocontrols:nogutter"&gt;&amp;lt;input id="IsItRaining_Yes" type="radio" value="Yes" name="IsItRaining"/&amp;gt;&lt;br /&gt;&amp;lt;label for="IsItRaining_Yes"&amp;gt;Yes&amp;lt;/label&amp;gt;&lt;br /&gt;&amp;lt;input id="IsItRaining_No" type="radio" value="No" name="IsItRaining"/&amp;gt;&lt;br /&gt;&amp;lt;label for="IsItRaining_No"&amp;gt;No&amp;lt;/label&amp;gt;&lt;/pre&gt;And will work as below&lt;br /&gt;&lt;br /&gt;&lt;input id="IsItRaining_Yes" value="Yes" name="IsItRaining" type="radio"&gt;&lt;label for="IsItRaining_Yes"&gt;Yes&lt;/label&gt;&lt;input id="IsItRaining_No" value="No" name="IsItRaining" type="radio"&gt;&lt;label for="IsItRaining_No"&gt;No&lt;/label&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6908201609754153877-5015030584530540449?l=dhvik.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?a=JXV0fzrFFrI:NpVluqHW1FY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?a=JXV0fzrFFrI:NpVluqHW1FY:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?i=JXV0fzrFFrI:NpVluqHW1FY:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://dhvik.blogspot.com/feeds/5015030584530540449/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://dhvik.blogspot.com/2009/01/radiobutton-helper-and-label.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6908201609754153877/posts/default/5015030584530540449" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6908201609754153877/posts/default/5015030584530540449" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DevelopingDotnetArchitect/~3/JXV0fzrFFrI/radiobutton-helper-and-label.html" title="RadioButton helper and label" /><author><name>Dan</name><uri>http://www.blogger.com/profile/14787263872119403136</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_BktCNuR9VXg/S_W8rNV-5hI/AAAAAAAABC0/BP4nWl1EXzc/S220/2009+-+Dan+H%C3%A4ndevik+80_80.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://dhvik.blogspot.com/2009/01/radiobutton-helper-and-label.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-6908201609754153877.post-7420980092512393354</id><published>2008-11-27T12:22:00.004+01:00</published><updated>2008-11-27T12:35:35.193+01:00</updated><title type="text">The GetField method</title><content type="html">Last month I wrote an &lt;a href="http://dhvik.blogspot.com/2008/10/clicking-winforms-button-from-code.html"&gt;article about clicking a button in a winforms application&lt;/a&gt; and in my code example I referred to the ReflectionUtil.GetField method. &lt;br /&gt;The ReflectionUtil class is an utility class that I have used for several years and they provide a better/easier way to use reflection. They are in line to be converted as Extension methods for the Type type, but for now they are ordinary static methods.&lt;br /&gt;I'll post the GetField method to allow the example to be complete.&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="c-sharp:nocontrols:nogutter"&gt;#region public static object GetField(Type type, string name, object instance)&lt;br /&gt;/// &amp;lt;summary&amp;gt;&lt;br /&gt;/// Gets the field from the instance&lt;br /&gt;/// &amp;lt;/summary&amp;gt;&lt;br /&gt;/// &amp;lt;param name="type"&amp;gt;The &amp;lt;see cref="Type"/&amp;gt; that contains the field&amp;lt;/param&amp;gt;&lt;br /&gt;/// &amp;lt;param name="name"&amp;gt;The name of the field&amp;lt;/param&amp;gt;&lt;br /&gt;/// &amp;lt;param name="instance"&amp;gt;The instance to get the value from&amp;lt;/param&amp;gt;&lt;br /&gt;/// &amp;lt;returns&amp;gt;The value of the field&amp;lt;/returns&amp;gt;&lt;br /&gt;public static object GetField(Type type, string name, object instance) {&lt;br /&gt;    return InvokeMember(type, name, instance, BindingFlags.GetField | BindingFlags.Instance);&lt;br /&gt;}&lt;br /&gt;#endregion&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The GetField only wraps the InvokeMember method. (I have more wrappers named GetProperty, SetField, SetProperty, InvokeMethod, InvokeStaticMethod etc. that calls the InvokeMember method)&lt;br /&gt;&lt;pre name="code" class="c-sharp:nocontrols:nogutter"&gt;#region public static object InvokeMember(Type type, string name, object instance, BindingFlags flags, params object[] parameters)&lt;br /&gt;/// &amp;lt;summary&amp;gt;&lt;br /&gt;/// Invokes the member&lt;br /&gt;/// &amp;lt;/summary&amp;gt;&lt;br /&gt;/// &amp;lt;param name="type"&amp;gt;The &amp;lt;see cref="Type"/&amp;gt; that contains the member&amp;lt;/param&amp;gt;&lt;br /&gt;/// &amp;lt;param name="name"&amp;gt;The name of the member&amp;lt;/param&amp;gt;&lt;br /&gt;/// &amp;lt;param name="instance"&amp;gt;The instance to invoke on&amp;lt;/param&amp;gt;&lt;br /&gt;/// &amp;lt;param name="flags"&amp;gt;The &amp;lt;see cref="BindingFlags"/&amp;gt; to use&amp;lt;/param&amp;gt;&lt;br /&gt;/// &amp;lt;param name="parameters"&amp;gt;The &amp;lt;see cref="object"/&amp;gt; array to pass as parameters&amp;lt;/param&amp;gt;&lt;br /&gt;/// &amp;lt;returns&amp;gt;The returnvalue&amp;lt;/returns&amp;gt;&lt;br /&gt;public static object InvokeMember(Type type, string name, object instance, BindingFlags flags, params object[] parameters) {&lt;br /&gt;    if (instance == null) {&lt;br /&gt;        flags |= BindingFlags.Static;&lt;br /&gt;        flags &amp;= ~BindingFlags.Instance;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    try {&lt;br /&gt;        return type.InvokeMember(name,BindingFlags.Public | BindingFlags.NonPublic | flags,null,instance,parameters);&lt;br /&gt;&lt;br /&gt;        //if the target threw an exception, throw this instead.&lt;br /&gt;    } catch (TargetInvocationException e) {&lt;br /&gt;&lt;br /&gt;        // if no exception is found, throw the TIException instead.&lt;br /&gt;        if (e.InnerException == null)&lt;br /&gt;            throw;&lt;br /&gt;        throw e.InnerException;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;#endregion&lt;/pre&gt;&lt;br /&gt;Hope the click button example can make more sense now :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6908201609754153877-7420980092512393354?l=dhvik.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?a=pyTZN_yt-5g:CwFtAO1N40w:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?a=pyTZN_yt-5g:CwFtAO1N40w:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?i=pyTZN_yt-5g:CwFtAO1N40w:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://dhvik.blogspot.com/feeds/7420980092512393354/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://dhvik.blogspot.com/2008/11/getfield-method.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6908201609754153877/posts/default/7420980092512393354" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6908201609754153877/posts/default/7420980092512393354" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DevelopingDotnetArchitect/~3/pyTZN_yt-5g/getfield-method.html" title="The GetField method" /><author><name>Dan</name><uri>http://www.blogger.com/profile/14787263872119403136</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_BktCNuR9VXg/S_W8rNV-5hI/AAAAAAAABC0/BP4nWl1EXzc/S220/2009+-+Dan+H%C3%A4ndevik+80_80.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://dhvik.blogspot.com/2008/11/getfield-method.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-6908201609754153877.post-7136687347448278039</id><published>2008-11-02T21:11:00.009+01:00</published><updated>2008-11-02T23:01:27.852+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="MVC" /><category scheme="http://www.blogger.com/atom/ns#" term="Lambda" /><category scheme="http://www.blogger.com/atom/ns#" term="Winforms" /><title type="text">Mvc for Winforms - Mapping the View event to the Controller action Part II</title><content type="html">This time I will try to deliver part of the answer to the requirements from &lt;a href="http://dhvik.blogspot.com/2008/11/mvc-for-winforms-mapping-view-event-to.html"&gt;my previous post&lt;/a&gt;. To recap I would like to be able to connect a component to a controller action by calling the RegisterAction method like below.&lt;br /&gt;&lt;pre name="code" class="c-sharp:nocontrols:nogutter"&gt;Controller.RegisterAction(saveButton, "Save");&lt;br /&gt;Controller.RegisterAction(createBoldTextButton, "CreateText", new {name="Bold", type=4});&lt;br /&gt;Controller.RegisterAction(myTextBox, "ValidateText","Validating", null);&lt;br /&gt;&lt;/pre&gt;And letting those events call the actions defined below&lt;br /&gt;&lt;pre name="code" class="c-sharp:nocontrols:nogutter"&gt;public void Save() {...}&lt;br /&gt;public void CreateText(string name, int type) {...}&lt;br /&gt;public void ValidateText(CancelEventArgs e, object source) {...}&lt;br /&gt;&lt;/pre&gt;I will divide the solution in two steps and in this post I will cover the first, that is capturing the event of the object.&lt;br /&gt;&lt;br /&gt;We start by creating the RegisterAction method. We get the object which event should be listened to and sometimes also the name of the event that we should listen to. If this argument isn't supplied we need to find the DefaultEvent of the object.&lt;br /&gt;&lt;br /&gt;By using reflection we can retrieve the DefaultEventAttribute of the object. The following unit test shows how to get the attribute for a Button object. Notice the true flag on the GetCustomAttributes call. Since the DefaultEventAttribute is not present on the Button class itself, we need to go down in the inheritance chain to look for the attribute. Not until we reach the Control class we find the DefaultEventAttribute.&lt;br /&gt;&lt;pre name="code" class="c-sharp:nocontrols:nogutter"&gt;[Test]&lt;br /&gt;public void GetDefaultEventAttribute() {&lt;br /&gt; object obj = new Button();&lt;br /&gt; DefaultEventAttribute attribute = null;&lt;br /&gt; Attribute[] attributes = obj.GetType().GetCustomAttributes(typeof(DefaultEventAttribute), true) as Attribute[];&lt;br /&gt; if (attributes != null &amp;amp;&amp;amp; attributes.Length &gt; 0) {&lt;br /&gt;     attribute = attributes[0] as DefaultEventAttribute;&lt;br /&gt; }&lt;br /&gt; Assert.IsNotNull(attribute);&lt;br /&gt;}&lt;/pre&gt;When we have the attribute, we just look at the Name property to get the name of the default event.&lt;br /&gt;&lt;br /&gt;Now when we have the name of the event (either by parameter or using the DefaultEventAttribute) we should add listener to the event. The listener method is a method in the Controller class, not the controller Action (we will get to that in the next part), but a event hub where all the Views events will pass before they are dispatched to the correct Action. The event hub method is declared as below&lt;br /&gt;&lt;pre name="code" class="c-sharp:nocontrols:nogutter"&gt;public void ExecuteAction(object source, object eventArgs, ActionData actionData)&lt;/pre&gt;The ExecuteAction method takes three parameters. The source and arguments of the event that was fired (this is the same values that the original event passes along). The third parameter contains the data for the action that is to take place, like the name of the action and any value parameters (The values that are stated when registering the action).&lt;br /&gt;&lt;br /&gt;So we got the object and the name of the event and the target method of the event, but how can we connect them?&lt;br /&gt;&lt;br /&gt;My first thought was to generate a delegate to the ExecuteAction and use reflection to get the EventInfo for the event and use the AddEventHandler of the EventInfo class to bind to the ExecuteAction method.&lt;br /&gt;&lt;pre name="code" class="c-sharp:nocontrols:nogutter"&gt;[Test]&lt;br /&gt;public void BindToButtonClickEvent() {&lt;br /&gt; object obj = new Button();&lt;br /&gt; EventInfo info = obj.GetType().GetEvent("Click");&lt;br /&gt; MethodInfo method = GetType().GetMethod("ExecuteAction");&lt;br /&gt; Delegate d = Delegate.CreateDelegate(typeof(MyExecuteAction),method);&lt;br /&gt; info.AddEventHandler(obj,d);&lt;br /&gt;}&lt;br /&gt;private delegate void MyExecuteAction(object source, object eventArgs, ActionData actionData);&lt;br /&gt;public void ExecuteAction(object source, object eventArgs, ActionData actionData) {}&lt;/pre&gt;But when I ran this code I got an Exception&lt;br /&gt;&lt;pre&gt;System.ArgumentException: Error binding to target method.&lt;/pre&gt;Of course this won't work since the Click event cannot directly connect to the ExecuteAction method because the Click event can only add handlers that matches the EventHandler delegate, a method with a void return value and two arguments, object and EventArgs.&lt;br /&gt;&lt;br /&gt;The conclusion of this is that if I would like to have a single method that acts as an event hub and it must be able to handle any type of delegate that the event declares (note that events as practice should always return void and take two arguments, object and a instance of an EventArgs derived class), I need to generate this method in runtime.&lt;br /&gt;&lt;br /&gt;The first option that comes to mind is using Emit. I have tested this in the past, it has worked but comes not so natural to me. &lt;a href="http://ayende.com/Blog/archive/2007/10/29/Dynamic-Methods.aspx"&gt;Oren Eini&lt;/a&gt; used this technique but since I would like to pass a local variable (the ActionData instance) in the call, I needed to modify this piece of code, and possibly use an external list of ActionData instances if I couldn't pass them along using the dynamic method, I searched a bit more for an alternative (second opinion)...&lt;br /&gt;&lt;br /&gt;Finally I came across &lt;a href="http://stackoverflow.com/questions/45779"&gt;an answer from Mark Cidade&lt;/a&gt; that compiled a method in runtime using lambda expressions and that was fairly easy to modify.&lt;br /&gt;First we need to setup the call to the ExecuteAction method. This is done using a lambda expression and storing it in the &lt;a href="http://msdn.microsoft.com/en-us/library/bb549311.aspx"&gt;Action&lt;t1,t2&gt; delegate&lt;/t1,t2&gt;&lt;/a&gt;.&lt;br /&gt;&lt;pre name="code" class="c-sharp:nocontrols:nogutter"&gt;ActionData actionData = new ActionData("Save", null);&lt;br /&gt;//Create the delegate using an lambda expression&lt;br /&gt;Action&amp;lt;object,object&amp;gt; eventHubCall = (source, e) =&gt; ExecuteAction(source, e, actionData);&lt;br /&gt;&lt;/pre&gt;This action will take two parameters and call the ExecuteAction just the way as we would like it to. The problem is that this expression is not typed the correct way as the event is so we need to create a new method using lambda expressions again but with the correct declaration. So we start by getting the information about the event.&lt;br /&gt;&lt;pre name="code" class="c-sharp:nocontrols:nogutter"&gt;Type type = obj.GetType();&lt;br /&gt;EventInfo evt = type.GetEvent("Click");&lt;br /&gt;ParameterInfo[] eventParams = evt.EventHandlerType.GetMethod("Invoke").GetParameters();&lt;/pre&gt;Then we create the lambda&lt;pre name="code" class="c-sharp:nocontrols:nogutter"&gt;ParameterExpression[] parameters = eventParams.&lt;br /&gt;  Select(p =&gt; Expression.Parameter(p.ParameterType, "x")).ToArray();&lt;br /&gt;MethodCallExpression body = Expression.Call(Expression.Constant(eventHubCall),&lt;br /&gt;  eventHubCall.GetType().GetMethod("Invoke"), parameters);&lt;br /&gt;LambdaExpression lambda = Expression.Lambda(body, parameters);&lt;br /&gt;&lt;/pre&gt;Now we have a method with two parameters of the correct type, the only thing left is to create a delegate that we can use for adding to the event.&lt;pre name="code" class="c-sharp:nocontrols:nogutter"&gt;Delegate proxy = Delegate.CreateDelegate(evt.EventHandlerType, lambda.Compile(), "Invoke", false);&lt;br /&gt;evt.AddEventHandler(obj, proxy);      &lt;br /&gt;&lt;/pre&gt;Tada!! No more Error binding to target method errors.&lt;br /&gt;The complete test follows.&lt;br /&gt;&lt;pre name="code" class="c-sharp:nocontrols:nogutter"&gt;[Test]&lt;br /&gt;public void BindToButtonClickEvent2() {&lt;br /&gt; ActionData actionData = new ActionData("Save", null);&lt;br /&gt; //Create the delegate using an lambda expression&lt;br /&gt; Action&amp;lt;object,object&amp;gt; eventHubCall = (source, e) =&gt; ExecuteAction(source, e, actionData);&lt;br /&gt;&lt;br /&gt; object obj = new Button();&lt;br /&gt; //find the exact definition of the event&lt;br /&gt; Type type = obj.GetType();&lt;br /&gt; EventInfo evt = type.GetEvent("Click");&lt;br /&gt; ParameterInfo[] eventParams = evt.EventHandlerType.GetMethod("Invoke").GetParameters();&lt;br /&gt;&lt;br /&gt; //create a new lambda expression using the correct parameters&lt;br /&gt; ParameterExpression[] parameters = eventParams.&lt;br /&gt;      Select(p =&gt; Expression.Parameter(p.ParameterType, "x")).ToArray();&lt;br /&gt; //call the event hub&lt;br /&gt; MethodCallExpression body = Expression.Call(Expression.Constant(eventHubCall),&lt;br /&gt;      eventHubCall.GetType().GetMethod("Invoke"), parameters);&lt;br /&gt; //create the expression with the correct parameters to match the event&lt;br /&gt; LambdaExpression lambda = Expression.Lambda(body, parameters);&lt;br /&gt; //and then create the delegate that wraps the lambda expression.&lt;br /&gt; Delegate proxy= Delegate.CreateDelegate(evt.EventHandlerType, lambda.Compile(), "Invoke", false);&lt;br /&gt;&lt;br /&gt; evt.AddEventHandler(obj, proxy);      &lt;br /&gt;}&lt;/pre&gt;Not so dumb ey! All credits goes to &lt;a href="http://www.marxidad.com/"&gt;Mark Cidade&lt;/a&gt; for providing the elegant solution. (So I perhaps my greatest talent is to find solutions that others have done before me, and use them ;)&lt;br /&gt;Anyway, that concludes part II and next we will look how to call the action method of the controller from the ExecuteAction method.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6908201609754153877-7136687347448278039?l=dhvik.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?a=hTm7rdxw_SU:-Xi5Ldw2XDw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?a=hTm7rdxw_SU:-Xi5Ldw2XDw:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?i=hTm7rdxw_SU:-Xi5Ldw2XDw:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://dhvik.blogspot.com/feeds/7136687347448278039/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://dhvik.blogspot.com/2008/11/mvc-for-winforms-mapping-view-event-to_02.html#comment-form" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6908201609754153877/posts/default/7136687347448278039" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6908201609754153877/posts/default/7136687347448278039" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DevelopingDotnetArchitect/~3/hTm7rdxw_SU/mvc-for-winforms-mapping-view-event-to_02.html" title="Mvc for Winforms - Mapping the View event to the Controller action Part II" /><author><name>Dan</name><uri>http://www.blogger.com/profile/14787263872119403136</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_BktCNuR9VXg/S_W8rNV-5hI/AAAAAAAABC0/BP4nWl1EXzc/S220/2009+-+Dan+H%C3%A4ndevik+80_80.jpg" /></author><thr:total>5</thr:total><feedburner:origLink>http://dhvik.blogspot.com/2008/11/mvc-for-winforms-mapping-view-event-to_02.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-6908201609754153877.post-1787092027089813591</id><published>2008-11-01T23:41:00.008+01:00</published><updated>2008-11-02T22:54:19.656+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="MVC" /><category scheme="http://www.blogger.com/atom/ns#" term="Winforms" /><title type="text">Mvc for Winforms - Mapping the View event to the Controller action</title><content type="html">In my current (or rather one of my current projects) I'm writing a small MVC framework for a WinForms application (I mentioned this in my &lt;a href="http://dhvik.blogspot.com/2008/10/clicking-winforms-button-from-code.html"&gt;last post&lt;/a&gt;). The latest issue that I stumbled upon and found worth mentioning is about connecting the Views events to the Controllers actions.&lt;br /&gt;&lt;br /&gt;If we look at the MVC for ASP.NET the events is the requests by the web client and the URL contains the information that the Routing module uses to find an appropriate action to call. It should be nice to have such a feature in the WinForms solution as well so after some thought I summarized a small example.&lt;br /&gt;&lt;br /&gt;In my view I can have several objects (not necessary controls) that can/will fire some events (like a button firering the click event when the user clicks it).&lt;br /&gt;In my controller I have several action methods that should be called by the view when the appropriate event occurs. (Like a Save action that should be called when the user clicks the save button, thus triggering the save button click event) (nothing out of the ordinary here;)&lt;br /&gt;&lt;br /&gt;Whats the fuzz about this then, you may think? This is normal stuff, no strange things!? (who is this dumb guy anyway...)&lt;br /&gt;&lt;br /&gt;Yes I see your point. I could easily use the Forms designer in Visual studio, double click the Save button and enter the code below to call the Save button.&lt;br /&gt;&lt;pre name="code" class="c-sharp:nocontrols:nogutter"&gt;private void saveButton_Click(object sender, System.EventArgs e) {&lt;br /&gt;  Controller.Save();&lt;br /&gt;}&lt;/pre&gt;But thats not what I want. I don't want to litter the View with a lot of event methods just calling one line of code. The purpose of the MVC pattern is to separate the View from the logic and if we start putting those event handler methods in the view, soon some line of controller logic will be entered in there (just to test) and we'll never find the way to clean them up again.&lt;br /&gt;&lt;br /&gt;My vision is to register these events one by one in the Views constructor, on one line that enables me to&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Listen to an event from an object in the view&lt;/li&gt;&lt;li&gt;Capture the event and pass it to an action in the controller&lt;/li&gt;&lt;li&gt;Allow the mapping to pass additional parameters to the action (compare the routing in MVC for ASP.NET)&lt;/li&gt;&lt;/ul&gt;If I would make the same example like the one above but using the one liner instead, it would look like below.&lt;br /&gt;&lt;pre name="code" class="c-sharp:nocontrols:nogutter"&gt;Controller.RegisterAction(saveButton,"Save");&lt;/pre&gt;If I would pass some parameters to the action I could use the same syntax as when defining default routes in MVC for ASP.NET.&lt;br /&gt;&lt;pre name="code" class="c-sharp:nocontrols:nogutter"&gt;Controller.RegisterAction(createBoldTextButton,"CreateText", new {name="Bold",type=4});&lt;/pre&gt;This would then be mapped to the action CreateText which declaration looks like below.&lt;br /&gt;&lt;pre name="code" class="c-sharp:nocontrols:nogutter"&gt;public void CreateText(string name, int type) {...}&lt;/pre&gt;If I want to listen to an event that isn't the DefaultEvent (see the &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.defaulteventattribute.aspx"&gt;DefaultEventAttribute&lt;/a&gt;) I could state this as well in the call&lt;br /&gt;&lt;pre name="code" class="c-sharp:nocontrols:nogutter"&gt;Controller.RegisterAction(myTextBox,"ValidateText","Validating", null);&lt;/pre&gt;And if I declare the action to include the event argument and/or source they should be passed along as well&lt;br /&gt;&lt;pre name="code" class="c-sharp:nocontrols:nogutter"&gt;public void ValidateText(CancelEventArgs e, object source) {...}&lt;/pre&gt; How do I code this to be like I want it to then???&lt;br /&gt;&lt;br /&gt;In my &lt;a href="http://dhvik.blogspot.com/2008/11/mvc-for-winforms-mapping-view-event-to_02.html"&gt;next post&lt;/a&gt; I will try to give you a solution to the requirements above and hopefully prove that I'm not a dumb guy after all ;)&lt;br /&gt;See ya!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6908201609754153877-1787092027089813591?l=dhvik.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?a=i5XBHJEbfKQ:IydJ8p1e5Zs:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?a=i5XBHJEbfKQ:IydJ8p1e5Zs:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?i=i5XBHJEbfKQ:IydJ8p1e5Zs:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://dhvik.blogspot.com/feeds/1787092027089813591/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://dhvik.blogspot.com/2008/11/mvc-for-winforms-mapping-view-event-to.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6908201609754153877/posts/default/1787092027089813591" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6908201609754153877/posts/default/1787092027089813591" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DevelopingDotnetArchitect/~3/i5XBHJEbfKQ/mvc-for-winforms-mapping-view-event-to.html" title="Mvc for Winforms - Mapping the View event to the Controller action" /><author><name>Dan</name><uri>http://www.blogger.com/profile/14787263872119403136</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_BktCNuR9VXg/S_W8rNV-5hI/AAAAAAAABC0/BP4nWl1EXzc/S220/2009+-+Dan+H%C3%A4ndevik+80_80.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://dhvik.blogspot.com/2008/11/mvc-for-winforms-mapping-view-event-to.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-6908201609754153877.post-7362925671236316634</id><published>2008-10-27T11:11:00.006+01:00</published><updated>2008-10-27T11:43:27.884+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Unittest" /><title type="text">Clicking a winforms button from code</title><content type="html">Today I was writing a unit test for a winforms application (or rather a small Mvc framework for winforms) and I would like to simulate a button click on the form to se that all events had been wired correctly.&lt;br /&gt;Since the event is a delegate, I thought it would be easy to just call the Invoke/DynamicInvoke methods of the Click delegate instance to get the events fiering...&lt;br /&gt;It wasn't quite that easy though. When I tried to use the code&lt;br /&gt;&lt;pre name="code" class="c-sharp:nocontrols:nogutter"&gt;button.Click.Invoke(this,EventArgs.Empty);&lt;/pre&gt;I got a compiler error&lt;br /&gt;&lt;br /&gt;The event 'System.Windows.Forms.Control.Click' can only appear on the left hand side of += or -=&lt;br /&gt;&lt;br /&gt;After a search I found &lt;a href="http://it.toolbox.com/blogs/parthas/events-vs-delegates-contd-10596"&gt;an article by Partha S&lt;/a&gt; that summarized the issue quite well, namely the difference between an event and a delegate is that the event can control the chaining and the event can only be invoked from within the declaring class. Partha also provided a solution for declaring an event that can be called from external code but that don't help me since I cannot modify the Button class.&lt;br /&gt;&lt;br /&gt;A workaround is then to use reflection for retrieving the delegate field from the button class and when we have direct access to the delegate (not through the event wrapper construct) we will be able to Invoke the event.&lt;br /&gt;The code below contains a method "GetField" that is included in our base library that I can post if anyone is interested, but for now it returns the value of a field.&lt;br /&gt;&lt;pre name="code" class="c-sharp:nocontrols:nogutter"&gt;//All events in a Component is listed in an EventHandlerList &lt;br /&gt;//called events in the Component class. &lt;br /&gt;//b is the button instance.&lt;br /&gt;EventHandlerList list = ReflectionUtil.GetField(&lt;br /&gt;    typeof(Component), "events", b) as EventHandlerList;&lt;br /&gt;Assert.IsNotNull(list,"Cannot get eventlist from component");&lt;br /&gt;&lt;br /&gt;//in the EventHandlerList, each delegate is identified by a&lt;br /&gt;//static object instance in the control class&lt;br /&gt;object eventClick = ReflectionUtil.GetField(typeof(Control),&lt;br /&gt;    "EventClick",null);&lt;br /&gt;&lt;br /&gt;//now we get the click event delegate&lt;br /&gt;Delegate click = list[eventClick];&lt;br /&gt;&lt;br /&gt;//finally we can invoke the listeners of the click event.&lt;br /&gt;click.DynamicInvoke(this, EventArgs.Empty);&lt;br /&gt;&lt;/pre&gt;So now I can click da button in my unittest :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6908201609754153877-7362925671236316634?l=dhvik.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?a=uw2YReL0LsI:jRcY8b6O0wk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?a=uw2YReL0LsI:jRcY8b6O0wk:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?i=uw2YReL0LsI:jRcY8b6O0wk:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://dhvik.blogspot.com/feeds/7362925671236316634/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://dhvik.blogspot.com/2008/10/clicking-winforms-button-from-code.html#comment-form" title="6 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6908201609754153877/posts/default/7362925671236316634" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6908201609754153877/posts/default/7362925671236316634" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DevelopingDotnetArchitect/~3/uw2YReL0LsI/clicking-winforms-button-from-code.html" title="Clicking a winforms button from code" /><author><name>Dan</name><uri>http://www.blogger.com/profile/14787263872119403136</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_BktCNuR9VXg/S_W8rNV-5hI/AAAAAAAABC0/BP4nWl1EXzc/S220/2009+-+Dan+H%C3%A4ndevik+80_80.jpg" /></author><thr:total>6</thr:total><feedburner:origLink>http://dhvik.blogspot.com/2008/10/clicking-winforms-button-from-code.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-6908201609754153877.post-8300924836014477363</id><published>2008-10-22T12:07:00.005+02:00</published><updated>2008-10-22T12:24:26.437+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Vista x64 .Net" /><title type="text">BadImageFormatException when loading Microsoft.TeamFoundation.Client.dll</title><content type="html">I tried to make a small winforms application on my 64bit Vista that talks with our TeamFoundationServer today. I use a plugin based application that loads the assemblies using Assembly.Load (utilizing the AppDomain.AssemblyResolve event).&lt;br /&gt;&lt;br /&gt;The problem surfaced when I tried to activate a function in one of my loaded plugins that used the TeamFoundation client dll, this was not located in the same folder as the exe.&lt;br /&gt;Using the AppDomain.CurrentDomain.AssemblyResolve event, I was easy to find the assembly dll and using Assembly.LoadFrom(filename) I could return the needed assembly.&lt;br /&gt;&lt;br /&gt;The problem was that when I tried to do this, I got a BadImageFormatException stating that&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Could not load file or assembly 'file:///C:\MyPath\MyProject\bin\Debug\Plugins\MyPlugin\Microsoft.TeamFoundation.Client.dll' or one of its dependencies. An attempt was made to load a program with an incorrect format.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;   at System.Reflection.Assembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Assembly locationHint, StackCrawlMark&amp;amp; stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;   at System.Reflection.Assembly.InternalLoad(AssemblyName assemblyRef, Evidence assemblySecurity, StackCrawlMark&amp;amp; stackMark, Boolean forIntrospection)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;   at System.Reflection.Assembly.LoadFrom(String assemblyFile)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;   at Meridium.Plugins.PluginLoader.CurrentDomain_AssemblyResolve(Object sender, ResolveEventArgs args) in C:\VSS\TFS\Meridium\Source\Meridium.Plugins\PluginLoader.cs:line 606&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This seemed not quite correct, since the assembly at the location is ok and can be opened for instance in Reflector.&lt;br /&gt;&lt;br /&gt;After a bit of searching I found more clues pointing to the fact that a 64bit application cannot load 32bit assemblies if they are in "Mixed mode" since they contain native code and thus are platform specific. The forum post &lt;a href="http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=665884&amp;amp;SiteID=1"&gt;http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=665884&amp;amp;SiteID=1&lt;/a&gt; stated the problem and provided the solution to set the project output to be built for the x86 platform.&lt;br /&gt;&lt;br /&gt;After changing the settings in the project, it worked like a charm.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6908201609754153877-8300924836014477363?l=dhvik.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?a=w63bdXafZ28:rmfR3Vuiqwo:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?a=w63bdXafZ28:rmfR3Vuiqwo:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?i=w63bdXafZ28:rmfR3Vuiqwo:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://dhvik.blogspot.com/feeds/8300924836014477363/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://dhvik.blogspot.com/2008/10/badimageformatexception-when-loading.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6908201609754153877/posts/default/8300924836014477363" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6908201609754153877/posts/default/8300924836014477363" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DevelopingDotnetArchitect/~3/w63bdXafZ28/badimageformatexception-when-loading.html" title="BadImageFormatException when loading Microsoft.TeamFoundation.Client.dll" /><author><name>Dan</name><uri>http://www.blogger.com/profile/14787263872119403136</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_BktCNuR9VXg/S_W8rNV-5hI/AAAAAAAABC0/BP4nWl1EXzc/S220/2009+-+Dan+H%C3%A4ndevik+80_80.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://dhvik.blogspot.com/2008/10/badimageformatexception-when-loading.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-6908201609754153877.post-9030877207448599649</id><published>2008-08-26T16:35:00.012+02:00</published><updated>2008-08-27T08:20:46.411+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Unittest" /><category scheme="http://www.blogger.com/atom/ns#" term="log4net" /><title type="text">Adding an appender to log4net in runtime</title><content type="html">I was testing logging with log4net today and wanted to create a unit test that verified that the method logged alright.&lt;br /&gt;To verify that the logging worked I wanted to create a log appender (the MemoryAppender) and add it to the log4net configuration to be able to compare the actual logged messages with the expected ones. (The MemoryAppender has the GetEvents() and Clear() methods which works well in a unit test case).&lt;br /&gt;&lt;br /&gt;Normally you use a configuration file (xml) to add your appenders but using configuration files in a unit test is not quite the optimal solution. So how could I set it in runtime in my test method. After a bit of testing and reading (I wonder why the testing and reading always seem to be in that order? (for me anyway) Shouldn't you start reading about the theory before you start coding and testing? ;)&lt;br /&gt;&lt;br /&gt;I found some tips using the Hierarchy class to access the root level logger and add append the MemoryAppender there.&lt;br /&gt;&lt;br /&gt;The important steps where to set the Configured property of the Hierarchy and call the RaiseConfigurationChanged() method to actually utilize the configuration changes.&lt;br /&gt;&lt;br /&gt;Here is a complete example.&lt;br /&gt;&lt;pre name="code" class="c-sharp:nocontrols:nogutter"&gt;//First create and configure the appender&lt;br /&gt;MemoryAppender memoryAppender = new MemoryAppender();&lt;br /&gt;memoryAppender.Name = "MyAppender";&lt;br /&gt;&lt;br /&gt;//Notify the appender on the configuration changes&lt;br /&gt;memoryAppender.ActivateOptions();&lt;br /&gt;&lt;br /&gt;//Get the logger repository hierarchy.&lt;br /&gt;log4net.Repository.Hierarchy.Hierarchy repository =&lt;br /&gt;   LogManager.GetRepository() as Hierarchy;&lt;br /&gt;&lt;br /&gt;//and add the appender to the root level&lt;br /&gt;//of the logging hierarchy&lt;br /&gt;repository.Root.AddAppender(memoryAppender);&lt;br /&gt;&lt;br /&gt;//configure the logging at the root.&lt;br /&gt;repository.Root.Level = Level.All;&lt;br /&gt;&lt;br /&gt;//mark repository as configured and&lt;br /&gt;//notify that is has changed.&lt;br /&gt;repository.Configured = true;&lt;br /&gt;repository.RaiseConfigurationChanged(EventArgs.Empty);&lt;/pre&gt;Now we have prepared the logging for the root (all log events) and directed it to the memoryAppender.&lt;br /&gt;&lt;pre name="code" class="c-sharp:nocontrols:nogutter"&gt;//Call the method to test (this one creates&lt;br /&gt;//an info level message to the log&lt;br /&gt;//stating the string "GetConfiguration()".&lt;br /&gt;ServerDataFactory.Instance.GetConfiguration();&lt;/pre&gt;When we have ran the code that has produced some logging, we add assert statements to check that the code behaved as we expected.&lt;br /&gt;&lt;pre name="code" class="c-sharp:nocontrols:nogutter"&gt;//use the memoryAppender to get the logged events&lt;br /&gt;LoggingEvent[] events = memoryAppender.GetEvents();&lt;br /&gt;&lt;br /&gt;//We only expect one log statement on the info level&lt;br /&gt;Assert.AreEqual(1, events.Length,&lt;br /&gt;   "Incorrect number of log statements");&lt;br /&gt;LoggingEvent e = events[0];&lt;br /&gt;Assert.AreEqual(Level.Info, e.Level,&lt;br /&gt;   "Incorrect logging level");&lt;br /&gt;Assert.AreEqual("GetConfiguration()", e.MessageObject,&lt;br /&gt;   "Incorrect log message");&lt;/pre&gt;Thats how I did it. Does anyone has another solution that works well?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6908201609754153877-9030877207448599649?l=dhvik.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?a=wfNuXSYxQ3M:_H-OHO_HzW8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?a=wfNuXSYxQ3M:_H-OHO_HzW8:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?i=wfNuXSYxQ3M:_H-OHO_HzW8:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://dhvik.blogspot.com/feeds/9030877207448599649/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://dhvik.blogspot.com/2008/08/adding-appender-to-log4net-in-runtime.html#comment-form" title="11 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6908201609754153877/posts/default/9030877207448599649" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6908201609754153877/posts/default/9030877207448599649" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DevelopingDotnetArchitect/~3/wfNuXSYxQ3M/adding-appender-to-log4net-in-runtime.html" title="Adding an appender to log4net in runtime" /><author><name>Dan</name><uri>http://www.blogger.com/profile/14787263872119403136</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_BktCNuR9VXg/S_W8rNV-5hI/AAAAAAAABC0/BP4nWl1EXzc/S220/2009+-+Dan+H%C3%A4ndevik+80_80.jpg" /></author><thr:total>11</thr:total><feedburner:origLink>http://dhvik.blogspot.com/2008/08/adding-appender-to-log4net-in-runtime.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-6908201609754153877.post-6256130887663238495</id><published>2008-02-28T13:50:00.005+01:00</published><updated>2008-02-28T14:01:39.677+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ClickOnce" /><category scheme="http://www.blogger.com/atom/ns#" term="SharePoint" /><title type="text">ClickOnce, SharePoint and Anonymous access</title><content type="html">I have been laborating with a ClickOnce deployed application in SharePoint and all seems to work well until I tried to connect to SharePoint (wss3) from a workstation where I used another locally logged in user than the one I used to authenticate myself at the SharePoint server.&lt;br /&gt;&lt;br /&gt;When I then tried to access the ClickOnce application the bootstrap downloader (ApplicationActivator) prompts a "Cannot Start Application" error that says "Cannot retrieve application. Authentication error".&lt;br /&gt;&lt;br /&gt;The details of the error indicates a 401 response from the webserver.&lt;br /&gt;&lt;pre&gt;System.Deployment.Application.DeploymentDownloadException (Unknown subtype)&lt;br /&gt;  - Downloading http://wm20031/_layouts/MyApp/MyApp.application did not succeed.&lt;br /&gt;  - Source: System.Deployment&lt;br /&gt;  - Stack trace:&lt;br /&gt;    at System.Deployment.Application.SystemNetDownloader.DownloadSingleFile(DownloadQueueItem next)&lt;br /&gt;    at System.Deployment.Application.SystemNetDownloader.DownloadAllFiles()&lt;br /&gt;    at System.Deployment.Application.FileDownloader.Download(SubscriptionState subState)&lt;br /&gt;    at System.Deployment.Application.DownloadManager.DownloadManifestAsRawFile(Uri&amp;amp; sourceUri, String targetPath, IDownloadNotification notification, DownloadOptions options, ServerInformation&amp;amp; serverInformation)&lt;br /&gt;    at System.Deployment.Application.DownloadManager.DownloadDeploymentManifestDirectBypass(SubscriptionStore subStore, Uri&amp;amp; sourceUri, TempFile&amp;amp; tempFile, SubscriptionState&amp;amp; subState, IDownloadNotification notification, DownloadOptions options, ServerInformation&amp;amp; serverInformation)&lt;br /&gt;    at System.Deployment.Application.DownloadManager.DownloadDeploymentManifestBypass(SubscriptionStore subStore, Uri&amp;amp; sourceUri, TempFile&amp;amp; tempFile, SubscriptionState&amp;amp; subState, IDownloadNotification notification, DownloadOptions options)&lt;br /&gt;    at System.Deployment.Application.ApplicationActivator.PerformDeploymentActivation(Uri activationUri, Boolean isShortcut, String textualSubId, String deploymentProviderUrlFromExtension)&lt;br /&gt;    at System.Deployment.Application.ApplicationActivator.ActivateDeploymentWorker(Object state)&lt;br /&gt;&lt;br /&gt;--- Inner Exception ---&lt;br /&gt;System.Net.WebException&lt;br /&gt;  - The remote server returned an error: (401) Unauthorized.&lt;br /&gt;  - Source: System&lt;br /&gt;  - Stack trace:&lt;br /&gt;    at System.Net.HttpWebRequest.GetResponse()&lt;br /&gt;    at System.Deployment.Application.SystemNetDownloader.DownloadSingleFile(DownloadQueueItem next)&lt;/pre&gt;&lt;p&gt;If I check the weblog we can se the following two entries &lt;/p&gt;&lt;pre&gt;2008-02-28 12:05:29 W3SVC1265274740 192.168.1.199 GET /_layouts/MyApp/MyApp.application 80 domain\administrator 192.168.1.2 Mozilla/4.0+(...) 206 0 0&lt;br /&gt;2008-02-28 12:05:29 W3SVC1265274740 192.168.1.199 GET /_layouts/MyApp/MyApp.application  80 - 192.168.1.2 - 401 5 0&lt;/pre&gt;The first is the webbrowser access where I authenticate using the domain\administrator account and the application manifest is successfully returned to the browser. Then the ApplicationActivator tries the same thing as anonymous but fails utterly. Ok, so perhaps this is only anonymous user access that is denied, but I had already checked the "Enable Anonymous access" in the IIS manager for the _layouts/MyApp folder.&lt;br /&gt;&lt;br /&gt;Testing with firefox and anonymous access proved that is not the access rights that is incorrectly set.&lt;br /&gt;&lt;pre&gt;2008-02-28 12:16:56 W3SVC1265274740 192.168.1.199 GET /_layouts/MyApp/MyApp.application 80 - 192.168.1.2 Mozilla/5.0+... 200 0 0&lt;/pre&gt;So the IIS is not blocking access, then it has to be SharePoint? (_layouts is a SharePoint managed folder)&lt;br /&gt;&lt;br /&gt;To test I checked the code for the System.Deployment.Application.SystemNetDownloader.DownloadSingleFile(DownloadQueueItem next) method and reproduced the code that was processed there.&lt;br /&gt;&lt;br /&gt;&lt;pre class="c-sharp:nocontrols:nogutter" name="code"&gt;WebRequest request = WebRequest.Create("http://wm20031/_layouts/MyApp/MyApp.application");&lt;br /&gt;request.Credentials = CredentialCache.DefaultCredentials;&lt;br /&gt;RequestCachePolicy policy = new RequestCachePolicy(RequestCacheLevel.BypassCache);&lt;br /&gt;request.CachePolicy = policy;&lt;br /&gt;HttpWebRequest request2 = request as HttpWebRequest;&lt;br /&gt;if (request2 != null) {&lt;br /&gt;  request2.UnsafeAuthenticatedConnectionSharing = true;&lt;br /&gt;  request2.AutomaticDecompression = DecompressionMethods.GZip;&lt;br /&gt;  request2.CookieContainer = GetUriCookieContainer(request2.RequestUri);&lt;br /&gt;  WebRequest.DefaultWebProxy.Credentials = CredentialCache.DefaultCredentials;&lt;br /&gt;}&lt;br /&gt;WebResponse response = null;&lt;br /&gt;response = request.GetResponse();&lt;br /&gt;using (StreamReader reader = new StreamReader(response.GetResponseStream())) {&lt;br /&gt;  Console.WriteLine(reader.ReadToEnd());&lt;br /&gt;}&lt;br /&gt;response.Close();&lt;/pre&gt;This code fails with the same exception as the Application Activator and after some debugging I noticed that if I didn't copy the cookies to the request, then it worked?!&lt;br /&gt;Checking further in the cookie container, it only added one cookie &lt;tt&gt;MSOWebPartPage_AnonymousAccessCookie&lt;/tt&gt; and with the value of the webapplication port. (80)&lt;br /&gt;&lt;br /&gt;The GetUriCookieContainer parsed the cookies retrieved in IE for the url. If I removed the cookie for the server in the temporary internet files folder, the code above worked even with the cookie row (no cookies added).&lt;br /&gt;&lt;br /&gt;To solve the problem one workaround is to create a virtual folder in the root of the SharePoint site (MyApp) (that is not managed by SharePoint), map this to the same folder as _layouts/MyApp, allow anonymous access there and navigate to that url instead (/MyApp/MyApp.application). This works since the cookie is not present for the application.&lt;br /&gt;&lt;br /&gt;But what I really like to know is the purpose of the &lt;strong&gt;MSOWebPartPage_AnonymousAccessCookie&lt;/strong&gt;, especially why SharePoint sets this cookie when I navigate to the site and why it throws an access denied when I try to access with the cookie set?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6908201609754153877-6256130887663238495?l=dhvik.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?a=SYXSTRn-1b0:UvfEHBdaHp4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?a=SYXSTRn-1b0:UvfEHBdaHp4:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?i=SYXSTRn-1b0:UvfEHBdaHp4:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://dhvik.blogspot.com/feeds/6256130887663238495/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://dhvik.blogspot.com/2008/02/clickonce-sharepoint-and-anonymous.html#comment-form" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6908201609754153877/posts/default/6256130887663238495" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6908201609754153877/posts/default/6256130887663238495" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DevelopingDotnetArchitect/~3/SYXSTRn-1b0/clickonce-sharepoint-and-anonymous.html" title="ClickOnce, SharePoint and Anonymous access" /><author><name>Dan</name><uri>http://www.blogger.com/profile/14787263872119403136</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_BktCNuR9VXg/S_W8rNV-5hI/AAAAAAAABC0/BP4nWl1EXzc/S220/2009+-+Dan+H%C3%A4ndevik+80_80.jpg" /></author><thr:total>4</thr:total><feedburner:origLink>http://dhvik.blogspot.com/2008/02/clickonce-sharepoint-and-anonymous.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-6908201609754153877.post-5112114397826610577</id><published>2007-11-26T15:10:00.001+01:00</published><updated>2007-11-26T15:12:59.740+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Visual Studio" /><title type="text">Task failed because "sgen.exe" was not found</title><content type="html">I installed Visual Studio 2008 (final) and started to create a WinForms (2.0) application that calls a webservice and is deployed with clickonce. When I try to compile it (after adding the webreference) I get the following build error&lt;br /&gt;&lt;span style="font-family:Courier;"&gt;&lt;br /&gt;C:\WINDOWS\Microsoft.NET\Framework\v3.5\Microsoft.Common.targets(1993,9):&lt;br /&gt;error MSB3091:&lt;br /&gt;Task failed because "sgen.exe" was not found, or the correct Microsoft Windows SDK is not installed. The task is looking for "sgen.exe" in the "bin" subdirectory beneath the location specified in the InstallationFolder value of the registry key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v6.0A. You may be able to solve the problem by doing one of the following:&lt;br /&gt; 1) Install the Microsoft Windows SDK for Windows Server 2008 and .NET Framework 3.5.&lt;br /&gt; 2) Install Visual Studio 2008.&lt;br /&gt; 3) Manually set the above registry key to the correct location.&lt;br /&gt; 4) Pass the correct location into the "ToolPath" parameter of the task.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I thought that the SDK was to be installed with VisualStudio 2008, but when looking into the SDKs folder (C:\Program Files\Microsoft Visual Studio 9.0\SDK) it contains almost nothing, only a few files in the v3.5 folder.&lt;br /&gt;&lt;br /&gt;When I searched for the SDK for framework 3.5 it seems that is included in the windows server 2008 platform sdk and that is only avaliable for beta2 so far...&lt;br /&gt;&lt;br /&gt;Regarding the registry settings, I have the SDK for v2.0 installed and since I build vs the 2.0 framework, shouldn't it look in the &lt;span style="font-family:Courier;"&gt;KEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v2.0&lt;span style="font-family:Arial;"&gt; key?&lt;br /&gt;&lt;br /&gt;How do I set the ToolPath?&lt;br /&gt;&lt;br /&gt;Anyway, I came around the issue by setting the &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier;"&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v6.0A&lt;span style="font-family:Arial;"&gt; InstallationFolder key to the same path as the 2.0 Sdk path and compilation was successful...&lt;br /&gt;&lt;br /&gt;Is the VisualStudio 2008 release not final since it seems to miss the SDK or have I been sloppy installing the product?&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6908201609754153877-5112114397826610577?l=dhvik.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?a=8oSDBDiqPac:khVGzv42uDE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?a=8oSDBDiqPac:khVGzv42uDE:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?i=8oSDBDiqPac:khVGzv42uDE:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://dhvik.blogspot.com/feeds/5112114397826610577/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://dhvik.blogspot.com/2007/11/task-failed-because-was-not-found.html#comment-form" title="10 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6908201609754153877/posts/default/5112114397826610577" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6908201609754153877/posts/default/5112114397826610577" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DevelopingDotnetArchitect/~3/8oSDBDiqPac/task-failed-because-was-not-found.html" title="Task failed because &amp;quot;sgen.exe&amp;quot; was not found" /><author><name>Dan</name><uri>http://www.blogger.com/profile/14787263872119403136</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_BktCNuR9VXg/S_W8rNV-5hI/AAAAAAAABC0/BP4nWl1EXzc/S220/2009+-+Dan+H%C3%A4ndevik+80_80.jpg" /></author><thr:total>10</thr:total><feedburner:origLink>http://dhvik.blogspot.com/2007/11/task-failed-because-was-not-found.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-6908201609754153877.post-6200140454739453986</id><published>2007-11-26T12:03:00.001+01:00</published><updated>2007-11-26T12:09:13.147+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ClickOnce" /><category scheme="http://www.blogger.com/atom/ns#" term="Visual Studio" /><title type="text">Signing a ClickOnce manifest file using a spc/pvk certificate</title><content type="html">&lt;p&gt;To sign a ClickOnce manifest file/assembly you need a pfx file without chaining information.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;First we need to convert the spc/pvk file to a pfx file. As &lt;a href="http://processbridge.spaces.live.com/blog/cns%21674C1260C39F1DB8%21116.entry?&amp;amp;_c02_owner=1"&gt;Stuart found out&lt;/a&gt; you use the &lt;a href="http://msdn2.microsoft.com/en-us/library/aa906332.aspx"&gt;pvk2pfx tool&lt;/a&gt; to accomplish this.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;If we try to use this certificate and it contains chaining information we will get an error stating&lt;br /&gt;&lt;/p&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: Courier;"&gt;"Cannot find the certificate and private key for decryption"&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;Then we need to make sure that the pfx don't include the chaining information as described in &lt;a href="https://support.comodo.com/index.php?_m=knowledgebase&amp;amp;_a=viewarticle&amp;amp;kbarticleid=1078"&gt;the case @ commodo&lt;/a&gt; (importing and exporting the pfx).&lt;br /&gt;&lt;/p&gt;&lt;p&gt;When these steps has been completed, you can build and sign your application.&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6908201609754153877-6200140454739453986?l=dhvik.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?a=FXaBV4mOg6M:fPGl28l2XBg:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?a=FXaBV4mOg6M:fPGl28l2XBg:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DevelopingDotnetArchitect?i=FXaBV4mOg6M:fPGl28l2XBg:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://dhvik.blogspot.com/feeds/6200140454739453986/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://dhvik.blogspot.com/2007/11/signing-clickonce-manifest-file-using.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6908201609754153877/posts/default/6200140454739453986" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6908201609754153877/posts/default/6200140454739453986" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DevelopingDotnetArchitect/~3/FXaBV4mOg6M/signing-clickonce-manifest-file-using.html" title="Signing a ClickOnce manifest file using a spc/pvk certificate" /><author><name>Dan</name><uri>http://www.blogger.com/profile/14787263872119403136</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_BktCNuR9VXg/S_W8rNV-5hI/AAAAAAAABC0/BP4nWl1EXzc/S220/2009+-+Dan+H%C3%A4ndevik+80_80.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://dhvik.blogspot.com/2007/11/signing-clickonce-manifest-file-using.html</feedburner:origLink></entry></feed>

