10101010101001

0101010101001

Posts Tagged ‘C#

Silverlight IsolatedStorageFile.IncreaseQuotaTo

leave a comment »

I had a lot of troubles using IsolatedStorageFile.IncreaseQuotaTo

Msdn documentation for IsolatedStorageFile.IncreaseQuotaTo states that:
To increase the quota, you must call this method from a user-initiated event, such as in an event handler for a button-click event. When you call the IncreaseQuotaTo method, the common language runtime in Silverlight presents a dialog box for the user to approve the request. If the user declines the request, this method returns false and the quota remains the same size.

Now that seems like half-baked documentation to me since it doesn’t accurately describe what a user-initiated event is, it only gives one example.
After much digging, I did find out what a user initiated event is. Seems that the msdn documentation specifies what a user initiated event in the section related to “events overview“, but there’s no link between documentation of IsolatedStorageFile.IncreaseQuotaTo and Events Overview.
So here goes the definition:

Silverlight user-initiated events include the mouse events (such as MouseLeftButtonDown), and the keyboard events (such as KeyDown). Events of controls that are based on such events (such as Click) are also considered user-initiated.

API calls that require user initiation should be called as soon as possible in an event handler. This is because the Silverlight user initiation concept also requires that the calls occur within a certain time window after the event occurrence. In Silverlight 4, this time window is approximately one second.

User-initiated event restrictions also apply to usages of JavaScript API for Silverlight.

When Silverlight is in full-screen mode, some input events are deliberately limited for security reasons, although this can be mitigated for out-of-browser applications using elevated trust. For more information, see Full-Screen Support.

At first these limitations seemed draconian to me.
Thinking it more about it, I guess Microsoft didn’t want a user to have many tabs open in a browser and then poof: I call automatically IncreaseQuotaTo.
Since the IncreaseQuotaTo is a modal dialog, meaning you can’t navigate to other tabs from it, if the user is now on page google.com, and I show automatically IncreaseQuotaTo, the user might think that google.com is asking for more storage :)). This would be a security breach indeed.

Had they implemented this with a page level dialog, then that would have probably been more easily hacked (worked around). I can already start imagining drawing some evil forged “Silverlight needs to be updated” image over the IncreaseQuotaTo text, hence tricking the user in pressing Yes . Or maybe some other evil scenario.

I was curios though how exactly does silverlight know what a user initiated event is, but after digging through .net framework source code I’ve got to a dead end:

if ((browserService == null) || !browserService.InPrivateMode())
{
    //..
}
return false; //means that IncreaseQuota will fail
where browser.IsInPrivateMode is:

[SecuritySafeCritical]
public bool InPrivateMode()
{
    bool privateMode = false;
    return (NativeMethods.SUCCEEDED(UnsafeNativeMethods.DOM_InPrivateMode(this._browserServiceHandle, out privateMode)) && privateMode);
}

where DOM_InPrivateMode is in a DllImport[“agcore”], which according to microsoft is confidential :(
So it looks like I won’t find out soon how they’re detecting user initiated events, although I’m guessing they have some centralized private method that detects clicks for example, and then probably sets a flag that this was indeed “a user initiated event”, and since you can’t forge clicks or keypresses using javascript and since you can’t call those private methods using reflection, it’s “safe”.

Advertisements

Written by Liviu Trifoi

May 18, 2011 at 6:33 pm

Posted in .NET, C#, Silverlight

Tagged with , , ,

Comparing object properties in C#

leave a comment »

I needed today, in my unit tests, a way to compare two objects of the same type, property by property.
In addition to this I needed the following:

    -If the property is a reference type, then go inside it and compare that too, property by property. (Basically deep object property comparison).
    -If the property is IEnumerable, then compare properties of each element inside the IEnumerable.
    -If the elements inside the IEnumerable are themselves IEnumerable then this could go on many levels deep, but this was not on my requirements.
    -I also want the possibility to ignore certain properties in the comparison, such as property which is a delegate (like the Filter property of the PagedCollectionView framework class).
    And of course I would need to know which properties were not equal, so I could show into my assertions.

Obviously this involves some heavy reflection code which I’m sure it would be fun to write if you had the time.
An alternative is to use a free library, with just one class, that does exactly this: http://comparenetobjects.codeplex.com/
Usage is very simple, and supports all kind of useful features which you can see below:

var compareObjects = new CompareObjects()
            {
                CompareChildren = true, //this turns deep compare one, otherwise it's shallow
                CompareFields = false,
                CompareReadOnly = true,
                ComparePrivateFields = false,
                ComparePrivateProperties = false,
                CompareProperties = true,
                MaxDifferences = 1,
                ElementsToIgnore = new List<string>() { "Filter" }
            };
                                                                            
            bool areEqual = compareObjects.Compare(objectA, objectB);
            Assert.IsTrue(areEqual, compareObjects.DifferencesString); //DifferencesString contains exactly what property and what value(s) was different

For Silverlight you do have to remove a couple of line of codes from it, related to DataTable comparison, which don’t exist in silverlight, but it’s easy and only takes a couple of minutes.

Happy Deep Object Comparisons :)

