Notes from Daily Encounters with Technology RSS 2.0
 
# Monday, December 12, 2011

WCF has great built-in support for most types of authentication so there aren’t many good reasons to use HTTP module based authentication with it. Having an existing ASP.NET application already using such authentication certainly is one of them. Finding resources on how to do it might be a challenge though. I managed to stumble upon an article by Microsoft patterns & practices team which helped a lot. In a way this post is its abridged and more practical version.

From here on I assume you already have an IHttpModule in your application (ProcessAuthentication() being the method implementing the actual authentication of the user):

public class HttpAuthenticationModule : IHttpModule
{
    public void Dispose()
    { }

    public void Init(HttpApplication context)
    {
        context.AuthenticateRequest += context_AuthenticateRequest;
    }

    void context_AuthenticateRequest(object sender, EventArgs e)
    {
        HttpContext.Current.User = ProcessAuthentication();
    }

    private static IPrincipal ProcessAuthentication()
    {
        // implement your authentication here
        IIdentity identity = new GenericIdentity("Authenticated User");
        return new GenericPrincipal(identity), null);
    }
}

The module should also already be registered in web.config:

<system.web>
    <!-- ... -->
    <httpModules>
        <add name="HttpAuthenticationModule" 
             type="WcfAuthentication.HttpAuthenticationModule"/>
    </httpModules>
</system.web>

The goal is of course getting access to the authenticated user (i.e. IPrincipal instance) in WCF service through ServiceSecurityContext. The following test method is a great way for testing that:
public string GetUser()
{
    if (ServiceSecurityContext.Current != null)
        return ServiceSecurityContext.Current.PrimaryIdentity.Name;
    else
        return null;
}

IAuthorizationPolicy is the interface to implement custom authorization in WCF with. In our case the authenticated user can be accessed through current HttpContext:

public class HttpContextAuthorizationPolicy : IAuthorizationPolicy
{
    public bool Evaluate(EvaluationContext evaluationContext, ref object state)
    {
        HttpContext context = HttpContext.Current;

        if (context != null)
        {
            evaluationContext.Properties["Principal"] = context.User;
            evaluationContext.Properties["Identities"] = new List<IIdentity>() { context.User.Identity };
        }

        return true;
    }

    public System.IdentityModel.Claims.ClaimSet Issuer
    {
        get { return ClaimSet.System; }
    }

    public string Id
    {
        get { return "HttpContextAuthorizationPolicy"; }
    }
}

Of course the class should be registered in web.config so that our service will use it:

<system.serviceModel>
    <!-- ... -->
    <behaviors>
        <serviceBehaviors>
            <behavior>
                <!-- ... -->
                <serviceAuthorization>
                    <authorizationPolicies>
                        <add policyType="
                             WcfAuthentication.HttpContextAuthorizationPolicy, 
                             WcfAuthentication, Version=1.0.0.0, 
                             Culture=neutral, PublicKeyToken=null"/>
                    </authorizationPolicies>
                </serviceAuthorization>
            </behavior>
        </serviceBehaviors>
    </behaviors>
</system.serviceModel>

There is still one thing missing. If you try out the above code, you will realize that HttpContext.Current is always null even if authorization in our HTTP module was successful. To get access to it you need to enable ASP.NET compatibility:

<system.serviceModel>
    <!-- ... -->
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" 
                               aspNetCompatibilityEnabled="true"/>
</system.serviceModel>

To make your WCF service work in this mode you need decorate it with AspNetCompatibilityRequirementsAttribute:

[AspNetCompatibilityRequirements(RequirementsMode = 
    AspNetCompatibilityRequirementsMode.Allowed)]
public class Service : IService
{
    // ...
}

Finally, we’re done. If you’ve implemented all of the above correctly, our test method GetUser() should return the user who was authenticated in the HTTP module. Unless you’re trying to use Windows authentication which still doesn’t work in this setup. That’s already a subject for another post, though.

Monday, December 12, 2011 9:29:48 PM (Central European Standard Time, UTC+01:00)  #    Comments [0] - Trackback
Development | .NET | ASP.NET | WCF
# Thursday, December 01, 2011

