Scott Wojan

DotRant BLOG
posts - 21 , comments - 72 , trackbacks - 5

Monday, May 20, 2013

Capturing HTTP traffic on an iPhone with Fiddler

This is a simple update to the great entry at http://conceptdev.blogspot.com/2009/01/monitoring-iphone-web-traffic-with.html with the new Fiddler interface.


1. Get Fiddler
Download Fiddler 

2. Set-up Fiddler
Start Fiddler then open the Tools > Fiddler Options... window


and in the Connections tab, ensure:

  • "Allow remote computers to connect" is checked.
  • "Act as system proxy on startup" is checked.
  • Note or change what port is set (eg. 8888).




Once you've saved those settings you need to stop and re-start Fiddler.

3. Ensure Fiddler is 'listening'
Once Fiddler has re-started, verify that the Capture Traffic menuitem is ticked.


4. Check the 'listening' IP
You need to know your computer's wireless-network IP address to configure the iPhone. This screenshots shows the Command Prompt > ipconfig output:


5. Set-up iPhone Settings
With the computer IP address and Fiddler port, go to your iPhone's Wifi Settings and scroll down to the HTTP Proxy, choose Manual and input the Fiddler proxy info:

(remember to switch back to Off when you're done)

6. 'sniff' away
If everything has been setup right, anything you do in Safari or other internet based applications will be logged in the Fiddler window.


It's extremely useful for testing/debugging - have fun!

Don't forget to UNDO the iPhone settings when you're finished!!

Posted On Monday, May 20, 2013 9:26 AM | Comments (0) | Filed Under [ fiddler iphone http proxy ]

Wednesday, March 13, 2013

ASP.NET MVC Helper Method for Enums... supports override of text using System.ComponentModel.DescriptionAttribute

public static MvcHtmlString DropDownListFromEnumFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression, object htmlAttribute = null)

{

    var type = typeof (TProperty);

    var addBlank = false;

    if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))

    {

        type = type.GetGenericArguments()[0];

        addBlank = true;

    }

    var values = (from f in type.GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static)

                                    let attribute = f.GetCustomAttributes(typeof(System.ComponentModel.DescriptionAttribute), true).FirstOrDefault() as System.ComponentModel.DescriptionAttribute

                                    select new

                                    {

                                        Text = attribute == null ? f.Name : attribute.Description,

                                        Value = f.Name

                                    }).ToList();

    if (addBlank)

        values.Insert(0, new {Text = String.Empty, Value = String.Empty});

 

    return helper.DropDownListFor(expression,new SelectList(values, "Value", "Text"), htmlAttribute);

}

 

Will take…

public enum Salutation

{

    [Description("Mr.")]

    Mr = 100,

    [Description("Mr.")]

    Ms = 101,

    [Description("Mrs.")]

    Mrs = 102,

    [Description("Miss")]

    Miss = 103

}

And convert it to…

<select id="Suffix" name="Suffix">

  <option value="Junior">Junior</option>

  <option value="Senior">Senior</option>

  <option value="First">First</option>

  <option value="Second">Second</option>

  <option value="Third">Third</option>

  <option value="Fourth">Fourth</option>

  <option value="Fifth">Fifth</option>

</select>

Or if it’s a nullable property…

<select id="Suffix" name="Suffix">

  <option value=""></option>

  <option value="Junior">Junior</option>

  <option value="Senior">Senior</option>

  <option value="First">First</option>

  <option value="Second">Second</option>

  <option value="Third">Third</option>

  <option value="Fourth">Fourth</option>

  <option value="Fifth">Fifth</option>

</select>

 

 

Posted On Wednesday, March 13, 2013 5:07 PM | Comments (0) |

Thursday, May 17, 2012

Enum helper for values specified in attributes