Written by Liviu Trifoi

April 28, 2011 at 6:20 pm

Silverlight stack trace line numbers

with 8 comments

As you probably know, to have stack traces line numbers in a .net app you need pdb files.
In Silverlight though, pdb files don’t get included in the XAP. Even if it was possible to include them you probably wouldn’t want them there because they tend to be huge and you want to have a fast loading web-site.

So what will you do when your client calls you and says he received an error message like the one below?
NullReferenceException
at ChaptersView.ChaptersTree_OnMouseMove
at ChaptersView.GetPreviousCommandButton

After I had a look today at the answer to this question, it became obvious:

Step 1)
In the place you now log or show exceptions to the user, you stop writing a normal stack trace using exception.ToString() or exception.StackTrace.
You should write a stacktrace that includes IL offsets using the code below:

...
catch (Exception exception)
{
            string errorDescription = string.Empty;
            try
            {
                StackTrace st = new System.Diagnostics.StackTrace(ex);
                string stackTrace = "";

                if (st != null)
                {
                    foreach (StackFrame frame in st.GetFrames())
                    {
                        stackTrace = "at " + frame.GetMethod().Module.Name + "." + frame.GetMethod().ReflectedType.Name +
                                     "." + frame.GetMethod().Name + "  (IL offset: 0x" +
                                     frame.GetILOffset().ToString("x") + ")\n" + stackTrace;
                    }
                }
                errorDescription = stackTrace;
            } catch //sometimes there are no stackframes, just use ex.ToString() in those cases
            {
                errorDescription = ex.ToString();
            }
            //do something with error description, like show it to the user or send it to your log server  
}

If we pass the exception that generated the stacktrace in our first example, it will look like:

NullReferenceException
at ChaptersView.ChaptersTree_OnMouseMove (IL offset: 0x44)
at ChaptersView.GetPreviousCommandButton (IL offset: 0x28)

Step 2: Client sends you an exception/log that includes IL offsets
You can use Reflector or IL Disassembler (which comes with visual studio) to find out the piece of code that generated the exception.
I prefer IL Disassembler because Reflector will only show you IL code from those IL offsets, and there’s a large chance you don’t read IL as well as you read C#.

So you have to perform the following steps:
1) Go to start menu and start IL Disassembler
2) Inside IL Disassembler go to File->Open and load the dll (not the XAP) where the exception was thrown. (e.g. …\Release\Client.dll)
3) Go to View->Show source lines
4) Now navigate to the last method that appears in the stacktrace and we look after the IL offset from the stacktrace.
In our example above this is ChaptersView.GetPreviousCommandButton and has offset 0x28

Inside IL Disassembler we will see a mix of C# code and corresponding IL code:

  IL_001c:  brtrue.s   IL_0029
//000193:             {
//000194:                 throw new NullReferenceException(“Test Exception”);
  IL_001e:  ldstr      "Test Exception"
  IL_0023:  newobj     instance void [mscorlib]System.Exception::.ctor(string)
  IL_0028:  throw