DefaultModelBinder is an essential piece of ASP.NET MVC framework which makes writing strongly typed actions really simple. In spite of its strengths (or maybe because of them) it can still introduce hard to solve problems in your code. Take a look at the following example, a simplification of the problem I was confronted with today:

public class DocumentVersion
{
    public int Id { get; set; }
    public int Version { get; set; }
    public string Name { get; set; }
}

public class DocumentController : Controller
{
    public ActionResult New()
    {
        return View();
    }

    public ActionResult Save(DocumentVersion version)
    {
        if (ModelState.IsValid)
        {
            // save data
            return View("Confirm");
        }
        return View("New");
    }
}

Assuming all DocumentVersion properties are submitted and valid Save action should return Confirm view, right? Wrong! Try it out and you’ll get a validation error on Version property. Taking a closer look it turns out ModelState["Version"].Errors[0].Exception contains an InvalidOperationException: "The parameter conversion from type 'System.String' to type 'MvcApplication1.Models.DocumentVersion' failed because no type converter can convert between these types." Of course there’s no String to DocumentVersion converter. Though, Version property is an int. Why does it want to convert it to a DocumentVersion?

I soon started running out of ideas and fortunately enough I quickly decided to enable .NET Framework source stepping. A few moments later I reached the following piece of code in DefaultModelBinder and suddenly it became obvious what was happening:

if (!String.IsNullOrEmpty(bindingContext.ModelName)
        && !bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName)) {
    // We couldn't find any entry that began with the prefix. If this is the top-level element, fall back
    // to the empty prefix.
    if (bindingContext.FallbackToEmptyPrefix) { 
        bindingContext = new ModelBindingContext() {
            ModelMetadata = bindingContext.ModelMetadata, 
            ModelState = bindingContext.ModelState, 
            PropertyFilter = bindingContext.PropertyFilter,
            ValueProvider = bindingContext.ValueProvider 
        };
        performedFallback = true;
    }
    else { 
        return null;
    } 
} 

// Simple model = int, string, etc.; determined by calling TypeConverter.CanConvertFrom(typeof(string)) 
// or by seeing if a value in the request exactly matches the name of the model we're binding.
// Complex type = everything else.
if (!performedFallback) {
    bool performRequestValidation = ShouldPerformRequestValidation(controllerContext, bindingContext); 
    ValueProviderResult vpResult = 
        bindingContext.UnvalidatedValueProvider
                      .GetValue(bindingContext.ModelName, skipValidation: !performRequestValidation);
    if (vpResult != null) { 
        return BindSimpleModel(controllerContext, bindingContext, vpResult); 
    }
} 

Notice the call to bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName) at the top and read the comment above the bottom block of the code. It turns out that in my sample ModelName Was "version" just like one of the DocumentVersion properties therefore DefaultModelBinder decided to use simple model binding which failed because of a missing converter as it was also clearly stated in the exception. You might be wondering where ModelName came from. It’s the name of the action method parameter. Fixing the code was simple now – rename the parameter and the code starts working as expected:

public ActionResult Save(DocumentVersion documentVersion)
{
    if (ModelState.IsValid)
    {
        // save data
        return View("Confirm");
    }
    return View("New");
}

Lesson of the day? Be aware of conventions and make sure parameter names don’t match any of the property names if you are using complex models.

Thursday, December 01, 2011 9:42:37 PM (Central European Standard Time, UTC+01:00)  #    Comments [0] - Trackback
Development | ASP.NET MVC
# Sunday, October 02, 2011

This year’s Bleeding Edge conference was taking place this week in the beautiful surroundings of Gozd Martuljek. The second day was dedicated to community driven redelivery of Build. As the last session of the day I had a talk on the aspects of reusing existing .NET framework code in Metro applications for Windows 8. I’ve based the contents of the talk on the following Build sessions:

The slides from my talk are available on SlideShare. Here are the sources for the sample Windows runtime component I've created during the talk.


