Wednesday, April 10, 2013
MEF 101
WCF Service --> Library with Interface / Base classes etc <-- Client extensions library implementing interfaces, and extending base classes
However I didn't want the WCF service to have a reference to all of the client extension assemblies and use Unity for example to resolve the concrete dependency at runtime through config - this will grow over time so won't scale, and is clumsy. Its worth pointing out that Unity won't load the assembly into the AppDomain by it's self - so another mechanism is needed (eg. project reference)
Never used MEF before, but it's perfect for this scenario - dynamic application composition.
Continuing with the WCF service example, I create a property which is the dependency I want to 'import' - below example is a logger dependency, where the ILogger interface is defined in the base library (i.e. what the WCF service is referencing), I have also decorated the property with the MEF Import attribute:
[Import(typeof(ILogger))]
public ILogger Logger { get; set; }
A customer wants to log in a particular way, so we'll create a specific implementation by implementing the ILogger interface in a customer specific assembly. This class has been decorated with the MEF Export attribute - which indicates it available as a composable part:
Export(typeof(ILogger))]
public class FlatFileLogger : ILogger
The next step is to build up the type with the dependencies / needs to composed using parts (i.e. needs to 'import' an implementation of ILogger). To do this you need to use the CompositionContainer, AggregateCatalog and the ComposablePartCatalog types. In my example, I just wanted to drop an assembly in a specified folder, and MEF would pick it when attempting to compose, so the DirectoryCatalog is the catalog type (there are others) that will allow me to do this.
new DirectoryCatalog("bin")
In the above snippet, I've created a Directory Catalog where MEF will evaluate all the assemblies in the bin folder - relative to the root folder of the AppDomain. Next I need to add this catalog instance to the AggregateCatalog, and then add the AggregateCatalog to the CompositionContainer.
var aggregationCatalog = new AggregateCatalog();
var compositionContainer = new CompositionContainer(aggregationCatalog);
So, assuming I've copied the customer extension assembly into the bin folder (i.e. the FlatFileLogger), I can then compose the parts for my instance the needs to be built up - so in the below example, instance that is passed into ComposeParts, is an instance of my type that needs to be composed with a ILogger (decorated with the Import attribute). Using the configured catalogs, MEF will then try and compose the instance. So since in this example a DirectoryCatalog is used (for the bin folder) - MEF will evaluate all the assemblies in that folder to determine if there are any types that are defined as being a composable part (i.e. decorated with Export). If so, MEF will instantiate the part - e.g. the Logger property will be instantiated as a FlatFileLogger.
compositionContainer.ComposeParts(instance);
Saturday, March 2, 2013
WebRequest.GetResponse causes the application to hang
Recently I built an application which required the use of the WebRequest type. When calling GetResponse to retrieve the response stream all was working fine. By mistake, I incorrectly created the application targetting .Net 4.0 - so I changed the target framework to 3.5 and all was not working fine. When GetResponse was called, the application hung, and looking through Fiddler no request was actually made to the http server.
After some googling, I found this is a common scenario where GetResponse hangs when not targetting .Net 4.0. Solutions I found to this issue varied, however the one that worked for me was looking at the MSDN example for using the WebRequest type and comparing line by line to how I was using WebRequest.
Turns out, the only difference was I wasn't specifying the Content-Length http header:
webRequest.ContentLength = byteArray.Length;
Once the above was included when setting up the WebRequest - GetResponse no longer hanged when targetting 3.5 (and continues to work fine when targetting 4.0).
The 4.0 WebRequest version is obviously more forgiving and allows you not to specify the Content-Length (and I'm assuming calculates automatically).
Monday, January 21, 2013
Cryptography_CSP_NoPrivateKey
I've been working with a application which is a WSE 2.0 client - which involves signing the message.
When attempting to send the request - an exception of type System.Security.Cryptography.CryptographicException is thrown, where the message is Cryptography_CSP_NoPrivateKey.
This is permissions issue - where the identity of the AppPool (the application I had the issue with was a web service), does not have the required permissions to access the private key of the certificate.
Management of the permissions can be done through the MMC Certificates snap-in - right click on the certificate, select All Tasks, then Manage private keys.
Tuesday, December 11, 2012
Svcutil and xsd imports
When wanting to generate a client proxy through svcutil, I always forget the exact syntax when I have a WSDL with xsd imports - i.e. when you get the syntax wrong (or don't have the xsd's included in the command line at all) you'll no doubt get the following errors:
Error: Schema with target namespace 'http://namespace/v1' could not be found.
Error: Cannot import wsdl:portType.
etc...
The basic command line syntax is svcutil [location of wsdl] [location of xsds] - where if there are multple xsds, then the locations are seperated by a space, e.g:
svcutil C:\MyWsdl.wsdl C:\Folder1\Xsd1.xsd C:\Folder2\Xsd2.xsd
A lot of the wsdls I build share xsds, which are in different locations, however some share the same location - but I just need to specify the location and then specify a wildcard *.xsd, which will result in all xsd files in the folder being picked up by svcutil - e.g.
svcutil C:\MyWsdl.wsdl C:\Folder1\*.xsd C:\Folder2\*.xsd
Friday, October 12, 2012
405 Method Not Allowed on PUT and DELETE verbs
PUT and DELETE requests to a MVC 4 Web Api application we released to a customer server were failing with a 405 status code - Method Not Allowed.
After some investigation on the web, the WebDAV module was the cause - this thread on the IIS forum has a good overview of why it occurs (PUT and DELETE are considered WebDAV verbs) and how to uninstall the feature.
Tuesday, June 19, 2012
ASP.Net Web API and Exception Shielding
Exception shielding (or exception sanitation) is a integration pattern that should always be implemented to ensure unexpected exceptions never arrive at the client (a.k.a bleed through).
For MVC 4's Web Api - this is achieved by overriding the OnException method, on the ExceptionFilterAttribute class. Here you can inspect the exception that was thrown, and sanitise if required (change the exception to be more generic).
However, the mechanism to return http status codes - e.g. 404 - when a resource is not found, is to throw an HttpResponsException with the appropriate status code. This ensures that RESTful semantics are upheld.
During development, I updated the OnException method to ignore exceptions of type HttpResponsException, as these are intended to reach the client. However the method was never invoked. After some googling, I discovered the filter is smart enough to know that HttpResponseExceptions should be ignored - "An exception filter is executed when a controller method throws any unhandled exception that is not an HttpResponseException exception. TheHttpResponseException type is a special case, because it is designed specifically for returning an HTTP response."
Monday, April 30, 2012
Fiddler & redirecting local traffic
Because I always forget the rule for redirecting requests that Fiddler receives while listening on port 8888 here it is below:
static function OnBeforeRequest(oSession: Session) {
//other statements
if (oSession.host == "localhost:8888") { oSession.host = "localhost:80" }
}
... where you can change localhost:80 to where the request needs to be redirected to