I've used this enum helper from time to time to get an enum value from attributes such as Description and XmlEnumAttribute. Maybe you can find it useful?

    public static class EnumEx

    {

        public static T GetXmlEnumValue<T>(string name)

        {

            var type = CheckEnum<T>();

 

            var val = (from f in type.GetFields()

                       let attribute = f.GetCustomAttributes(typeof(System.Xml.Serialization.XmlEnumAttribute), true).FirstOrDefault() as System.Xml.Serialization.XmlEnumAttribute

                       where attribute != null

                          && attribute.Name == name

                       select (T)f.GetValue(null));

 

            if (val.Count() == 0)

                throw new ArgumentException(string.Format("{0} is not a valid XmlEnumAttribute for {1}", name, typeof(T).FullName), "name");

 

            return val.First();

        }

 

        public static T GetValueFromDescription<T>(string description)

        {

            var type = CheckEnum<T>();

 

            var val = (from f in type.GetFields()

                       let attribute = f.GetCustomAttributes(typeof(System.ComponentModel.DescriptionAttribute), true).FirstOrDefault() as System.ComponentModel.DescriptionAttribute

                       where attribute != null

                          && attribute.Description == description

                       select (T)f.GetValue(null));

 

            if (val.Count() == 0)

                throw new ArgumentException(string.Format("{0} is not a valid description for {1}", description, typeof(T).FullName), "description");

 

            return val.First();

        }

 

        private static Type CheckEnum<T>()

        {

            var type = typeof(T);

            if (type.IsEnum == false)

                throw new InvalidOperationException(string.Format("{0} is not an enum", typeof(T)));

            return type;

        }

    }

 

Posted On Thursday, May 17, 2012 4:06 PM | Comments (0) |

Wednesday, May 18, 2011

Extension Methods for ToXml and FromXml

Extension Methods for ToXml and FromXml

Posted On Wednesday, May 18, 2011 11:47 AM | Comments (0) |

Friday, December 10, 2010

An open plea to Microsoft to fix the serializers in WCF.

I simply DO NOT understand how Microsoft can be this far along with a tool like WCF and it STILL tout it as being an "Enterprise" tool.

For example... The following is a simple xsd schema with a VERY simple data contract that any enterprise would expect an "enterprise system" to be able to handle:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="Sample"
    targetNamespace="http://tempuri.org/Sample.xsd"
    elementFormDefault="qualified"
    xmlns="http://tempuri.org/Sample.xsd"
    xmlns:mstns="http://tempuri.org/Sample.xsd"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">
 
 <xs:element name="SomeDataElement">
    <xs:annotation>
      <xs:documentation>This documents the data element. This sure would be nice for consumers to see!</xs:documentation>
    </xs:annotation>
    <xs:complexType>
      <xs:all>
        <xs:element name="Description" minOccurs="0">
          <xs:simpleType>
            <xs:restriction base="xs:string">
              <xs:minLength value="0"/>
              <xs:maxLength value="255"/>
            </xs:restriction>
          </xs:simpleType>
        </xs:element>
      </xs:all>
      <xs:attribute name="IPAddress" use="required">
        <xs:annotation>
          <xs:documentation>Another explanation!  WOW!</xs:documentation>
        </xs:annotation>
        <xs:simpleType>
          <xs:restriction base="xs:string">
            <xs:pattern value="(([1-9]?[0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([1-9]?[0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])"/>
          </xs:restriction>
        </xs:simpleType>
      </xs:attribute>
    </xs:complexType>
 </xs:element>
 
</xs:schema> 

An minimal example xml document would be:

<?xml version="1.0"encoding="utf-8" ?>
<SomeDataElementxmlns="http://tempuri.org/Sample.xsd" IPAddress="1.1.168.10">
</SomeDataElement>

With the max example being: 

<?xml version="1.0"encoding="utf-8" ?>
<SomeDataElementxmlns="http://tempuri.org/Sample.xsd" IPAddress="1.1.168.10">
 <Description>ddd</Description>
</SomeDataElement>

This schema simply CANNOT be exposed by WCF. 