Sunday, October 02, 2011 8:34:40 PM (Central European Daylight Time, UTC+02:00)  #    Comments [0] - Trackback
Development | .NET | Metro | Downloads | Presentations | Sources
# Sunday, July 24, 2011

Reflection is a great tool for calling methods on objects when their types are not known at compile time. Unfortunately the Type.GetMethod method doesn’t work with generic methods therefore we seem to be stuck with finding the right method by iterating through all the methods returned by Type.GetMethods:

public static MethodInfo GetMethodWithLinq(this Type staticType, string methodName, params Type[] paramTypes)
{
    var methods = from method in staticType.GetMethods()
                  where method.Name == methodName
                        && method.GetParameters()
                                  .Select(parameter => parameter.ParameterType)
                                  .Select(type => type.IsGenericType ? type.GetGenericTypeDefinition() : type)
                                  .SequenceEqual(paramTypes)
                  select method;
    try
    {
        return methods.SingleOrDefault();
    }
    catch (InvalidOperationException)
    {
        throw new AmbiguousMatchException();
    }
}

Searching for alternatives I stumbled upon a solution using expression trees posted by Neil Whitaker on StackOverflow:

private static MethodInfo GetMethodWithExpressions(Type innerType)
{
    var method = typeof(Program).GetMethod("GetSingleOrDefaultMethod", 
                                           BindingFlags.Static | BindingFlags.NonPublic, 
                                           null, Type.EmptyTypes, null)
                                .MakeGenericMethod(innerType);
    return method.Invoke(null, new object[] { }) as MethodInfo;
}

private static MethodInfo GetSingleOrDefaultMethod<TSource>()
{
    Expression<Func<TSource, bool>> fakePredicate = i => true;
    Expression<Func<IQueryable<TSource>, TSource>> lambda = l => l.SingleOrDefault(fakePredicate);

    return (lambda.Body as MethodCallExpression).Method;
}

Sure, it is more difficult to comprehend and a lot less flexible, requiring a helper method building the expression tree for every method to be returned as MethodInfo. It got me wondering though, which of the two solutions actually performs better. Let’s try them out:

static void Main(string[] args)
{
    MethodInfo method;
    Type innerType = typeof(string);

    int count = 10000;
    Stopwatch stopwatch = new Stopwatch();

    stopwatch.Restart();
    for (int i = 0; i < count; i++)
    {
        method = typeof(Queryable).GetMethodWithLinq("SingleOrDefault", typeof(IQueryable<>), typeof(Expression<>))
                                  .MakeGenericMethod(innerType);
    }
    stopwatch.Stop();
    Console.WriteLine(String.Format("Method 1: {0}", stopwatch.ElapsedMilliseconds));

    stopwatch.Restart();
    for (int i = 0; i < count; i++)
    {
        method = GetMethodWithExpressions(innerType);
    }
    stopwatch.Stop();
    Console.WriteLine(String.Format("Method 2: {0}", stopwatch.ElapsedMilliseconds));

    Console.ReadLine();
}

And the results?

Method 1: 224
Method 2: 396

Not only is the Type.GetMethods based approach simpler, it also consistently performs a lot better. We’ll just stick with it until support for generic methods is added to Type.GetMethod.

Sunday, July 24, 2011 10:31:43 AM (Central European Daylight Time, UTC+02:00)  #    Comments [0] - Trackback
Development | .NET | C#
# Sunday, June 12, 2011

XmlSerializer is often a great choice for persisting objects or transmitting them over the wire, either by using default object serialization tailored only with attributes or by implementing the IXmlSerializable interface yourself. If you’re not careful though, this might come at a significant performance cost.

You’re probably already aware that in order to increase performance of XML serialization, assemblies are dynamically generated each time XmlSerializer is instantiated for the first time for a specific type. Since it happens only once in the application lifetime, it usually doesn’t pose much of a problem.

What you might not know, is that this is not necessary a once in a lifetime process. If you’re using the wrong constructor, it can happen every time you instantiate XmlSerializer. To be fair, this is mentioned in the documentation, but if you’re like me, you might not read it until you encounter performance issues in your project. So unless you’re calling XmlSerializer(Type) or XmlSerializer(Type, String), the dynamically generated assemblies are not reused. When you think about it, it also makes perfect sense. All other constructors modify the behavior of the serializer, thus causing small differences in the generated serializers and hindering their reuse.

