Go Back
  • NHibernate basic 2 table example

    I’m slowly becoming intrigued by NHibernate and was playing around with it against AdventureWorks tonight.

     

    I came up with this basic 2 table tutorial using Employee and Contact.

     

    First, I created a wpf project for my user interface and I slapped a ListView on the main window like this:

    <Window x:Class="NHAdventureWorks.Window1"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        Title="Window1" Height="300" Width="300"

         Loaded="Window_Loaded">

        <Grid>

            <ListView x:Name="lvwEmployees">

                

            </ListView>

        </Grid>

    </Window>

     

    Then I hooked up the Loaded Event:

    private void Window_Loaded(object sender, RoutedEventArgs e)

            {

                this.lvwEmployees.ItemsSource = LoadEmployeesFromDatabase();

            }

     

    Then I added this code from the ‘hello world’ example in Manning’s “NHibernate in action” book:

            static ISession OpenSession()

            {

                if (factory == null)

                {

                    Configuration c = new Configuration();

                    //c.AddClass(typeof(Employee));

                    c.AddAssembly(Assembly.GetCallingAssembly());

                    factory = c.BuildSessionFactory();

                }

                return factory.OpenSession();

            }

            static ISessionFactory factory;

     

            static IList<Employee> LoadEmployeesFromDatabase()

            {

                using (ISession session = OpenSession())

                {

                    IQuery query = session.CreateQuery(

                    "from Employee as emp order by emp.Contact.LastName asc");

                    IList<Employee> foundEmployees = query.List<Employee>();

                    return foundEmployees;

                }

            }

     

    Then I declared my domain model classes Employee and Contact as such:

        internal class Employee

        {

            internal int EmployeeId;

            internal string LoginId;

            internal Contact Contact { get; set; }

            internal int ContactId;

            public override string ToString()

            {

                return string.Format("{0} : {1} {2}", LoginId, Contact.FirstName, Contact.LastName);

            }

     

        }

        internal class Contact

        {

            internal int ContactId;

            internal string FirstName;

            internal string LastName;

     

        }

     

    Then I had to do the NHibernate specific stuff. First I added an xml file to the project called Employee.hbm.xml and then changed it’s build action to “Embedded Resource” (VERY IMPORTANT)

    Then I added a Contact.hbm.xml file as well (also marked as Embedded Resource). Then their contents looked like this respectively:

     

    <?xml version="1.0"?>

    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"

    auto-import="true">

      <class name="NHAdventureWorks.Employee, NHAdventureWorks"

             table="HumanResources.Employee" lazy="false">

        <id name="EmployeeId"

            column="EmployeeID"

            access="field">

          <generator class="native" />

        </id>

        <property name="LoginId" access="field" column="LoginID"/>

        <many-to-one

          name="Contact"

          column="ContactID"

          class="NHAdventureWorks.Contact, NHAdventureWorks"

          not-null="true" />

      </class>

    </hibernate-mapping>

     

    <?xml version="1.0"?>

    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"

    auto-import="true">

      <class name="NHAdventureWorks.Contact, NHAdventureWorks"

             table="Person.Contact"

             lazy="false">

        <id name="ContactId"

           column="ContactID"

           access="field">

          <generator class="native" />

        </id>

        <property name="FirstName" access="field" column="FirstName"/>

        <property name="LastName" access="field" column="LastName"/>

      </class>

    </hibernate-mapping>

     

    Of course there are some app.config settings that had to be put into place:

    <?xml version="1.0" encoding="utf-8" ?>

    <configuration>

      <configSections>

        <section name="hibernate-configuration"

                 type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate" />

        <section name="log4net"

                 type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />

      </configSections>

      <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">

        <session-factory>

          <property name="connection.provider">

            NHibernate.Connection.DriverConnectionProvider

          </property>

          <property name="connection.driver_class">

            NHibernate.Driver.SqlClientDriver

          </property>

          <property name="connection.connection_string">

            Server=(local);database=AdventureWorks;Integrated Security=SSPI;

          </property>

          <property name="dialect">

            NHibernate.Dialect.MsSql2000Dialect

          </property>

          <property name="show_sql">

            false

          </property>

          <property name='proxyfactory.factory_class'>NHibernate.ByteCode.LinFu.ProxyFactoryFactory, NHibernate.ByteCode.LinFu</property>

        </session-factory>

      </hibernate-configuration>

      <log4net>

        <appender name="ConsoleAppender"

        type="log4net.Appender.ConsoleAppender, log4net">

          <layout type="log4net.Layout.PatternLayout, log4net">

            <param name="ConversionPattern" value="%m" />

          </layout>

        </appender>

        <root>

          <priority value="WARN" />

          <appender-ref ref="ConsoleAppender" />

        </root>

      </log4net>

    </configuration>

    Full story

    Comments (0)

  • Making a custom mouse cursor in silverlight 3

    When you write games in silverlight you are going to want to make a custom mouse cursor. Maybe you want a gun cross hair or maybe an animated cursor of some sort. I’ve found no way to do this other than to turn off the cursor and hook an image up to the mouse move events.

     

    Basically let’s start with a silverlight application and change the Grid to a Canvas like this:

    <UserControl x:Class="MouseCursorReplacement.MainPage"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

        mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480">

        <Canvas x:Name="LayoutRoot">

           

        </Canvas>

    </UserControl>

     

    Now add a cursor representation as an image tag and point it to your new cursor file. In this case I’m using a cross hair. I make the ZIndex high so it floats on top of anything I put in.

    <UserControl x:Class="MouseCursorReplacement.MainPage"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

        mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480">

        <Canvas x:Name="LayoutRoot">

            <Image x:Name="CustomCursorImage" Source="cross.png" Canvas.ZIndex="100"/>

        </Canvas>

    </UserControl>

     

    Now go into your code behind and setup a load event and disable the cursor:

        public partial class MainPage : UserControl

        {

            public MainPage()

            {

                this.Loaded += new RoutedEventHandler(MainPage_Loaded);

                InitializeComponent();

            }

     

            void MainPage_Loaded(object sender, RoutedEventArgs e)

            {

                this.Cursor = Cursors.None;

            }

        }

     

    Now add a mouse move event and finally the code that will make the image move around as your new cursor.

            public MainPage()

            {

                this.Loaded += new RoutedEventHandler(MainPage_Loaded);

                this.MouseMove += new MouseEventHandler(MainPage_MouseMove);

                InitializeComponent();

            }

     

            void MainPage_MouseMove(object sender, MouseEventArgs e)

            {

                Point position = e.GetPosition(LayoutRoot);

                double leftOffset = CustomCursorImage.ActualWidth / 2;

                double topOffset = CustomCursorImage.ActualHeight / 2;

                double newLeft = position.X - leftOffset;

                double newTop = position.Y - topOffset;

                Canvas.SetLeft(CustomCursorImage, newLeft);

                Canvas.SetTop(CustomCursorImage, newTop);

            }

     

    The last part. And I find this a little ‘magical’ is that when the background was white the mouse kept “losing” the new cursor. So I changed the background to classic ‘directx’ cornflowerblue and the problem went away (I don’t know why and believe me I don’t usually fall for the ‘it must be magic’ comment, but apparently it works?):

     

    <UserControl x:Class="MouseCursorReplacement.MainPage"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

        mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480">

        <Canvas x:Name="LayoutRoot" Background="CornflowerBlue">

            <Image x:Name="CustomCursorImage" Source="cross.png" Canvas.ZIndex="100"/>

        </Canvas>

    </UserControl>

     

     

    Full story

    Comments (0)

  • Some TDD in the real world

    One of the most common things that I run into when doing TDD with NUnit in the 'real world' is that the ugly truth is dependencies are either hard or impossible to test.

     

    Take for example this code snippet where we're calling a webservice a couple times to do some work.

        public class HumanResources

     

        {

            public void FireThisGuy(long employeeId)

            {

                HumanResourcesService service = new HumanResourcesService();

                GetEmployeeRequest request = new GetEmployeeRequest();

                request.EmployeeId=employeeId;

                Employee emp = service.GetEmployee(request).Employee;

                emp.TerminationDate = DateTime.Now;

     

                SetEmployeeRequest setRequest = new SetEmployeeRequest();

                setRequest.Employee = emp;

                service.SetEmployee(setRequest);

            }

        }

     

     

     

     

     

    We know it's a bad practice to call webservices in our unit tests for a few reasons. (namely it's slow). So let's refactor a little and remove anything related to the webservices out. I extract method on the get...

           public void FireThisGuy(long employeeId)

            {

                Employee emp = GetEmployeeById(employeeId);

                emp.TerminationDate = DateTime.Now;

     

                HumanResourcesService service = new HumanResourcesService();

                SetEmployeeRequest setRequest = new SetEmployeeRequest();

                setRequest.Employee = emp;

                service.SetEmployee(setRequest);

            }

     

            protected Employee GetEmployeeById(long employeeId)

            {

                Employee emp;

                HumanResourcesService service = new HumanResourcesService();

                GetEmployeeRequest request = new GetEmployeeRequest();

                request.EmployeeId=employeeId;

                emp = service.GetEmployee(request).Employee;

                return emp;

            }

     

    notice this wasn't a straight up 'extract to method' on your refactoring tool. I did about 5 small refactorings before i did the extract but just notice the complete extraction of the dependency on the webservice to a new method "GetEmployeeById".

     

    now the same for the set:

     

           public void FireThisGuy(long employeeId)

            {

                Employee emp = GetEmployeeById(employeeId);

                emp.TerminationDate = DateTime.Now;

                SetEmployee(emp);

            }

     

            protected void SetEmployee(Employee emp)

            {

                HumanResourcesService service = new HumanResourcesService();

                SetEmployeeRequest setRequest = new SetEmployeeRequest();

                setRequest.Employee = emp;

                service.SetEmployee(setRequest);

            }

     

            protected Employee GetEmployeeById(long employeeId)

            {

                Employee emp;

                HumanResourcesService service = new HumanResourcesService();

                GetEmployeeRequest request = new GetEmployeeRequest();

                request.EmployeeId=employeeId;

                emp = service.GetEmployee(request).Employee;

                return emp;

            }

     

    now for my unit test the only thing i really want to test is the "FireThisGuy" logic. so first i would need to inherit from HumanResources and make a testing class that overrides the 2 dependencies i do not want.

        public class HumanResources

        {

            public void FireThisGuy(long employeeId)

            {

                Employee emp = GetEmployeeById(employeeId);

                emp.TerminationDate = DateTime.Now;

                SetEmployee(emp);

            }

     

            protected virtual void SetEmployee(Employee emp)

            {

                HumanResourcesService service = new HumanResourcesService();

                SetEmployeeRequest setRequest = new SetEmployeeRequest();

                setRequest.Employee = emp;

                service.SetEmployee(setRequest);

            }

     

            protected virtual Employee GetEmployeeById(long employeeId)

            {

                Employee emp;

                HumanResourcesService service = new HumanResourcesService();

                GetEmployeeRequest request = new GetEmployeeRequest();

                request.EmployeeId=employeeId;

                emp = service.GetEmployee(request).Employee;

                return emp;

            }

        }

        public class TestingHumanResources : HumanResources

        {

            public Employee GetEmployeeByIdTestingEmployee { get; set; }

            protected override Employee GetEmployeeById(long employeeId)

            {

                return GetEmployeeByIdTestingEmployee;

            }

     

            public Employee SetTestingEmployee { get; set; }

            protected override void SetEmployee(Employee emp)

            {

                SetTestingEmployee = emp;

            }

        }

     

     

     

     

     

     

     

     

     

    Now i can actually write a test that validates

      public class HumanResources

        {

            public void FireThisGuy(long employeeId)

            {

                Employee emp = GetEmployeeById(employeeId);

                emp.TerminationDate = DateTime.Now;

                SetEmployee(emp);

            }

     

            protected virtual void SetEmployee(Employee emp)

            {

                HumanResourcesService service = new HumanResourcesService();

                SetEmployeeRequest setRequest = new SetEmployeeRequest();

                setRequest.Employee = emp;

                service.SetEmployee(setRequest);

            }

     

            protected virtual Employee GetEmployeeById(long employeeId)

            {

                Employee emp;

                HumanResourcesService service = new HumanResourcesService();

                GetEmployeeRequest request = new GetEmployeeRequest();

                request.EmployeeId=employeeId;

                emp = service.GetEmployee(request).Employee;

                return emp;

            }

        }

        public class TestingHumanResources : HumanResources

        {

            public Employee GetEmployeeByIdTestingEmployee { get; set; }

            protected override Employee GetEmployeeById(long employeeId)

            {

                return GetEmployeeByIdTestingEmployee;

            }

     

            public Employee SetTestingEmployee { get; set; }

            protected override void SetEmployee(Employee emp)

            {

                SetTestingEmployee = emp;

            }

        }

        [TestFixture]

        public class HumanResourcesTests

        {

            [Test]

            public void FireThisGuy_UserIdIn_FiredEmployeeSaved()

            {

                TestingHumanResources hr = new TestingHumanResources();

                hr.GetEmployeeByIdTestingEmployee = new Employee();

                hr.GetEmployeeByIdTestingEmployee.TerminationDate = null;

     

                hr.FireThisGuy(200);

                Assert.IsNotNull(hr.SetTestingEmployee.TerminationDate);

     

            }

        }

     

     

     

     

     

     

     

     

     

     

     

     

     

    This is why im a big fan of object oriented programming and using inheritance to break dependencies. It's a real fast solution to some of the unique dependency issues i fight every day and it is a lot easier to read and debug than tons of interfaces.  This and other examples of seaming and seperation can be found in Michael Feather's book "Working Effectively with Legacy Code"

     

     

     

     

    Grab the code here

    Full story

    Comments (10)

  • Beginning C# through Test Driven Development

    So this is how this idea began...

    twitter

     

    I figured that, in the interest of bettering those who surround me and those who follow this blog, I would begin at the very start. Just like we all learned c#, let’s learn c# from scratch as if it’s brand new but using Test Driven Development.

     

    So this is my first in potentially a series… “Beginning C# through Test Driven Development”.

     

    So what is an Object?

     

    Objects are a collection of information and functionality. In other words, they are state and behavior, respectively. Every object has some type of data that we wish to manipulate and get some other type of data back out of it. Every object is a black box to which we put something in it, tell it to do something, and then usually get something back out.

    Let's start with the basics of why we use objects.

    What is inheritance?

     Inheritance is taking an Object that someone has already defined and adding more functionality to it. The idea is that you already have something doing most of what you want to do, but you just need to add a little bit more to it. You take what already exists and inherit it, then apply new things to it so you do not have to copy and paste that functionality.

     

    What are Combination, Aggregation, and Containment?

     

    When you have an object that uses or ‘contains’ other objects inside of it, this is thought of as Aggregation or Containment.

     

    Inheritance is often known as the “IS A” relationship. A dog is a mammal. A mammal is an animal.

     

    Combination is often known as the “HAS A” relationship. A dog has a leg. A leg has a foot. A foot has a toe.

     

    Lesson 1: Hello world in TDD

     

    First, we will need to create a C# Class Library project.

    twitter

     

    In .net a dll or exe is called an Assembly. A class library project creates a dll assembly. We are choosing to use a dll assembly because our unit test framework will require a dll and cannot execute tests from an exe file.

     

    Now that you have a dll, we will have to add references to a unit testing library. I have chosen MbUnit as the unit testing framework/library. 

     

    You will need to go download MbUnit and install it. Or you can download Nunit and install that.

     

    Ok now that you have a unit test framework, go back to visual studio and expand your class library project in the solution explorer.

    twitter

     

    Right click on “References” and choose “Add reference…”

    twitter

    Choose the MbUnit.Framework (Or NUnit.Framework) and hit ‘Ok”.

    twitter

     

    You have just added MbUnit.Framework.dll as an assembly reference. This allows your dll to use functionality from that dll.

     

    Now you have code that looks like this:

    using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Text

    namespace HelloWorld

    {

        public class Class1

        {

        }

    }

     

    Frankly, the class name is not appropriate and we do not need those using statements (that visual studio automatically adds for you).

     

    We will first rename the class by right clicking “Class1.cs”in the solution explorer and choosing rename:

    twitter

     

    I renamed it to “HelloWorld.cs” and allowed visual studio to change the name of the class as well. Then I removed the using statements. My code looks like this:

    namespace HelloWorld

    {

        public class HelloWorld

        {

        }

    }

     

    Now we are going to add what is called an attribute to our class. An attribute basically just adds description to your class. For now just follow along but you can research more on attributes separately if you desire.

     

    Your code should now appear like this: (or use NUnit.Framework)

     

    using MbUnit.Framework;

     namespace HelloWorld

    {

        [TestFixture]

        public class HelloWorld

        {

        }

    }

     

    A test fixture is a class that represents a set of tests around a particular area of functionality. I believe the term fixture comes from electrical engineering where they would place circuits and a test on a fixture.

     

    So let’s put our test in this fixture. We’ll add a method and give it a “Test” attribute. Methods are behavior or functionality. They can be called from other places in the program to execute a task or some behavior. Ours will start out with nothing in it.

     

    Here’s how it should look:

    using MbUnit.Framework;

     

    namespace HelloWorld

    {

        [TestFixture]

        public class HelloWorld

        {

            [Test]

            public void HelloWorldTest()

            {

     

            }

        }

    }

     

    Go ahead and Build the project by going to the build menu:(or shift + F6) (or F6 to build the whole solution, which happens to be our 1project right now)

    twitter

     

     

    So now we can run the MbUnit application to fire off this test.

     

    By default this is C:\Program Files\MbUnit\bin\MbUnit.GUI.exe

     

    Choose assemblies -> add assembly

    twitter

     

    Browse to your dll…on vista it should be in C:\Users\<userid>\Documents\VisualStudio 2008\Projects\HelloWorld\HelloWorld\bin\Debug

     

    If you click run, it will pass:

    twitter

     

    So we have a basic framed out test and test fixture but wearen’t doing anything yet!

     

    What is TDD?

     

    TDD stands for test driven development. (in some circles it’s test driven design, but in our case we’re talking about the development).

     

    Generally the mantra for TDD is “Red, Green,Refactor”

    1.      make just enough test to fail (RED)

    2.      write just enough code to pass (GREEN)

    3.      REFACTOR to remove any duplication (DRY or do not repeat yourself)

     

    Let’s go ahead and make just enough test to fail using astring object.

    using MbUnit.Framework;

     

    namespace HelloWorld

    {

        [TestFixture]

        public class HelloWorld

        {

            [Test]

            public void HelloWorldTest()

            {

                string helloWorld = null;

                Assert.AreEqual("Hello World!", helloWorld);

            }

        }

    }

    NOTE: There are 3 basic parts to any test. 

    1. Set up some state. Here we've defined a string.
    2. Do some behavior. Right now we don't really have any behavior, but normally there would be a method called .
    3. Assert the state is what you expect

    Build this then run the test again. See what happens.

    twitter

     

    We failed the test. This is GOOD.

     

    Now let’s make the test pass by changing the null to “Hello World!”

     

    using MbUnit.Framework;

     

    namespace HelloWorld

    {

        [TestFixture]

        public class HelloWorld

        {

            [Test]

            public void HelloWorldTest()

            {

                string helloWorld = "Hello World!";

                Assert.AreEqual("Hello World!", helloWorld);

            }

        }

    }

     

    When we build and run the test it now passes.

     

    Red, Green…

     

    Now we should refactor out any duplication.

     

    Do we have any?

     

    Well we have this “Hello World!” string in there twice. Would it be much of a test if we removed that?

     

    I’d say for testing practices sake, we should probably leave each string defined separately! More reasoning for that will be apparent as you learn more about TDD, but for now let’s recap what we’ve learned in this post.

     

     We’ve introduced the class and string keywords. We saw how to create a dll, add references to it, and how to write a basic unit test using MbUnit.  Lastly, we saw how to do the basics of TDD by making it red, making it green, and then checking for duplication.

     

    Full story

    Comments (2)

  • Polymorphing different Types


    So my friend (though not good enough friend to be my ‘boatfriend’) ran into a programming issue the other day at work. He had two objectswith similar data and no behavior (vb6 style data/procedural programming). Unfortunately,these two objects did NOT inherit from the same base object and they were beingused similarly in an asp.net code behind page but there was no clearabstraction.

     

    If(foo.GetType() == typeof(recurringTransaction))

    {

    Foo1();

    }

    Else

    {

    Foo2();

    }

     

    So basically “foo” could be one of two different types… arecurring transfer or a single transfer. Depending on the type, we’d get adifferent UI behavior.

     

    This is clearly an opportunity for polymorphism, but we didNOT have control of these objects! They were vendor code.

     

    So what do you do in this situation?

     

    Well directly to the point, you would create a new baseclass called “Transfer” and then use composition to encapsulate the dataobjects. Making something like this:

     

    What’s that look like in code?

         class OldSingleTransfer

        {

            //Some data

        }

        class OldRecurringTransfer

        {

            //Some similiar data

        }

        abstract class Transfer

        {

            public abstract void MyUIBehavior();

        }

        class SingleTransfer : Transfer

        {

            OldSingleTransfer instance;

            public override void MyUIBehavior()

            {

                //Specific single transfer code

            }

        }

        class RecurringTransfer : Transfer

        {

            OldRecurringTransfer instance;

            public override void MyUIBehavior()

            {

                //specific recurring transfer code

            }

        }

     Now you can just do foo.MyUIBehavior(); and be done with it.

     I know what you're thinking... GOD that's a LOT of code just to do this one thing. That's not how i would do this.

    Well, yes you're right this is more code initially... however in reality what we had was 40-100 lines of 'type specific' code that was mostly all repeated for both types. We've eliminated all of that duplication and left ourselves with an easier set of operations to maintain and reduced the complexity by removing the conditional logic.

    There were bugs lurking in this code... for example what would happen if you made a third type of transfer? it would have hit the "else" condition... meaning "single transfer". What if it was a scheduled transfer?

    Full story

    Comments (7)

  • Init Params in Silverlight 3

    I converted my silverlight app over to silverlight 3 today and ran into an issue with InitParams because the silverlight hosting control is no longer valid for silverlight 3 nor provided in the vs2008 tools.

     

    The quick and dirty: I had to take all of the object tag string and move it to the code behind by inserting into the inner Html of the div tag that hosts it.

     

    Explanation:

     

    When you create a new Silverlight 3 application it asks you if you want to add it to an existing asp.net application. If you do that it generates a test aspx page that has something like this:

     

        <div id="silverlightControlHost">

            <object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%"height="100%">

                <param name="source"value="ClientBin/JPeckham.xap"/>

                <param name="onError"value="onSilverlightError"/>

                <param name="background"value="white"/>

                <param name="minRuntimeVersion"value="3.0.40624.0"/>

                <param name="autoUpgrade"value="true"/>

                <href="http://go.microsoft.com/fwlink/?LinkID=149156&v=3.0.40624.0"style="text-decoration:none">

                        <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get MicrosoftSilverlight" style="border-style:none"/>

                </a>

              </object><iframe id="_sl_historyFrame" style="visibility:hidden;height:0px;width:0px;border:0px"></iframe></div>

    What you need to do is change the div to be runat=”server” and do a CUT of the object tag contents. You’ll have this then:

    <div id="silverlightControlHost"runat="server">

    </div>

     

    Now inside of your code behind for the page, past that string and parse it using a string builder, like this:

    silverlightControlHost.InnerHtml =

    silverlightControlHost.InnerHtml =

                new StringBuilder(

                @"<object id=""SilverlightApp"" data=""data:application/x-silverlight-2,""

    type=""application/x-silverlight-2"" width=""100%"" height=""100%"" >

                  <param name=""source"" value=""../../ClientBin/JPeckham.xap""/>

                  <param name=""onError"" value=""onSilverlightError"" />

                  <param name=""background"" value=""white""/>

                  <param name=""minRuntimeVersion"" value=""3.0.40624.0"" />

                  <param name=""autoUpgrade"" value=""true""/>

              <param name=""InitParams"" value=")

     

                                                .Append(BuildSilverlightInitParametersFromQueryString())

               

                                                .Append( @"""/>

                  <a href=""http://go.microsoft.com/fwlink/?LinkID=149156&v=3.0.40624.0""style=""text-decoration:none"">

                        <img src=""http://go.microsoft.com/fwlink/?LinkId=108181"" alt=""Get Microsoft Silverlight"" style=""border-style:none""/>

                  </a>

              </object><iframe id=""_sl_historyFrame"" style=""visibility:hidden;height:0px;width:0px;border:0px""></iframe>").ToString();

     

    NOTE: Basically BuildSilverlightInitParametersFromQueryString()is the method that constructs your InitParams value string. So write thathowever you feel like. Make sure toHtmlEncode it! J

    Full story

    Comments (3)

  • POST data is missing in the POST

    So I was working on this WCF client to talk to the facebook REST api and ran into a really strange issue.

    If i utilized the client to call getLoggedInUser it would work when called from an ASP.NET page code behind but it would fail "POST data is missing in the POST" when I tried to call it from within my WCF service host.

    For clarification, I have a WCF service that I created and within that service I am calling over to facebook using my WCF REST client.

    Basically the client tier is the web browser.
    the server tier is the web server with my wcf service and my code behind file.

    the server tier uses a facebook WCF REST client to talk to facebook api.

    //end of clarification :)

    Anyhow so I fired up Fiddler and sure enough, every call from my wcf service over to facebook was being sent as a POST! not a GET.

    In the end i had to change my code to this:

     

            public long getLoggedInUser(string sessionKey)

            {

                Dictionary<string, string> args = CreateArgsDictionary();

                args.Add("method","users.getLoggedInUser");

                args.Add("session_key",sessionKey);

                args.Add("call_id",DateTime.Now.Ticks.ToString());

                stringsig = new Signature(args).ToString();

                stringqueryString = string.Format

                    ("?method=users.getLoggedInUser&api_key={0}&sig={1}&v=1.0&call_id={2}&session_key={3}"

                    , args["api_key"], sig,args["call_id"],args["session_key"]);

               

                //HACK:using this instead of WCF.

                varrequest = WebRequest.Create(channelFactory.Endpoint.Address.Uri.AbsoluteUri+ queryString);

        

                using(var response= request.GetResponse()) 

                {

                    varxs = new XmlSerializer(typeof(users_getLoggedInUser_response));

                    return(xs.Deserialize(response.GetResponseStream())as users_getLoggedInUser_response).value;

                }

               

            }

    Full story

    Comments (0)

  • Duplex Service in Silverlight

    I'm writing a silverlight app for facebook and I came across a couple of blogs that were extremely helpful on the subject of duplex services in silverlight.


    then this one helped know what to put in the web.config/app.config to setup the service host

    Possibly more to come as I figure out how to implement some of this.

    --UPDATE: i tried this out and it just locks up. Never got it working. Plus it's polling so it's probably not scalable so useless for what I'm doing.

    Full story

    Comments (0)

  • Authenticating a Canvas Page in Facebook with .Net

    So, the first time I did this was a while back and I remembered it being very confusing.

    Here's the basic breakdown:

     First you need to configure your settings on the app.

     

     

    Note: Canvas Callback URL is where you are going to create a page (in my case Default.aspx) for facebook to connect to.

     

    Second:

    Make an asp.net website. As above mine is called “FacebookApps”. Then I made a folder for the “jpeckham” facebook app. Then a folder called Canvas. Then I put a new webform called Default.aspx in that folder. Looks like this:

     

     

    Third:

    Setup your REST service client to have these operations in the service contract for WCF.

         [OperationContract]

            [WebGet(

                UriTemplate =

            "?method=Users.getLoggedInUser&api_key={apiKey}&sig={sig}&v=1.0&call_id={callId}&session_key={sessionKey}"

                ,

                BodyStyle = WebMessageBodyStyle.Bare)]

            Message getLoggedInUser(string apiKey, string sig, string callId, string sessionKey);

     

            [OperationContract]

            [WebGet(UriTemplate = "?method=Auth.getSession&api_key={apiKey}&sig={sig}&v=1.0&auth_token={authToken}",

                BodyStyle = WebMessageBodyStyle.Bare)]

            Message getSession(string apiKey, string sig, string authToken);

     

    Lastly:

    Do some .net/c# code in the webpage that is something like this:

    string apiKey = "1f3b0f29b995519b003f0fe236d56907";

            Facebook.Service.FacebookCustomProxy proxy = new Facebook.Service.FacebookCustomProxy("FacebookClient",apiKey);

          

            if (string.IsNullOrEmpty(Request.QueryString["fb_sig_session_key"]) && string.IsNullOrEmpty(Request.QueryString["auth_token"]))

            {

                Response.Redirect("http://www.facebook.com/login.php?v=1.0&api_key="+apiKey);

            }

            else

            if (!string.IsNullOrEmpty(Request.QueryString["auth_token"]))

            {

                Response.Write(proxy.getSession(Request.QueryString["auth_token"]).ToString());

            }

            else

            {

                Dictionary<string, string> incomingParmsFromFacebook = new Dictionary<string, string>();

                foreach (string s in Request.QueryString.Keys)

                {

                    if (s.StartsWith("fb_sig_"))

                    {

                        incomingParmsFromFacebook.Add(s, Request.QueryString[s]);

                    }

                }

                if (FacebookCustomProxy.IsValidSigFromFacebook(Request.QueryString["fb_sig"],incomingParmsFromFacebook))

                {

     

                    Response.Write("Your User Id Is: " + proxy.getLoggedInUser(Request.QueryString["fb_sig_session_key"]));

                }

                else

                {

                    Response.Write("Invalid Signature, Access Denied");

                }

            }

     

    I’ll summarize briefly. Basically check to see if you have either a session key or an auth token. If you don’t… kick them out to the login page to authenticate. If they do have an auth token, they just came from the login page so retrieve their brand new session from the API. Finally, if you do have a sessionkey being passed to you from somewhere, check to see if it’s from facebook (see facebook wiki for info on validating sigs from facebook) and then once verified go ahead and make calls using that session key.

     

    I haven’t exactly figured out why a session key is less trusted than an auth_token yet… but apparently they don’t do any sig for an auth token query string. Go figure.

     

     

     

     

     

     

     

     

     

     

    Full story

    Comments (0)

  • Calling RESTful Facebook services with WCF

     

    So, I got some crazy idea that I wanted to take another stab at writing a facebook application. A friend at work was showing off his WPF app that utilizes Netflix webservices and it gave me an idea about a facebook app. Unfortunately, someone already wrote my idea (http://apps.facebook.com/mynetflix ).

     

    I got the idea of how to use wcf from this twitter app example on Kirk Evans Blog

    (here's the code class library minus the config file Download Here)

    <?xml version="1.0" encoding="utf-8" ?>

    <configuration>

      <system.serviceModel>

        <bindings>

          <webHttpBinding>

            <binding name="FacebookConfig">

              <security mode="None"/>

            </binding>

          </webHttpBinding>

        </bindings>

        <client>

          <endpoint

            address="http://api.facebook.com/restserver.php"

            binding="webHttpBinding"

            bindingConfiguration="FacebookConfig"

            contract="Facebook.Service.IFacebookService"

            name="FacebookClient" />

        </client>

      </system.serviceModel>

    </configuration>

     

     My service contract ended up looking like this after a few times banging on my head getting an error that said “No POST data to POST” when trying WebInvoke Attribute.

        [ServiceContract(Namespace=http://api.facebook.com/1.0/)]

        [XmlSerializerFormat(Style= OperationFormatStyle.Document,Use=OperationFormatUse.Literal)]

     

     

        public interface IFacebookService

        {

            [OperationContract]

              [WebGet(

                UriTemplate="?method=admin.getBannedUsers&api_key={apiKey}&sig={sig}&v=1.0",

                BodyStyle=WebMessageBodyStyle.Bare)]

            Message getBannedUsers(string apiKey, string sig);

     

            [OperationContract]

              [WebGet(

                UriTemplate="?method=admin.banUsers&api_key={apiKey}&sig={sig}&v=1.0&uids={userIds}",

                BodyStyle=WebMessageBodyStyle.Bare)]

            Message banUsers(string apiKey, string sigstring userIds);

     

            [OperationContract]

            [WebGet(

                UriTemplate="?method=admin.unbanUsers&api_key={apiKey}&sig={sig}&v=1.0&uids={userIds}",

                BodyStyle=WebMessageBodyStyle.Bare

                )]

            Message unbanUsers(string apiKey, string sig, string userIds);

     

        }

     

    I chose these 3 methods because they do not require a session so I can just pass in my API key without needing a facebook signon to test my mad experiments.

     

    So let’s move on to actually using this thing and the speed bumps I ran into there.

     

    This is a work in progress, so far I’ve only done the “admin.unbanUsers” call

      public class FacebookCustomProxy

        {

            private readonly WebChannelFactory<IFacebookService> channelFactory;

            private readonly IFacebookService facebookChannel;

     

            public FacebookCustomProxy(string endpointName)

            {

                channelFactory =

                    new WebChannelFactory<IFacebookService>(endpointName);

                facebookChannel = channelFactory.CreateChannel();

            }

     

            [Obsolete]

            public Message getBannedUsers(string apiKey, string sig)

            {

                return facebookChannel.getBannedUsers(apiKey, sig);

            }

            [Obsolete]

            public Message banUsers(string apiKey, string sig, string userIds)

            {

                return facebookChannel.banUsers(apiKey, sig, userIds);

            }

     

            public Message unbanUsers( long[] userIds)

            {

                Dictionary<string, string> args = new Dictionary<string, string>();

                args.Add("method", "admin.unbanUsers");

                args.Add("api_key", "<INSERT YOUR API_KEY HERE>");

                args.Add("uids",JasonMe(userIds));

                args.Add("v","1.0");

                string sig = MakeSig(args);

                return facebookChannel.unbanUsers(args["api_key"], sig, args["uids"]);

            }

     

            string JasonMe(long[] arrayOfLongs)

            {

                StringBuilder builder = new StringBuilder("[");

                bool adComma = false;

                foreach (long val in arrayOfLongs)

                {

                    if (adComma)

                    { builder.Append(","); }

                    builder.Append(val.ToString());

                    adComma = true;

                }

                builder.Append("]");

                return builder.ToString();

            }

     

     

             string MakeSig(IDictionary<string, string> parameters)

            {

                StringBuilder signatureBuilder = new StringBuilder();

     

                // Sort the keys of the method call in alphabetical order

                List<string> keyList = new List<string>(parameters.Keys);

                keyList.Sort();

     

                // Append all the parameters to the signature input paramaters

                foreach (string key in keyList)

                    signatureBuilder.Append(String.Format(CultureInfo.InvariantCulture, "{0}={1}", key, parameters[key]));

     

                // Append the secret to the signature builder

                signatureBuilder.Append("<INSERT YOUR APP SECRET HERE>");

     

                MD5 md5 = MD5.Create();

                // Compute the MD5 hash of the signature builder

                byte[] hash = md5.ComputeHash(Encoding.UTF8.GetBytes(signatureBuilder.ToString().Trim()));

     

                // Reinitialize the signature builder to store the actual signature

                signatureBuilder = new StringBuilder();

     

                // Append the hash to the signature

                foreach (byte hashByte in hash)

                    signatureBuilder.Append(hashByte.ToString("x2", CultureInfo.InvariantCulture));

     

                return signatureBuilder.ToString();

            }

        }

     

     

    The first thing I ran into was I tried to get back just a string or a specific strongly typed object. But I kept running into problems with that. One, I couldn’t deserialize into a string, and two, sometimes I would get back <admin_unbanUsers_response> but sometimes I’d get back <error_response>. So I ended up using System.ServiceModel.Channels.Message class.

     

    The second thing I hit was getting “Invalid Sig” errors from facebook.php. props for the MakeSig method to midowazzan on this facebook forum post

     

    Lastly, I had issues because I wasn’t sending a JSON array to facebook. Unfortunately facebook doesn’t use a regular JSON array like this: {“user ids” : [378173,738127]} they use one that looks like this “[47387483,4783743]”, which is ok, just strange and you have no way of knowing without pouring through the awful wiki site.

     

     

    Finally the code to actually execute this one method becomes trivial:

         FacebookCustomProxy proxy = new FacebookCustomProxy("FacebookClient");

               

                Message msg = proxy.unbanUsers( new long[]{789789,12344});

               

                string result = msg.ToString();

               

               

                Console.WriteLine(result);

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    Full story

    Comments (3)

  1. 1
  2. 2
  3. Next page