Let's list why: 

  1. svcutil.exe will not generate classes for you because it can't read an xsd with xs:annotation.
  2. Even if you remove the documentation, the DataContractSerializer DOES NOT support attributes so IPAddress would become an element this not meeting the contract
  3. xsd.exe could generate classes but it is a very legacy tool, generates legacy code, and you still suffer from the following issues:
  4. NONE of the serializers support emitting of the xs:annotation documentation.  You'd think a consumer would really like to have as much documentation as possible!
  5. NONE of the serializers support the enforcement of xs:restriction so you can forget about the xs:minLength, xs:maxLength, or xs:pattern enforcement.

Microsoft... please, please, please, please look at putting the work into your serializers so that they support the very basics of designing enterprise data contracts!!

 

Posted On Friday, December 10, 2010 12:40 PM | Comments (0) |

Wednesday, September 8, 2010

Multithreaded queue with exception handling and progress reporting

Below is a multithreaded queue with progress reporting and nice exception handling that I implemented for a project. I hope it might help someone else. You can copy and paste the following code into a console app to see how to use it.
 
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Threading;
 
namespace WorkQueueTest
{
    class Program
    {
        static readonly object locker = new object();
        static void Main(string[] args)
        {
            //You can play with these values to test
            var workQueueSettings = new {NumberOfTasks = 6, NumberOfTaskSteps = 3, TaskStepSleepTime = 500, NumberOfThreads = 3};
            var nonThreadingTime = workQueueSettings.NumberOfTasks * workQueueSettings.NumberOfTaskSteps * workQueueSettings.TaskStepSleepTime;
            Console.WriteLine("====================\nWithout a work queue, this would take {0} milliseconds\n====================", nonThreadingTime);
 
            var workQueue = new WorkQueue(workQueueSettings.NumberOfThreads);
            var stopWatch = new Stopwatch();
            stopWatch.Start();
            for (var i = 0; i < workQueueSettings.NumberOfTasks; i++)
            {
                var index = i;
                workQueue.Enqueue(new WorkItem
                                      {
                                          OnException = OnException,
                                          OnProgressChanged = OnProgressChanged,
                                          Task = onProgressChangedCallBack =>
                                          {
                                              #region - Code to actually do stuff goes here... the rest of this is sample fluff
                                              //
                                              var taskName = "Task #" + index;
                                              //fake some long running process
                                              for (var j = 0; j < workQueueSettings.NumberOfTaskSteps; j++)
                                              {
                                                  Thread.Sleep(workQueueSettings.TaskStepSleepTime);
                                                  var percent = (int)(((decimal)j / workQueueSettings.NumberOfTaskSteps) * 100);
                                                  onProgressChangedCallBack(new ProgressChangedEventArgs(percent, taskName));
                                              }
 
                                              if (workQueueSettings.NumberOfTasks>2 && index == 2)//fake a sample exception
                                                  throw new Exception("Some fake exception.");
 
                                              onProgressChangedCallBack(new ProgressChangedEventArgs(100, taskName));
                                              #endregion
                                          }
                                             
                                      });
            }
 
            workQueue.WaitForTasksToComplete();//wait for the tasks to complete before continuing
            workQueue.Stop(false);
            stopWatch.Stop();
            Console.WriteLine("====================\nTotal time = {0} milliseconds\n====================\nPress any key to exit", stopWatch.ElapsedMilliseconds);
            Console.ReadLine();
        }
 
        private static void OnException(Exception ex)
        {
            lock (locker)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("EXCEPTION: {0}", ex);
                Console.ResetColor();
            }
        }
 