Fortunately there is a way to avoid this performance hit. Since XmlSerializer is one of the few thread safe classes in the framework you really only need a single instance of each serializer even in a multithreaded application. The only thing left for you to do, is to devise a way to always retrieve the same instance. If you know in advance which serializers you’ll need, you can simply store them in static fields. If you don’t, you’ll need to store them in a dictionary, keyed by the arguments used in the constructor.

Your best choice for the data structure is ConcurrentDictionary introduced in .NET 4 which takes care of synchronizing for multithreading. This makes the implementation really simple:

private static ConcurrentDictionary<Type, XmlSerializer> serializers = 
    new ConcurrentDictionary<Type, XmlSerializer>();

private XmlSerializer GetSerializer(Type type)
{
    return serializers.GetOrAdd(type, t => 
        { return new XmlSerializer(t, new XmlRootAttribute("Value")); });
}

If you’re wondering what kind of performance hit I’m talking about, try running the following sample:

static void Main(string[] args)
{
    StringWriter writer = new StringWriter();
    XmlTextWriter xmlWriter = new XmlTextWriter(writer);
    xmlWriter.WriteStartDocument();
    xmlWriter.WriteStartElement("Root");
    Stopwatch stopwatch = new Stopwatch();
    int iterations = 100;

    stopwatch.Restart();
    for (int i = 0; i < iterations; i++)
    {
        XmlSerializer serializer = new XmlSerializer(typeof(string));
        serializer.Serialize(xmlWriter, "Test");
    }
    stopwatch.Stop();
    Console.WriteLine(
        "{0} serializations with XmlSerializer(string):                   {1,5} ms",
        iterations, stopwatch.ElapsedMilliseconds);

    stopwatch.Restart();
    for (int i = 0; i < iterations; i++)
    {
        XmlSerializer serializer = new XmlSerializer(typeof(string), new XmlRootAttribute("Type"));
        serializer.Serialize(xmlWriter, "Test");
    }
    stopwatch.Stop();
    Console.WriteLine(
        "{0} serializations with XmlSerializer(string, XmlRootAttribute): {1,5} ms",
        iterations, stopwatch.ElapsedMilliseconds);

    XmlSerializer staticSerializer = new XmlSerializer(typeof(string), new XmlRootAttribute("Type"));
    stopwatch.Restart();
    for (int i = 0; i < iterations; i++)
    {
        staticSerializer.Serialize(xmlWriter, "Test");
    }
    stopwatch.Stop();
    Console.WriteLine(
        "{0} serializations with a static serializer:                     {1,5} ms",
        iterations, stopwatch.ElapsedMilliseconds);

    Console.ReadKey();
}

In my case the output was as follows:

100 serializations with XmlSerializer(string):                       2 ms
100 serializations with XmlSerializer(string, XmlRootAttribute): 17460 ms
100 serializations with a static serializer:                         2 ms

Quite a difference, isn’t it?

Sunday, June 12, 2011 4:55:48 PM (Central European Daylight Time, UTC+02:00)  #    Comments [0] - Trackback
Development | .NET
Sponsored Ads

About Me
Twitter
@MladenPrajdic @andrejt use the middle mouse button then 1 day ago
@matevzg @MladenPrajdic Ctrl+F4, as well 1 day ago
Great #DotNetRocks show: Troy Hunt Secures http://t.co/oxClbXLe http://t.co/MiMasNuZ PDF is worth checking out as well http://t.co/z4BHAzqh 3 days ago
Hazards of Converting Binary Data To A String http://t.co/lb8kRSsU via @haacked 5 days ago
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

All Content © 2012, Damir Arh, M. Sc. Send mail to the author(s) - Privacy Policy - Sign In
Based on DasBlog theme 'Business' created by Christoph De Baene (delarou)
Social Network Icon Pack by Komodo Media, Rogie King is licensed under a Creative Commons Attribution-Share Alike 3.0 Unported License.