//000195:             }
//000196:
//000197:             var previousCommandButton =
 

As you can see, at IL_0028 there’s the instruction that caused the exception.
This is IL code, but because we’ve checked “View->Show source lines” we also get the corresponding C# code just a few lines above.

//000193: {
//000194: throw new NullReferenceException();

So, in this case the exception was thrown because I’ve thrown it explicitly in order to show how IL offsets and IL Disassembler can be used to get an alternative to stack trace line numbers in silverlight.

Also please don’t just put that piece of code in every catch block. Create a method like “string GetStackTraceFromException(Exception ex)”
Another good idea would be to have some centralized error service, on the server side. You would then send those exception descriptions automatically along with method parameter values logged with PostSharp, whenever an error happens.
So by the time the client calls you, you have fixed the problem and he’s impressed ;)

Happy Debugging.

Written by Liviu Trifoi

April 21, 2011 at 6:15 pm

C# Fluent Interface with Type Safe Polymorphic Chain Calls

with 2 comments

Presuming you already know what fluent interfaces are I’ll skip to a certain case that caused me troubles:

Let’s say you have two Order classes: NormalOrder and SpecialOrder. Both of them inherit a base Order class. fluent_interfaces_order_class_hierarchy

I wanted to built a fluent interface for unit testing them so that I could say something like:

New.DefaultNormalOrder.AddItem(10).AddFreeShipping()   
.....
New.DefaultSpecialOrder.AddItem(15).AddLargeSpecialTaxes();

I thought it would be easy, just use the a builder pattern or extension methods in C#.
But there’s a big inconvenience with both of them that I’ll illustrate below:

Builder Problem:

    public class OrderBuilder
    {
        private Order o = new Order();

        public virtual OrderBuilder AddItem(int item)
        {
            o.AddItem(item);
            return this;
        }
    }

    public class NormalOrderBuilder : OrderBuilder
    {
        private NormalOrder no = new NormalOrder();

        public NormalOrderBuilder AddFreeShipping()
        {
            no.ShippingCost = 0;
            return this;
        }
    }

    public class SpecialOrderBuilder : OrderBuilder
    {
        private SpecialOrder so = new SpecialOrder();

        public SpecialOrderBuilder AddLargeSpecialTaxes()
        {
            so.SpecialTaxes = Int32.MaxValue;
            return this;
        }
    }

Can you spot the problem presuming that the New.DefaultNormalOrder returns a NormalOrderBuilder and that New.DefaultSpecialOrder returns a SpecialOrderBuilder?
Here it is if you try to write a small example using those builders:

//This works
New.DefaultNormalOrder.AddFreeShipping().AddItem(10);  
//This doesn't
New.DefaultNormalOrder.AddItem(10).AddFreeShipping();  

