• 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

    <?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/")]

        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 (0)

  • Speeding Up Processing with Async Delegates

    The other day we had to add a longer running I/O call during a log in process that already took a while and I was asked to ensure that we do not add any more additional time to the log in process. I recalled using delegates to speed up some data access to some FoxPro databases a couple years back when I was at SRG J

     

    Basically, let’s say you have a simple little program that does some adding and then does some multiplying. To make it interesting we’ll make each method take 10 seconds.

    It looks like this:

     

            static void Main(string[] args)

            {

                DateTime start = DateTime.Now;

                int addresult = AddTwoNumbers(2, 3);

                int multiplyResult = MultiplyTwoNumbers(2, 3);

                DateTime finish = DateTime.Now;

                TimeSpan resultTime = finish - start;

                Console.WriteLine("Add Result = {0}, Multiply Result = {1}, Time To Run = {2}", addresult, multiplyResult, resultTime);

                Console.WriteLine("press a key to exit");

                Console.ReadKey();

            }

          

            public static int AddTwoNumbers(int parm1, int parm2)

            {

                for (int x = 0; x < 10; x++)

                {

                    Thread.Sleep(1000);

                    Console.WriteLine("AddTwoNumbers waiting");

                }

                return parm1 + parm2;

            }

            public static int MultiplyTwoNumbers(int parm1, int parm2)

            {

                for (int x = 0; x < 10; x++)

                {

                    Thread.Sleep(1000);

                    Console.WriteLine("MultiplyTwoNumbers waiting");

                }

                return parm1 * parm2;

            }

     

    Basically it runs sequentially first adding two numbers after counting to 10 then multiplying two numbers while counting to 10. The output looks like this and takes about 20 seconds to run J

     

     

     

    Let’s now convert this over to adding delegates. Our methods have a signature of int [name](int, int) so we’ll have to make a delegate with the same signature. For clarity in my code I always make a delegate type specific to each method type.

     

    public delegate int AddTwoNumbersDelegate(int parm1, int parm2);

    public delegate int MultiplyTwoNumbersDelegate(int parm1, int parm2);

     

    then I’ll add a couple lines to my main function. It’ll look like this:

    AddTwoNumbersDelegate addDelegate = new AddTwoNumbersDelegate(AddTwoNumbers);

    MultiplyTwoNumbersDelegate multiplyDelegate = new MultiplyTwoNumbersDelegate(MultiplyTwoNumbers);

     

    That just creates the delegate. So now if I call addDelegate(2,2); it will delegate over to MultiplyTwoNumbers(2,2); but the COOL thing with delegates is you automatically get the Async Pattern built into them. So let’s add some code to fire off both of these delegates asynchronously:

     

                IAsyncResult addIar = addDelegate.BeginInvoke(2, 3, null, null);

                IAsyncResult multiplyIar = multiplyDelegate.BeginInvoke(2, 3, null, null);

     

    Ok, what are these nulls? Well the first null is the AsyncCallback reference… this we would pass in another delegate with a specific format. When the asynchronous operation finishes, it will execute the call back delegate and pass in a reference to an IAsyncResult implementation. The second is an object reference where we can pass in state. I’ll show you some tricks we can do with that some day.

     

    For now, ignore both of these parameters because we’re going to block the thread right after we start these invocations. BeginInvoke is non-blocking… meaning that after you call BeginInvoke another thread is fired up and begins working the invocation off the thread pool but your main app thread continues on to the next statement (another BeginInvoke call).

     

    So anyhow, now we have 2 threads working at the same time and we want to block the app thread to wait for both of them to exit (Synchronize the two worker threads). This is the simplest way to synch threads… but not always ideal (see WaitHandle, AutoResetEvent, ManualResetEvent, Mutex, Semaphore, ReaderLock and WriterLock for other ideas about how to sync threads)

     

    So here’s our thread blocking calls:

    /*int*/  addresult = addDelegate.EndInvoke(addIar);

    /*int*/  multiplyResult = multiplyDelegate.EndInvoke(multiplyIar);

     

    Then we wrap this all up with a console.writeline… here’s the whole final app:

        class Program

        {

            static void Main(string[] args)

            {

                DateTime start = DateTime.Now;

                int addresult = AddTwoNumbers(2, 3);

                int multiplyResult = MultiplyTwoNumbers(2, 3);

                DateTime finish = DateTime.Now;

                TimeSpan resultTime = finish - start;

                Console.WriteLine("Add Result = {0}, Multiply Result = {1}, Time To Run = {2}", addresult, multiplyResult, resultTime);

                Console.WriteLine("To begin the async press any key");

                Console.ReadKey();

     

                start = DateTime.Now;

                AddTwoNumbersDelegate addDelegate = new AddTwoNumbersDelegate(AddTwoNumbers);

                MultiplyTwoNumbersDelegate multiplyDelegate = new MultiplyTwoNumbersDelegate(MultiplyTwoNumbers);

                IAsyncResult addIar = addDelegate.BeginInvoke(2, 3, null, null);

                IAsyncResult multiplyIar = multiplyDelegate.BeginInvoke(2, 3, null, null);

                addresult = addDelegate.EndInvoke(addIar);

                multiplyResult = multiplyDelegate.EndInvoke(multiplyIar);

                finish = DateTime.Now;

                resultTime = finish - start;

               

                Console.WriteLine("Add Result = {0}, Multiply Result = {1}, Time To Run = {2}", addresult, multiplyResult, resultTime);

                Console.WriteLine("press any key to exit");

                Console.ReadKey();

               

            }

          

            public static int AddTwoNumbers(int parm1, int parm2)

            {

                for (int x = 0; x < 10; x++)

                {

                    Thread.Sleep(1000);

                    Console.WriteLine("AddTwoNumbers waiting");

                }

                return parm1 + parm2;

            }

            public static int MultiplyTwoNumbers(int parm1, int parm2)

            {

                for (int x = 0; x < 10; x++)

                {

                    Thread.Sleep(1000);

                    Console.WriteLine("MultiplyTwoNumbers waiting");

                }

                return parm1 * parm2;

            }

        }

        public delegate int AddTwoNumbersDelegate(int parm1, int parm2);

        public delegate int MultiplyTwoNumbersDelegate(int parm1, int parm2);

     

     

     

     

     

     

    Full story

    Comments (0)

  • Controlling Schema In WCF

    So I’m studying the MCTS for WCF and they talked about the differences between Data Contract serialization and Xml Serializer serialization as it pertains to wsdl. I did a little deeper diving to get some insight into what that really meant to me. What I learned is that DataContracts are explicit while XmlSerializer is implicit. Meaning that I must choose what to include in a data contract and I must choose what to ignore in the XmlSerializer format. Here take a look at this code using the XmlSerializerFormatAttribute.

     

    [ServiceContract(Name = "MyRenamedServiceName",

            Namespace="http://www.jamespeckham.com/2009/05/MCTS")]

        [XmlSerializerFormat(Style= OperationFormatStyle.Document,

            Use=OperationFormatUse.Literal)]

        //[DataContractFormat(Style= OperationFormatStyle.Document)]

        public interface IMyService

        {

            [OperationContract]

            MyData MyOperation(

                [MessageParameter(Name = "MyRequestObject")]

                    MyData unseenParamName);

        }

     

        [Serializable]

        [DataContract]

        public class MyData

        {

            //[DataMember]

            public MySubData1 Field1;

            //[DataMember]

            public MySubData2 Field2;

        }

        [Serializable]

        [DataContract]

        public class MySubData1

        {

            //[DataMember]

            public int X;

        }

        [Serializable]

        [DataContract]

        public class MySubData2

        {

            //[DataMember]

            public int Z;

        }

    What do these attributes mean?

     

    The easy ones first:

    ServiceContractAttribute is basically declaring your service name and the xml namespace. Pretty easy, it is of note here that if you do not put in a name it uses the interface name. So in this way you can control what gets put in the wsdl:

     

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

    - <wsdl:definitions targetNamespace="http://www.jamespeckham.com/2009/05/MCTS" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:tns="http://www.jamespeckham.com/2009/05/MCTS" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:wsa10="http://www.w3.org/2005/08/addressing" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex">

    - <wsdl:types>

    - <xsd:schema targetNamespace="http://www.jamespeckham.com/2009/05/MCTS/Imports">

      <xsd:import schemaLocation="http://localhost:52251/Service1.svc?xsd=xsd0" namespace="http://www.jamespeckham.com/2009/05/MCTS" />

      </xsd:schema>

      </wsdl:types>

    - <wsdl:message name="MyRenamedServiceName_MyOperation_InputMessage">

      <wsdl:part name="parameters" element="tns:MyOperation" />

      </wsdl:message>

    - <wsdl:message name="MyRenamedServiceName_MyOperation_OutputMessage">

      <wsdl:part name="parameters" element="tns:MyOperationResponse" />

      </wsdl:message>

    - <wsdl:portType name="MyRenamedServiceName">

    - <wsdl:operation name="MyOperation">

      <wsdl:input wsaw:Action="http://www.jamespeckham.com/2009/05/MCTS/MyRenamedServiceName/MyOperation" message="tns:MyRenamedServiceName_MyOperation_InputMessage" />

      <wsdl:output wsaw:Action="http://www.jamespeckham.com/2009/05/MCTS/MyRenamedServiceName/MyOperationResponse" message="tns:MyRenamedServiceName_MyOperation_OutputMessage" />

      </wsdl:operation>

      </wsdl:portType>

      </wsdl:definitions>

     

    Ok so that’s all well and good. What about XmlSerializerFormatAttribute?

     

    There are basically two ways to serialize your Xml. You can either format it using the XmlSerializer (using this attribute) or you can use the DataContractSerializer.

    [DataContractFormat(Style= OperationFormatStyle.Document)]

     

    Their output is different and the way the book explains it is that XmlIgnoreAttribute is used to ignore things that shouldn’t be in the contract, while in a Data Contract Serialization you have to explicitly include things that should be in there.

     

    So here’s what it looks like based on the code above:

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

    - <xs:schema elementFormDefault="qualified" targetNamespace="http://www.jamespeckham.com/2009/05/MCTS" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://www.jamespeckham.com/2009/05/MCTS">

    - <xs:element name="MyOperation">

    - <xs:complexType>

    - <xs:sequence>

      <xs:element minOccurs="0" maxOccurs="1" name="MyRequestObject" type="tns:MyData" />

      </xs:sequence>

      </xs:complexType>

      </xs:element>

    - <xs:complexType name="MyData">

    - <xs:sequence>

      <xs:element minOccurs="0" maxOccurs="1" name="Field1" type="tns:MySubData1" />

      <xs:element minOccurs="0" maxOccurs="1" name="Field2" type="tns:MySubData2" />

      </xs:sequence>

      </xs:complexType>

    - <xs:complexType name="MySubData1">

    - <xs:sequence>

      <xs:element minOccurs="1" maxOccurs="1" name="X" type="xs:int" />

      </xs:sequence>

      </xs:complexType>

    - <xs:complexType name="MySubData2">

    - <xs:sequence>

      <xs:element minOccurs="1" maxOccurs="1" name="Z" type="xs:int" />

      </xs:sequence>

      </xs:complexType>

    - <xs:element name="MyOperationResponse">

    - <xs:complexType>

    - <xs:sequence>

      <xs:element minOccurs="0" maxOccurs="1" name="MyOperationResult" type="tns:MyData" />

      </xs:sequence>

      </xs:complexType>

      </xs:element>

      </xs:schema>

     

    So let me just change these 2 attributes:

        [ServiceContract(Name = "MyRenamedServiceName",

            Namespace="http://www.jamespeckham.com/2009/05/MCTS")]

        /*[XmlSerializerFormat(Style= OperationFormatStyle.Document,

            Use=OperationFormatUse.Literal)]*/

        [DataContractFormat(Style= OperationFormatStyle.Document)]

        public interface IMyService

        {

            [OperationContract]

            MyData MyOperation(

                [MessageParameter(Name = "MyRequestObject")]

                    MyData unseenParamName);

        }

     

     

    I get this with data contract format

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

    - <xs:schema elementFormDefault="qualified" targetNamespace="http://www.jamespeckham.com/2009/05/MCTS" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://www.jamespeckham.com/2009/05/MCTS">

      <xs:import schemaLocation="http://localhost:52251/Service1.svc?xsd=xsd2" namespace="http://schemas.datacontract.org/2004/07/OTASample.Vehicles.Service" />

    - <xs:element name="MyOperation">

    - <xs:complexType>

    - <xs:sequence>

      <xs:element minOccurs="0" name="MyRequestObject" nillable="true" type="q1:MyData" xmlns:q1="http://schemas.datacontract.org/2004/07/OTASample.Vehicles.Service" />

      </xs:sequence>

      </xs:complexType>

      </xs:element>

    - <xs:element name="MyOperationResponse">

    - <xs:complexType>

    - <xs:sequence>

      <xs:element minOccurs="0" name="MyOperationResult" nillable="true" type="q2:MyData" xmlns:q2="http://schemas.datacontract.org/2004/07/OTASample.Vehicles.Service" />

      </xs:sequence>

      </xs:complexType>

      </xs:element>

      </xs:schema>

     

    So what happened? Well because I am using the DataContractFormat attribute, it correctly sees the MyData class (due to being serializable and a datacontract) but because the DataMember attribute on the fields is commented out it does not put the xml elements for those fields in there.

     

    Let’s uncomment my [DataMember] attributes and see if that helps

     

        [Serializable]

        [DataContract]

        public class MyData

        {

            [DataMember]

            public MySubData1 Field1;

            [DataMember]

            public MySubData2 Field2;

        }

        [Serializable]

        [DataContract]

        public class MySubData1

        {

            [DataMember]

            public int X;

        }

        [Serializable]

        [DataContract]

        public class MySubData2

        {

            [DataMember]

            public int Z;

        }

     

    Why yes, it does work (it puts it in two different pages of schema):

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

    - <xs:schema elementFormDefault="qualified" targetNamespace="http://www.jamespeckham.com/2009/05/MCTS" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://www.jamespeckham.com/2009/05/MCTS">

      <xs:import schemaLocation="http://localhost:52251/Service1.svc?xsd=xsd2" namespace="http://schemas.datacontract.org/2004/07/OTASample.Vehicles.Service" />

    - <xs:element name="MyOperation">

    - <xs:complexType>

    - <xs:sequence>

      <xs:element minOccurs="0" name="MyRequestObject" nillable="true" type="q1:MyData" xmlns:q1="http://schemas.datacontract.org/2004/07/OTASample.Vehicles.Service" />

      </xs:sequence>

      </xs:complexType>

      </xs:element>

    - <xs:element name="MyOperationResponse">

    - <xs:complexType>

    - <xs:sequence>

      <xs:element minOccurs="0" name="MyOperationResult" nillable="true" type="q2:MyData" xmlns:q2="http://schemas.datacontract.org/2004/07/OTASample.Vehicles.Service" />

      </xs:sequence>

      </xs:complexType>

      </xs:element>

      </xs:schema>

     

    AND

     

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

    - <xs:schema elementFormDefault="qualified" targetNamespace="http://schemas.datacontract.org/2004/07/OTASample.Vehicles.Service" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://schemas.datacontract.org/2004/07/OTASample.Vehicles.Service">

    - <xs:complexType name="MyData">

    - <xs:sequence>

      <xs:element minOccurs="0" name="Field1" nillable="true" type="tns:MySubData1" />

      <xs:element minOccurs="0" name="Field2" nillable="true" type="tns:MySubData2" />

      </xs:sequence>

      </xs:complexType>

      <xs:element name="MyData" nillable="true" type="tns:MyData" />

    - <xs:complexType name="MySubData1">

    - <xs:sequence>

      <xs:element minOccurs="0" name="X" type="xs:int" />

      </xs:sequence>

      </xs:complexType>

      <xs:element name="MySubData1" nillable="true" type="tns:MySubData1" />

    - <xs:complexType name="MySubData2">

    - <xs:sequence>

      <xs:element minOccurs="0" name="Z" type="xs:int" />

      </xs:sequence>

      </xs:complexType>

      <xs:element name="MySubData2" nillable="true" type="tns:MySubData2" />

      </xs:schema>

     

    As you can see adding a DataMember Attribute brings in the Field that you want in the schema when using the DataContractFormat and the XmlIgnore Attribute would thusly exclude anything you did not want in your schema when using the XmlSerializerFormatAttribute.

     

    I hope this helps you do some more controlled schema writing using WCF.

    Full story

    Comments (4)

  • Internet Explorer 7 hangs indefinitely

    So I saw this awesome issue where IE 7 hangs indefinitely and stops responding on the third request for a page. Yes the 3rd request.

    Basically IE7 is limited to 2 active connections per server inside one browser window (including all tabs) and these connections were being wasted in unresponsive requests for favicon.ico.

     

    Here's what I learned. 

    At the time I did not know that IE browsers attempt to retrieve favicon.ico from ther root of your website every time they make a page request. (How to add a favicon to your website)

    Also, I did not know that this generated a 404 error in the IIS log every single time they tried to retrieve it unsuccessfully.

    Also, I did not know that some web application firewalls (firewalls that constantly learn and update themselves to prevent security breaches) will actually stop responding to requests that are consistently turning up 404 as a safety measure.

    Columnist Ivan Ristic comments on web security "The point is that you are not looking for a single suspicious action any more - you are using counters to look for anomalies. Other examples include looking for IP addresses with too many failed requests (too many 404 responses typically point to web application scanner activity), enforcing session inactivity timeouts, session duration timeouts, and so on."

    Lastly, and the final piece of the puzzle. I did not know that:

    Internet Explorer 7 (IE7) has an extremely long time out for requesting favicon.ico. ("a hex with a lot of F's" said the Microsoft Support Engineer)

     

     

    Full story

    Comments (0)

  • Playing Music and Sound in Managed DirectX

    //Here's the code, pretty straightforward

    //Download this Project in Visual Studio 2008 Format

    //download and install the directx SDK

    using System;

    using System.Windows.Forms;

    using Microsoft.DirectX.AudioVideoPlayback;

    using Microsoft.DirectX.DirectSound;

     

    namespace MusicAndSound

    {

        public partial class Form1 : Form

        {

            private Audio musicAudio;

     

            public Form1()

            {

                InitializeComponent();

            }

     

            private void btnBrowseMusic_Click(object sender, EventArgs e)

            {

                GrabFileNameIntoTextBox(txtMusicFileName,"Music (*.mp3) |*.mp3|All Files (*.*) |*.*");

            }

     

            private void GrabFileNameIntoTextBox(TextBox box, string filter)

            {

                FileDialog dialog = new OpenFileDialog();

                dialog.Filter = filter;

                DialogResult result = dialog.ShowDialog();

                if (result == DialogResult.OK)

                {

                    box.Text = dialog.FileName;

                }

            }

     

            private void btnBrowseSound_Click(object sender, EventArgs e)

            {

                GrabFileNameIntoTextBox(txtSoundFileName,"Sound (*.wav) |*.wav|All Files (*.*) |*.*");

            }

     

            private void btnPlayMusic_Click(object sender, EventArgs e)

            {

                if (MusicIsStopped())

                {

                    PlayMusic(txtMusicFileName.Text);

                }

                else

                {

                    StopMusic();

                }

            }

     

            private void StopMusic()

            {

                musicAudio.Stop();

                musicAudio.Dispose();

                musicAudio = null;

                btnPlayMusic.Text = "Play Music";

            }

     

            private void PlayMusic(string songFile)

            {

                musicAudio = new Audio(songFile, true);

                //loop it

                musicAudio.Ending += ReplayMusic;

                btnPlayMusic.Text = "Stop Music";

            }

     

            private bool MusicIsStopped()

            {

                return btnPlayMusic.Text == "Play Music";

            }

     

            private void ReplayMusic(object sender, EventArgs e)

            {

                //makes it keep looping.

                musicAudio.Stop();

                musicAudio.Play();

            }

     

            private void btnPlaySound_Click(object sender, EventArgs e)

            {

                try

                {

                    PlaySound(txtSoundFileName.Text);

                }

                catch (ArgumentException)

                {

                    MessageBox.Show("Invalid Sound File format. Try a wav file for example");

                }

            }

     

            private void PlaySound(string soundFile)

            {

                var soundDevice = new Device();

                soundDevice.SetCooperativeLevel(this, CooperativeLevel.Normal);

                var buffer = new SecondaryBuffer(soundFile, soundDevice);

                buffer.Play(0, BufferPlayFlags.Default);

            }

        }

    }

     

     

     

     

     

     

     

     

     

     

     

     

     

    Full story

    Comments (0)

  • Building A Culture of Responsibility

    When you can't find your keys in the morning, is your first reaction to yell "Honey, where'd you put my keys?" When you're late for work after not being able to find your keys for 20-30minutes do you give the excuse "Sorry, I couldn't find my keys" or do you lie and say "Man, traffic was such a bear!"

    Inspect yourself and watch your teammates for this type of behavior as it is a sign that they lack responsibility. Responsibility is a pillar of great teams because responsibility builds trust and accountability. When individuals are responsible for their actions no matter the outcome then you can start to trust eachother better and improve.

    The key to this mature responsible thinking is remembering it is OK to make mistakes. No, it is GOOD to make mistakes. Without mistakes, we learn nothing. Unfortunately, some organizations have built so much culture and process around eliminating mistakes that they cease to function on a level that encourages learning or growth!

    There's a type of procrastination that may be familiar to many of us. It's basically procrastination through perfectionism. Effectively, this means that a perfectionist is so afraid of making a mistake that they put off doing anything until the have a proper plan or maybe the put it off completely and never get around to it. "Oh why bother, i wouldn't be able to do it the _right_ way, so why do it at all?"

    Now which feels better, letting people know you made a mistake? or some random guy mentioning your mistake at a meeting in front of everyone when you were trying so hard to cover it up?

    Go out, try hard, and if you make a mistake, let everyone why you made the mistake and how you learned from it and they will learn from it then too. Enjoy your mistakes because you learned something you didn't know before!

    One thing that I try to work into conversations about our daily scrums is that, impediments are not someone's fault. They just are what they are and we need to create a solution! This culture has to start by setting a good example, so don't punish people for making mistakes. Congratulate them! For they just saved you a hard lesson.

     

    Responsibility Process Model

     

     

    Full story

    Comments (0)

  • Tips for Recruiters

    Here's the standard pitch that I hear from recruiters who are 'phoning it in to work'

    "Hey, I have this exciting opportunity and I really want to talk to you about it, please give me a call and I'll go over it."

    Translation.

    "Hey, I stumbled across you while googling and I have no idea if you'll fit anything I have but I want you to call me because that shows you are looking."

    Failure. You're only going to get lame candidates who are seeking for a way out of their current job.

     

    Here's another one that i get since i have "agile coach" on my resume.

    "This company is looking for someone to do agile software development."

    Translation.

    "This company doesn't do agile, but they want to be buzzword compliant so if they hire you they can say they're agile."

    Failure. Agile software is a team thing and must be supported by the business units who want the software.

     

    This one is the absolute worst.

    "Looking for project manager for 6 month project."

    Translation

    "Looking for a scape goat to blame this failing project on because we're 9 months behind and over budget but it just won't die."

    Failure. Don't let the client fool you on this. You want to bring good candidates to good companies, not ruin your reputation.

     

    So here's what I suggest for technical recruiters.

    1. Showing that you're not trying to find the right candidate for the right job by spamming out randomly at people who fit the general buzzwordiness of the job description only makes it readily apparent that you care nothing about the candidate but only the placement.
    2. Learn the lingo beyond just the buzzword. Understand the buzzwords and why people are spouting them off.
    3. Understand your client and why they're hiring the position because good candidates are going to ask and you don't want to look like a moron saying "Huh? Well I don't know why they have this open position. I guess I am wasting your time."

    Bottom line, if you care about your candidates more than you care about your clients then you will build lasting networks that you can re-use. Good candidates placed into good career opportunities become great clients eventually.

    Full story

    Comments (0)

  • Exception Handling in .Net

    There's two topics I want to talk about.

    The Overly broad catch and Wrapping APIs that don't use Exceptions. (Such as some websphere/java services I've been working with lately)

     

    It’s a pandemic in most of the code I look at where I work. Nothing against the developers I work with. We inherited this code and we’ve been copying and pasting our way to glory because “if it works don’t fix it”

     

    I got into this all-time religious war with one of my co workers today because he was catching System.Exception and returning false within a method. I asked why, and he said because he wanted to make sure to return false if anything failed.

     

    This article would have helped me explain better why you shouldn’t catch system.exception

     

    The basic premise is that when you catch System.Exception you’re catching everything that could possibly happen. So when your program doesn’t work the way you expect it should, you have to go deep diving into the debugger to find out what is getting caught in the exception handler (or log every single exception that gets to there in some giant log file that becomes a dumping ground for random BS and garbage)

     

    So the other topic. Wrapping code that doesn't throw exceptions.

    How many times have you seen code like this:

     

    Int returnCode = Foo(out myparam1, out param2);

    If(returncode != 0)

    {

                //do stuff

    }

    Else if(returncode == 3)

    {

                //do other stuff

    }

    Else

    {

                //an error happened, log stuff and exit.

    }

     

    YUCK! J

     

    Ideally you’d want something like this

    Try

    {

                Foo(out myParam1, out myParam2);

                //do stuff

    }

    Catch(Exception3 ex)

    {

       //do other stuff

    }

    //all other errors bubble up to the main program.

     

    So anyhow, how do we get to something like this if we have an API that uses error codes?

     

    Just wrap it and throw exceptions. Preferably custom exceptions that are descriptive (unlike mine that are named genericly for example purposes)! J

     

    Public void foo(out int param1, out int param2)

    {

                Int code = foo(out param1, out param2);

                If(code != 0) return;

                If(code == 3) throw new MyCustomException(“Code was 3”);

                Else throw new MyCustomGeneralException(“A bad thing happened, error code was: “+code.ToString() );

    }

    Public class MyCustomException : System.Exception{}

    Public class MyCustomGeneralException : System.Exception{}

     

    Anyhow, try this out and see if it helps your code read better and flow smoother.

    Full story

    Comments (0)

  • We Care Ministries launches website

    The website we worked on at Coders 4 Charities officially launched. Much thanks to Cody Inman who put most of the effort into the project from custom css and design to getting hosting provided.

    You can view the site http://wecareministries.org

    I think this is cody's site: http://www.codyinman.net/

    Again thanks to http://coders4charities.org/ for running the event and giving us a way to use our talents to give back to the community. I look forward to the next one and encourage people to hunt down more charities to bring them into the fold.

    Full story

    Comments (0)

  • Revitalizing a technical career

    Jeremy Miller at Code Better gives some advice to developers who are trying to sharpen their saw.

    It's also good advice for anyone wanting to start a career in software development.

    Similiarly to Jeremy, I wonder if other managers feel the same way about concepts/fundamentals and getting involved with open source projects.

    Of course blogs aren't credible so everything Jeremy says is BS, right?

    I think you're smart enough to decide on your own.

     

    What about his comment that makes the suggestion to move on if you're in a moderate engineering company?

    Are you the rockstar at your shop? Would you rather move on than continue to improve and stay the rockstar?

    Is it true that you're only as good as your weakest link?

    Full story

    Comments (0)

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. Next page