Archives

Archives / 2008 / July
  • Open a WPF Window from WinForms

    If you find yourself in need to open a WPF Window from a WinForms program - this is one way to do it (works for me):

    1) Create/Add a new project of type "WPF Custom Control Library"

    image

    2) Add a new Item of type "Window (WPF)"

    image

    3) Do your thing with the WPF Window

    4) From your WinForms app, create and open the WPF Window:

    using System;
    using System.Windows.Forms;
    using System.Windows.Forms.Integration;
    var wpfwindow = new WPFWindow.Window1();
    ElementHost.EnableModelessKeyboardInterop(wpfwindow);
    wpfwindow.Show();

    There you go!

    The EnableModelessKeyboardInterop() call is necessary to handle keyboard input in the WPF window if loaded from a non-WPF host like WinForms. I understand there are other ways to do this and you can read more about WPF/WinForms interop here.

  • IronRuby with ASP.NET MVC

    MVCIronRuby Now that ASP.NET MVC preview 4 is out, Phil Haack did as promised and made available a working prototype of IronRuby + ASP.NET MVC integration. He wrote:

    Now that Preview 4 is out, I revisited the prototype and got it working again. I use the term working loosely here. Yeah, it works, but it is really rough around the edges.

    To be able to use Ruby with ASP.NET MVC there has to be some c# glue/bridge code, especially in global.asax, which loads the routing tables (via extensions) and points at a specially made Ruby Controller Factory:

    protected void Application_Start(object sender, EventArgs e)
    {
        RouteTable.Routes.LoadFromRuby();
        ControllerBuilder.Current.SetControllerFactory(new RubyControllerFactory());
    }

    That glue code is placed in a c# library called IronRubyMvcLibrary, which also contains support for .rhtml view pages. The objects you need to use from within the view page is accessible through Ruby global variables - $model, $response, $html and so on.

    As John and Phil points out, this is a prototype and a test to try out a few things with IronRuby and MVC, and I think it's cool. Much will change over time, like how they use instance variables on the controller to pass data to the view.

    This is a step towards something which may become quite popular in the Ruby community, and perhaps to Rails people who has to, or wants to, write web apps on the .NET platform in the future. For those that hasn't been looking at IronRuby yet and want to have some fun with this - note that you don't have any intellisense or anything lika that in Visual Studio yet.

  • Fetching User Details from OpenId via Attribute Exchange

    CropperCapture[4]Rob Conery did another excellent episode of his MVC Storefront series the other day where he ripped out his user membership code and replaced it with OpenId.

    Implementing the whole OpenId protocol yourself isn't necessary as there are some great libraries for you out there which makes it really, really simple to use and integrate with both WebFoms and A SP.NET MVC. Rob uses the DotNetOpenId library to authenticate the user but didn't show how to fetch user details like the user full name.

    Well, this is possible using Attribute Exchange which is a way of transferring information about the user between the OpenID provider and relying party. The DotNetOpenId library supports this too, and it just requires a small change to the DotNetOpenId code samples I've seen out there.

    First, most people redirect to the provider like this:

    openid.CreateRequest(id).RedirectToProvider();

    But instead, create the request manually and add extension requests to fetch user information (like the name for example) to it before redirecting:

    var openidRequest = openid.CreateRequest(id);
    var fetch = new FetchRequest();
    fetch.AddAttribute(new AttributeRequest("http://schema.openid.net/namePerson"));
    openidRequest.AddExtension(fetch);
    
    openidRequest.RedirectToProvider();

    Just keep on adding the attributes you're interested in, like email, website etc. Remeber to inform your user about you wanting to fetch the extra information before doing the authentication.

    After a successful OpenId authentication the provider redirects back to your site and you normally authenticate and redirect like this:

    switch (openid.Response.Status)
    {
        case AuthenticationStatus.Authenticated:
            FormsAuthentication.RedirectFromLoginPage(openid.Response.ClaimedIdentifier, false);
    //...snip...

    Now, before the redirect statement, you have the chance to fetch out the attributes you asked for from the OpenId response, like this for example:

    switch (openid.Response.Status)
    {
        case AuthenticationStatus.Authenticated:
            var fetch = openid.Response.GetExtension<FetchResponse>();
            if (fetch != null)
            {
                //assuming we got data back from the provider - add sanity check to this :)
                var name = fetch.GetAttribute("http://schema.openid.net/namePerson").Values[0];
                //...store name in session or something...
    }
    FormsAuthentication.RedirectFromLoginPage(openid.Response.ClaimedIdentifier, false); //...snip...

    Note that DotNetOpenId library offers a few "well known" attributes as enums which all uses the "axschema.org" schema, but they do not work with the myOpenId provider. That's why I'm using the "schema.openid.net" schema instead.

    Rakuto Furutani blogged about the attribute schema problems in a Ruby on Rails post:

    myOpenID supports only some attributes that can be exchange with OpenID Attribute Exchange, but you should care about Type URI, because myOpenID doesn't support Type URI described on "http://www.axschema.org/types/". You should specify Type URI with "http://schema.openid.net/" instead.

    It could be I'm using an older version of the DotNetOpenId library and it's been changed in newed releases. I have to check this out.

    Also, Andrew Arnott has written a longer post on how to use DotNetOpenId's Attribute Extensions extension which you should read if you want some more in-depth sample code (he's using ASP.NET WebForms).

  • ThreadPool.QueueUserWorkItem with Anonymous Types

    I thought this blog post by Matt Valerio was good, and it gave me a few ideas to use in a current test project. He wrote a helper method to be able to use anonymous types when calling a delegate or lambda in the ThreadPool:

    public delegate void WaitCallback<T>(T state);
    
    public static class ThreadPoolHelper
    {
        public static bool QueueUserWorkItem<T>(T state, WaitCallback<T> callback)
        {
            return ThreadPool.QueueUserWorkItem(s => callback((T)s), state);
        }
    }

    And his example code for using this method:

    ThreadPoolHelper.QueueUserWorkItem(
        new { Name = "Matt", Age = 26 },
        (data) =>
        {
            string name = data.Name;
            int age = data.Age;
            // Long-running computation
        });

     

    Cute, eh?