This is because AddItem is polymorphic and returns the base class OrderBuilder. Even though New.DefaultNormalOrder.AddItem(10) is actually a NormalOrderBuilder at runtime, you can’t call AddFreeShipping() because Include item returns the base OrderBuilder class breaking our chain calls :(

The same problem happens when using extension methods.

One solution would be to leave all the chain calls to the base class at the end, but that doesn’t solve the problem because there might be times when we really need to call the methods from the base class first.
Another solution would be to cast, but those won’t be fluent interfaces in my opinion :(
The fluency is gone when you have to put ugly paranthesis and casts where there’s no real need for them.
Of course you may say that all I need is override the AddItem method, call the base.AddItem and do a cast on to the NormalOrderBuilder class on the result:

    public class NormalOrderBuilder : OrderBuilder
    {
.....

        public override NormalOrderBuilder AddItem(int item)
        {
            return (NormalOrderBuilder)base.AddItem(item);
        }
    }

But this doesn’t scale well because if you have lots of methods in the base OrderBuilder class you’ll have to do this casting for all of them in all your inheritors. OK, maybe this is an exaggeration, but you’ve got to admit it’s plumbing code :)
The only solution that I’ve found is to use a combination of the Builder pattern with generics and extension methods with generics:

    public class OrderBuilder<T> where T:Order
    {
        protected internal T order = default(T);

        public OrderBuilder(T o)
        {
            order = o;
        }

        public OrderBuilder AddItem(int item)
        {
            order.AddItem(item);
            return this;
        }
    }


    public static class OrderBuilderExtensionMethods
    {
        public static OrderBuilder<T> AddFreeShipping<T>(this OrderBuilder<T> ob) where T:NormalOrder
        {
            ((NormalOrder) ob.order).ShippingCost = 0;
            return ob;
        }

        public static OrderBuilder<T> AddLargeSpecialTaxes<T>(this OrderBuilder<T> ob) where T:SpecialOrder
        {
            ((SpecialOrder) ob.order).SpecialTaxes = Int32.MaxValue;
            return ob;
        }
    }

    public class New
    {
        public static OrderBuilder<NormalOrder> DefaultNormalOrder = new OrderBuilder<NormalOrder>(new NormalOrder());
        public static OrderBuilder<SpecialOrder> DefaultSpecialOrder = new OrderBuilder<SpecialOrder>(new SpecialOrder());
    }

The compiler will enforce the constraints we specified at compile time like: “where T:NormalOrder”, so here goes the example again:

//This works
New.DefaultNormalOrder.AddFreeShipping().AddItem(10);  
//This works :D
New.DefaultNormalOrder.AddItem(10).AddFreeShipping();  
//This doesn't, the compiler screams in pain because of the generic constraints :)
New.DefaultSpecialOrder.AddItem(10).AddFreeShipping();

This is cool, because now our call chain doesn’t break and it’s type safe so we can’t make invalid call chains :D

In the end though, I’m pretty sure I wouldn’t recommend this approach because code is less readable, but it was a good exercise for generic extension methods with generic constraints.

Written by Liviu Trifoi

February 16, 2009 at 1:56 pm

xsl number format localization

leave a comment »

These days I’ve had to do some xslt stylesheets that are processed by ibex pdf creator.
One of the things that I found little information on was how to format a number based on current regional settings of the user.
Example: I have the decimal number 1234.56.
What I want is that if the current regional settings point to English (US) culture then display 1,234.56 and if the current regional settings point to some other culture, let’s say Romanian culture, then display 1.234,56

Approach 1) – That doesn’t work.
Initially I thought I could use the built-in format-number function to format numbers like this:

  <xsl:decimal-format name="en-US" decimal-separator="." grouping-separator="," />
  <xsl:decimal-format name="ro-RO" decimal-separator="," grouping-separator=" " />
....
  <xsl:variable name="df" select="//NumberDecimalSeparator/."></xsl:variable>
...
 <xsl:value-of select='format-number(1234.56, "###,##0.00",$df)' />

I would only have to serialize from the calling program an element called NumberDecimalSeparator that would contain the correct format name.
But the xslt decimal format cannot be dynamic and the xslt processor complains about it :(
So this approach is no use.

Approach 2) – Works but it’s ugly

You can have a static decimal format and modify it from the calling program just before calling your xslt processor.
In my case before calling ibex from C# I had to modify the following xml called ‘DecimalSeparators.xsl’:

 <?xml version="1.0" ?>
 <xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

   <xsl:decimal-format name="i" decimal-separator="." grouping-separator="," />
  </xsl:stylesheet>

And our initial xsl looks like this.

  <xsl:include href="DecimalSeparators.xsl"/>
  <xsl:variable name="ts" select="//NumberGroupSeparator/."></xsl:variable>
  <xsl:variable name="ds" select="//NumberDecimalSeparator/."></xsl:variable>

  <xsl:value-of select="format-number(1234.56, concat('###',$ts,'##0',$ds,'00'),'i')" />

So because we’re modifying the DecimalSeparators.xsl before runtime with the correct separators and because we’re also inserting the correct separators in the input xml everything will be just fine.