        private static void OnProgressChanged(ProgressChangedEventArgs eventArgs)
        {
            lock (locker)
            {
                switch (eventArgs.ProgressPercentage)
                {
                    case 0:
                        Console.ForegroundColor = ConsoleColor.Yellow;
                        Console.WriteLine("Starting {0}", eventArgs.UserState);
                        break;
                    case 100:
                        Console.ForegroundColor = ConsoleColor.Green;
                        Console.WriteLine("Completed 100% of {0}", eventArgs.UserState);
                        break;
                    default:
                        Console.WriteLine("Completed {0} of {1}", eventArgs.ProgressPercentage, eventArgs.UserState);
                        break;
                }
                Console.ResetColor();
            }
        }
    }
 
    public class WorkItem
    {
        public virtual Action<Exception> OnException { get; set; }
        public virtual Action<ProgressChangedEventArgs> OnProgressChanged { get; set; }
        public virtual Action<Action<ProgressChangedEventArgs>> Task { get; set; }
    }
 
    public class WorkQueue
    {
        private readonly object locker = new object();
        private readonly Thread[] threads;
        private readonly Queue<WorkItem> queue = new Queue<WorkItem>();
        internal class QueueStopWorkItem : WorkItem{}
 
        public WorkQueue(int workerCount)
        {
            threads = new Thread [workerCount];
 
            // Create and start a separate thread for each worker
            for (var i = 0; i < workerCount; i++)
                (threads [i] = new Thread (RunWorkItem)).Start();
        }
 
        public void Stop (bool waitForWorkersToComplete)
        {
            if (waitForWorkersToComplete == false)
            {
                lock (locker)
                {
                    queue.Clear();
                }
            }
 
            // Enqueue stop worker item for each worker to make each exit.
            for (var i = 0; i < threads.Length; i++)
            {
                Enqueue(new QueueStopWorkItem());
            }
 
            // Wait for threads to finish
            if (waitForWorkersToComplete)
            {
                for (var i = 0; i < threads.Length; i++)
                {
                    threads[i].Join();
                }
            }
        }
 
        public void Enqueue (WorkItem workItem)
        {
            lock (locker)
            {
                queue.Enqueue(workItem); //Push one element into the queue.
                Monitor.Pulse(locker);   //Release the waiting thread
            }
        }
 
        void RunWorkItem()
        {
            while (true)// loop until a stop work item is found.
            {
                WorkItem item;
                lock (locker)
                {
                    while (queue.Count == 0)
                        Monitor.Wait(locker); ////Wait, if the queue is busy.
                    item = queue.Dequeue();
                }
 
                if (item is QueueStopWorkItem)
                    return; // Time to exit.
 
                try
                {
                    item.Task(item.OnProgressChanged); // Execute item.
                }
                catch(Exception ex)
                {
                    if (item.OnException != null)
                        item.OnException(ex);
                    else
                        throw;
                }
            }
        }
 
        public void WaitForTasksToComplete()
        {
            Stop(true);
        }
    }
}
 
 
 
The result should look like the following:
 
 

Posted On Wednesday, September 8, 2010 11:46 AM | Comments (0) |

Friday, August 13, 2010

SimpleWcf - WCF 4.0 made easy

I just released a new project on CodePlex called SimpleWcf"

SimpleWcf provides a way to essentially do “simple, configuration-less, file-less, WCF 4.0”. It works by discovering services using reflection and assumes a convention is intended for the namespaces. 

It leverages a lot of the great new baked in defaults in WCF 4.0.

http://simplewcf.codeplex.com/documentation

Posted On Friday, August 13, 2010 10:18 AM | Comments (0) |

Thursday, April 1, 2010

Loading symbols in Visual Studio 2008 Slow

I was fighting with this issue today... Visual Studio was taking FOREVER to load the symbol files (.pdb) in order to start debugging.  It seems if you clear all of your break points, the issue is corrected.  Hope this helps someone.

Posted On Thursday, April 1, 2010 3:32 PM | Comments (7) |

Wednesday, August 19, 2009

Is it cold in here?

Wow, so I just had to install the JRE for a product and was shocked to see the following:

Java... now with Bing?

AND they recommend it!

Hell hath frozen!

 

Posted On Wednesday, August 19, 2009 1:01 PM | Comments (0) |

Wednesday, June 17, 2009

JQuery LightBox Max Height and Width