And you could use this piece of code to modify DecimalSeparators.xsl from C#

        private static XmlNamespaceManager CreateNsMgr(XmlDocument doc)
        {
            XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
            foreach (XmlAttribute attr in doc.SelectSingleNode("/*").Attributes)
                if (attr.Prefix == "xmlns") nsmgr.AddNamespace(attr.LocalName, attr.Value);
            return nsmgr;
        }

        public void GenerateCultureSpecificDecimalFormats()
        {
            string numberGroupSeparator = System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberGroupSeparator;
            string numberDecimalSeparator = System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;

            XmlDocument doc = new XmlDocument();
            doc.Load("DecimalFormats.xsl");
            XmlElement node = (XmlElement)doc.SelectSingleNode("//xsl:decimal-format", CreateNsMgr(doc));
            node.SetAttribute("name", "i");
            node.SetAttribute("decimal-separator", numberDecimalSeparator);
            node.SetAttribute("grouping-separator", numberGroupSeparator);
            XmlTextWriter writer = new XmlTextWriter("DecimalFormats.xsl", null);
            doc.WriteTo(writer);
            writer.Close();
        }

But it’s a very ugly solution.

So here goes
Approach 3) Elegant.

You can write a custom .net function and call it from the xsl using the extension-objects mechanism provided by xsl.

Here’s the .net class that has that custom function:

    /// <summary>
    /// Provides number formatting methods used by an xslt processor at runtime.
    /// </summary>
    public class XsltNumberFormatter
    {

        /// <summary>
        /// Formats provided number using a culture specific transformation of the provided format
        /// as the format.
        /// </summary>
        ///
<param name="numberFormat">The number format in the en-US culture.</param>
        ///
<param name="strNumber">The decimal number as string.</param>
        /// <returns>
        /// Formatted <see cref="strNumber"/> using a culture specific transformation of <see cref="numberFormat"/>
        /// as the format.
        /// If
<paramref name="strNumber"/> is invalid it returns <see cref="Properties.Resources.NaN"/>
        /// </returns>
        /// <example>
        /// FormatNumber('1234.56','###,##0.00')
        /// will return 1,234.56 if the current culture is en-US or 1.234,56 if the current culture is ro-RO
        /// </example>
        public string FormatNumber(string strNumber, string numberFormat)
        {
            try
            {
                string stringDotFormatArg = "{0:" + numberFormat + "}";
                decimal number = Decimal.Parse(strNumber, new CultureInfo("en-US").NumberFormat);
                string result = String.Format(stringDotFormatArg, number);

                return result;
            }
            catch (Exception ex)
            {
                return "NaN";
            }

        }

    }

You would plug it into ibex xslt processor using this .net code:

using System;
using System.IO;
using System.Collections;

using ibex4;


public class test {

   static void Main( string[] args ) {

        FODocument doc = new FODocument();

        FileStream xml = new FileStream( "exslt.xml", FileMode.Open, FileAccess.Read );
        FileStream xsl = new FileStream( "exslt.xsl", FileMode.Open, FileAccess.Read );
        FileStream pdf = new FileStream( "exslt.pdf", FileMode.Create, FileAccess.Write );

        Hashtable xslArgs = new Hashtable();

        xslArgs.Add("http://www.yourcompany.com/numbers", new XsltNumberFormatter());

        doc.generate( xml, xsl, pdf, true, xslArgs );
   }

}

All what is left is to call it from your xsl file :)

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

<xsl:stylesheet version="2.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
	xmlns:fo="http://www.w3.org/1999/XSL/Format"
	xmlns:ibex="http://www.xmlpdf.com/2003/ibex/Format"
        xmlns:my-num="http://www.yourcompany.com/numbers"  exclude-result-prefixes="my-num">

        <xsl:value-of select="my-num:FormatNumber('1234.56','###,###,##0.00')"/>

</xsl:stylesheet>

So now whenever you need to format something you just specify it’s format using en-US culture formats in your xsl (with ‘,’ ‘.’ as separators) and everything will be translated into the current culture format by our custom FormatNumber function.

Enjoy! :)

Written by Liviu Trifoi

February 11, 2009 at 4:49 pm