An extension to JQuery LightBox for max width and height

Posted On Wednesday, June 17, 2009 9:19 AM | Comments (40) |

Thursday, May 28, 2009

Sir... We're not the taco stand...

This hits home also!

 

Posted On Thursday, May 28, 2009 6:35 PM | Comments (1) |

Saturday, May 9, 2009

The Downfall of Agile Hitler...

This had me rolling on the floor.  Hope someone else can appreciate it.

 

Posted On Saturday, May 9, 2009 10:49 AM | Comments (5) |

Wednesday, January 14, 2009

Using PostSharp without installing via the MSI

So, it took me forever today to figure out how to get PostSharp working without installing it 'globally' with the msi installer.

In a nutshell, you have to include a directory for example /lib/ with all of the PostSharp baggage:
  • Default.psproj
  • PostSharp.targets
  • PostSharp-1.0.targets
  • PostSharp-1.0.version
  • PostSharp-AppDomain.config
  • PostSharp-Platform.config
  • PostSharp.Core.dll
  • PostSharp.Core.pdb*
  • PostSharp.Core.XmlSerializers.dll
  • PostSharp.exe
  • PostSharp.exe.config
  • PostSharp.pdb*
  • PostSharp.Laos.dll
  • PostSharp.Laos.pdb*
  • PostSharp.Laos.psplugin
  • PostSharp.Laos.Weaver.dll
  • PostSharp.Laos.Weaver.pdb*
  • PostSharp.MSBuild.dll
  • PostSharp.MSBuild.pdb*
  • PostSharp.Public.dll
  • PostSharp.Public.pdb*

* = Optional

Add a reference to the PostSharp.Laos and PostSharp.Public assemblies in your project.

Then you have to edit your .csproj file around the existing <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> section to be: 
  <PropertyGroup>
    <DontImportPostSharp>True</DontImportPostSharp>
    <PostSharpDirectory>lib\</PostSharpDirectory>
  </PropertyGroup>
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
  <Import Project="$(PostSharpDirectory)PostSharp.targets" />

You can download a working demo: http://rapidshare.com/files/183439996/PostSharpTest.zip.html

Posted On Wednesday, January 14, 2009 8:32 PM | Comments (4) |

Monday, November 10, 2008

Mapping an NCLOB to a String property in NHibernate

So I ran into an issue this evening where I needed to map a string property to a NCLOB column but I kept getting:

"ORA-01461: can bind a LONG value only for insert into a LONG column"

Turns out that you should set the column type to "AnsiString" as in:

<property name="Contents" column="CONTENTS" type="AnsiString"/>

 

- Hope this helps someone else out.

Posted On Monday, November 10, 2008 7:32 PM | Comments (7) |

Thursday, October 23, 2008

Calling a Static Method on a Generic Class

I needed to be able to call a static method on a generic class today, so I thought I would post it up here to share with the world.  Enjoy.

 //Our Generic Class

public class SomeGenericClass<T>
{
    public static char[] ConvertToCharArray(T something)
    {
        return something.ToString().ToCharArray();
    }
}
The example code:
// Get the type of the generic class
Type typeofClassWithGenericStaticMethod = typeof(SomeGenericClass<>);
 
//Get a typed version of the generic type
Type type = Type.GetType("System.String");
Type[] args = new[] { type };
Type genericType = typeofClassWithGenericStaticMethod.MakeGenericType(args);
 
// Get a reference to the method you want to call.
MethodInfo methodInfo = genericType
    .GetMethod("ConvertToCharArray", System.Reflection.BindingFlags.Static | BindingFlags.Public);
 
// Invoke the method with parameters. (If it doesn't have a pameter, use null instead of the object array)
object returnValue = methodInfo.Invoke(null, new object[]{"Hello World"});
 
char[] characters = (char[])returnValue;
foreach (char character in characters)
{
    Console.Write(character);
}

Posted On Thursday, October 23, 2008 1:55 PM | Comments (0) |

Powered by: