iPhone and iTouch Support For BlogEngine.NET

September 30 2010

BlogEngine.NET does a great job with mobile devices, rendering its content with a default skin whenever it detects a mobile device. Unfortunately, this behavior doesn’t work on the iPhone or iTouch. However, the fix is easy. Simply add iphone and ipod to the BlogEngine.MobileDevices key in web.config, as follows:

<add key="BlogEngine.MobileDevices" value="(iphone|ipod|nokia|sonyericsson|blackberry|samsung|sec\-|windows ce|motorola|mot\-|up.b|midp\-)"/>

Once you’ve done this, the default mobile theme will render on the iPhone and iTouch.

If you are looking for even a prettier theme   I also found the BETouch iPhone theme, which looks great. Simply add the theme to the themes directory and then change the mobile theme to BETouch in admin settings.

I’m now using it for this blog!

image

Windows Phone Developer Tools Hiccup, Links

September 20 2010

Installed the Windows Phone Developer Tools. Then tried to run the emulator and it failed with “Error: Connection failed because of invalid command-line arguments.” The solution? (1) Reboot. (2) Run as administrator.

Also been reading Creating High Performing Silverlight Applications for Windows Phone. Awesome content. Tons of ideas and information. Essential reading.

Lastly, just starting to dive into the Microsoft Advertising SDK for Windows Phone 7. Documentation is on the web here.  Could be promising.

Screencast On Creating jQuery Animations Without Code

August 12 2010

Check out this post by my designer colleage, Tim Aidlin, on how to use Glimmer to create jQuery animations, in this case the hero graphic up at http://archivist.visitmix.com. Here's the screencast itself:

 

Oomph artwork
You need Silverlight to view this video. It’s fast, it’s free and it’s awesome. Click here to get it.

Windows Phone 7 Development Tip: Discovering and Using Default Styles

August 10 2010

I was playing around with the Windows Phone 7 tools and noticed that there are some system styles available for text.  For example, I noticed the following XAML that referenced PhoneTextTitle1Style in one of the Visual Studio project templates:

            <TextBlock x:Name="ListTitle" Text="{Binding LineOne}" Margin="-3,-8,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>

I then wanted to figure out what all the system styles were.  How to do it? Expression Blend!  By going to the Assets tab and then clicking Styles --> System Styles, I was able to see all the styles:

 

I then wanted to see what they looked like, so I double clicked each one, which created a textbox. To correlate the look with the name, I replaced the default text with the name of the style, producing this:

 

Perhaps this graphic/tip will help someone out there!

Getting Request.Form Data Out of XDomainRequest In ASP.NET

July 12 2010

I am using the XDomainRequest object in IE8 and IE9 to do cross domain posting.  However, I hit an issue where I couldn't seem to get at the data I was posting: the Request.Form collection contained nothing yet I was clearly sending it. I then found this post:

http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx

which states: "we restricted the content type to text/plain but didn’t allow the caller to specify that the data was in application/x-www-urlencoded form. This is problematic because server-side frameworks (e.g. ASP, ASPNET, etc) will only automatically parse a request’s fields into name-value pairs if the x-www-urlencoded content type is specified.

To workaround this issue, server code that currently processes HTML Forms must be rewritten to manually parse the request body into name-value pairs when receiving requests from XDomainRequest objects. This makes adding support for the XDomainRequest object more difficult than it would be otherwise."

Okay, so how does one do that? Well, turned to be pretty simple. I just had to access the Request.InputStream directly, as follows:

           //set the header to support XDomainRequest

           Response.Headers.Add("Access-Control-Allow-Origin", "*");

           //now extract the data out of the stream

           System.IO.Stream str;

           String jsonContents;

           Int32 counter, strLen, strRead;

           // Create a Stream object.

           str = Request.InputStream;

           // Find number of bytes in stream.

           strLen = Convert.ToInt32(str.Length);

           // Create a byte array.

           byte[] byteArray = new byte[strLen];

           // Read stream into byte array.

           strRead = str.Read(byteArray, 0, strLen);

           // Convert byte array to a text string.

           jsonContents = Encoding.UTF8.GetString(byteArray);

Serializing Request.ServerVariables to JSON: JavaScriptSerializer vs. DataContractJsonSerializer

July 7 2010

I needed to serialize Request.ServerVariables to JSON.  I tried both  JavaScriptSerializer nor DataContractJsonSerializer without any luck.  But I thought both would work, as Request.ServerVariables is of type NameValueCollection and the docs on MSDN state that both serialization engines support dictionaries. The solution? Convert (manually) the NameValueCollection into a dictionary.

Here's the code:

            Dictionary<string,string> d = new Dictionary<string,string>();
            foreach (string s in Request.ServerVariables.AllKeys)
            {
                d.Add(s, Request.ServerVariables[s]);
            }
            //DataContractJsonSerializer
            DataContractJsonSerializer serverVariablesSerializer = new DataContractJsonSerializer(typeof(Dictionary<string,string>));
            MemoryStream ms = new MemoryStream();
            serverVariablesSerializer.WriteObject(ms, d);
            string json = Encoding.Default.GetString(ms.ToArray());
            Debug.WriteLine(json);
            //JavaScriptSerializer
            JavaScriptSerializer serverVariablesSerializer2 = new JavaScriptSerializer();
            string json2 = serverVariablesSerializer2.Serialize(d);
            Debug.WriteLine(json2);

What's interesting is that the output is different between the two serialization engines. JavaScriptSerializer is smart enough to turn the key into the key in JSON, whereas DataContractJsonSerializer creates a key called "key" with the value of the key and then a key called "value" with the value of the value. Kind of annoying. The winner? JavaScriptSerializer

Here's the output BTW:

DataContractJsonSerializer: [{"Key":"ALL_HTTP","Value":"HTTP_CONNECTION:Keep-Alive\u000d\u000aHTTP_ACCEPT:*\/*\u000d\u000aHTTP_ACCEPT_ENCODING:gzip, deflate\u000d\u000aHTTP_ACCEPT_LANGUAGE:en-us\u000d\u000aHTTP_COOKIE:comment=name=b&email=b@b.com&url=&country=us; WT_FPC=id=71.231.143.146-177222816.30061129:lv=1277910617997:ss=1277910147666\u000d\u000aHTTP_HOST:localhost:4135\u000d\u000aHTTP_USER_AGENT:Mozilla\/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident\/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.2; OfficeLiveConnector.1.4; OfficeLivePatch.1.3; MS-RTC LM 8; .NET4.0C; .NET4.0E)\u000d\u000a"},{"Key":"ALL_RAW","Value":"Connection: Keep-Alive\u000d\u000aAccept: *\/*\u000d\u000aAccept-Encoding: gzip, deflate\u000d\u000aAccept-Language: en-us\u000d\u000aCookie: comment=name=b&email=b@b.com&url=&country=us; WT_FPC=id=71.231.143.146-177222816.30061129:lv=1277910617997:ss=1277910147666\u000d\u000aHost: localhost:4135\u000d\u000aUser-Agent: Mozilla\/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident\/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.2; OfficeLiveConnector.1.4; OfficeLivePatch.1.3; MS-RTC LM 8; .NET4.0C; .NET4.0E)\u000d\u000a"},{"Key":"APPL_MD_PATH","Value":""},{"Key":"APPL_PHYSICAL_PATH","Value":"C:\\stuff\\WebApplication1\\WebApplication1\\"},{"Key":"AUTH_TYPE","Value":"NTLM"},{"Key":"AUTH_USER","Value":"REDMOND\\karstenj"},{"Key":"AUTH_PASSWORD","Value":""},{"Key":"LOGON_USER","Value":"REDMOND\\karstenj"},{"Key":"REMOTE_USER","Value":"REDMOND\\karstenj"},{"Key":"CERT_COOKIE","Value":""},{"Key":"CERT_FLAGS","Value":""},{"Key":"CERT_ISSUER","Value":""},{"Key":"CERT_KEYSIZE","Value":""},{"Key":"CERT_SECRETKEYSIZE","Value":""},{"Key":"CERT_SERIALNUMBER","Value":""},{"Key":"CERT_SERVER_ISSUER","Value":""},{"Key":"CERT_SERVER_SUBJECT","Value":""},{"Key":"CERT_SUBJECT","Value":""},{"Key":"CONTENT_LENGTH","Value":"0"},{"Key":"CONTENT_TYPE","Value":""},{"Key":"GATEWAY_INTERFACE","Value":""},{"Key":"HTTPS","Value":""},{"Key":"HTTPS_KEYSIZE","Value":""},{"Key":"HTTPS_SECRETKEYSIZE","Value":""},{"Key":"HTTPS_SERVER_ISSUER","Value":""},{"Key":"HTTPS_SERVER_SUBJECT","Value":""},{"Key":"INSTANCE_ID","Value":""},{"Key":"INSTANCE_META_PATH","Value":""},{"Key":"LOCAL_ADDR","Value":"127.0.0.1"},{"Key":"PATH_INFO","Value":"\/Default.aspx"},{"Key":"PATH_TRANSLATED","Value":"C:\\stuff\\WebApplication1\\WebApplication1\\Default.aspx"},{"Key":"QUERY_STRING","Value":""},{"Key":"REMOTE_ADDR","Value":"127.0.0.1"},{"Key":"REMOTE_HOST","Value":"127.0.0.1"},{"Key":"REMOTE_PORT","Value":""},{"Key":"REQUEST_METHOD","Value":"GET"},{"Key":"SCRIPT_NAME","Value":"\/Default.aspx"},{"Key":"SERVER_NAME","Value":"localhost"},{"Key":"SERVER_PORT","Value":"4135"},{"Key":"SERVER_PORT_SECURE","Value":"0"},{"Key":"SERVER_PROTOCOL","Value":"HTTP\/1.1"},{"Key":"SERVER_SOFTWARE","Value":""},{"Key":"URL","Value":"\/Default.aspx"},{"Key":"HTTP_CONNECTION","Value":"Keep-Alive"},{"Key":"HTTP_ACCEPT","Value":"*\/*"},{"Key":"HTTP_ACCEPT_ENCODING","Value":"gzip, deflate"},{"Key":"HTTP_ACCEPT_LANGUAGE","Value":"en-us"},{"Key":"HTTP_COOKIE","Value":"comment=name=b&email=b@b.com&url=&country=us; WT_FPC=id=71.231.143.146-177222816.30061129:lv=1277910617997:ss=1277910147666"},{"Key":"HTTP_HOST","Value":"localhost:4135"},{"Key":"HTTP_USER_AGENT","Value":"Mozilla\/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident\/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.2; OfficeLiveConnector.1.4; OfficeLivePatch.1.3; MS-RTC LM 8; .NET4.0C; .NET4.0E)"}]

JavaScriptSerializer: {"ALL_HTTP":"HTTP_CONNECTION:Keep-Alive\r\nHTTP_ACCEPT:*/*\r\nHTTP_ACCEPT_ENCODING:gzip, deflate\r\nHTTP_ACCEPT_LANGUAGE:en-us\r\nHTTP_COOKIE:comment=name=b&email=b@b.com&url=&country=us; WT_FPC=id=71.231.143.146-177222816.30061129:lv=1277910617997:ss=1277910147666\r\nHTTP_HOST:localhost:4135\r\nHTTP_USER_AGENT:Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.2; OfficeLiveConnector.1.4; OfficeLivePatch.1.3; MS-RTC LM 8; .NET4.0C; .NET4.0E)\r\n","ALL_RAW":"Connection: Keep-Alive\r\nAccept: */*\r\nAccept-Encoding: gzip, deflate\r\nAccept-Language: en-us\r\nCookie: comment=name=b&email=b@b.com&url=&country=us; WT_FPC=id=71.231.143.146-177222816.30061129:lv=1277910617997:ss=1277910147666\r\nHost: localhost:4135\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.2; OfficeLiveConnector.1.4; OfficeLivePatch.1.3; MS-RTC LM 8; .NET4.0C; .NET4.0E)\r\n","APPL_MD_PATH":"","APPL_PHYSICAL_PATH":"C:\\stuff\\WebApplication1\\WebApplication1\\","AUTH_TYPE":"NTLM","AUTH_USER":"REDMOND\\karstenj","AUTH_PASSWORD":"","LOGON_USER":"REDMOND\\karstenj","REMOTE_USER":"REDMOND\\karstenj","CERT_COOKIE":"","CERT_FLAGS":"","CERT_ISSUER":"","CERT_KEYSIZE":"","CERT_SECRETKEYSIZE":"","CERT_SERIALNUMBER":"","CERT_SERVER_ISSUER":"","CERT_SERVER_SUBJECT":"","CERT_SUBJECT":"","CONTENT_LENGTH":"0","CONTENT_TYPE":"","GATEWAY_INTERFACE":"","HTTPS":"","HTTPS_KEYSIZE":"","HTTPS_SECRETKEYSIZE":"","HTTPS_SERVER_ISSUER":"","HTTPS_SERVER_SUBJECT":"","INSTANCE_ID":"","INSTANCE_META_PATH":"","LOCAL_ADDR":"127.0.0.1","PATH_INFO":"/Default.aspx","PATH_TRANSLATED":"C:\\stuff\\WebApplication1\\WebApplication1\\Default.aspx","QUERY_STRING":"","REMOTE_ADDR":"127.0.0.1","REMOTE_HOST":"127.0.0.1","REMOTE_PORT":"","REQUEST_METHOD":"GET","SCRIPT_NAME":"/Default.aspx","SERVER_NAME":"localhost","SERVER_PORT":"4135","SERVER_PORT_SECURE":"0","SERVER_PROTOCOL":"HTTP/1.1","SERVER_SOFTWARE":"","URL":"/Default.aspx","HTTP_CONNECTION":"Keep-Alive","HTTP_ACCEPT":"*/*","HTTP_ACCEPT_ENCODING":"gzip, deflate","HTTP_ACCEPT_LANGUAGE":"en-us","HTTP_COOKIE":"comment=name=b&email=b@b.com&url=&country=us; WT_FPC=id=71.231.143.146-177222816.30061129:lv=1277910617997:ss=1277910147666","HTTP_HOST":"localhost:4135","HTTP_USER_AGENT":"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.2; OfficeLiveConnector.1.4; OfficeLivePatch.1.3; MS-RTC LM 8; .NET4.0C; .NET4.0E)"}

Using Stringify With the New window.msPerformance in Internet Explorer 9

July 6 2010

I've been playing with the new window.msPerformance that's part of IE9 as explained in this blog post: http://blogs.msdn.com/b/ie/archive/2010/06/28/measuring-web-page-performance.aspx. Of course, the main thing you want to do is capture this data. The blog post mentions that you can use the stringify method to serialize the object to JSON and then send the diagnostics back to the server.  Well, I tried this with no luck. Here's what my code looked like:

   <script type="text/javascript" >
        function test() {
            if (window.msPerformance != null) {


                var json = JSON.stringify(window.msPerformance.timing);
                alert(window.msPerformance.timing);
                alert(json);
            }
        }
</script>

Even though the performance object was populated, the serialization to JSON failed.

I did some digging around and learned that the native JSON method in IE9 doesn't successfully stringify native objects, like anything hanging off window or document.  However, I was able to work around this by using Crockford's JSON class from here: http://www.json.org/js.html.  The one thing I had to do was to change the prototype to JSON2 so that the browser's native JSON prototype wasn't called. Then it worked!

The Archivist Is Live!

June 28 2010

Well, the project I've been working on for quite a while just went live to the world: The Archivist at http://archivist.visitmix.com. Go give it a whirl and let me know what you think. The intro article is here: http://visitmix.com/LabNotes/Intro-To-The-Archivist and you can download the source code here: http://code.msdn.microsoft.com/archivist

Been quite an adventure building and shipping this puppy -- looking forward to seeing what happens now that it is out in the wild.

 

 

HttpClient and HttpResponseMessage Unhappy in Medium Trust

June 19 2010

Just hit an issue where I was using the WCF REST Starter kit and their wrapper methods for handling HttpWebRequest and HttpWebResponse for consuming ATOM. All was fine -- until I deployed. Then I was getting a securtiy exception.  So, I ported the code to use raw HttpWebRequest and all worked. My guess is that my provider has configured something to explicitly allow for HttpWebRequest but not wrapper methods around it. Or something. Anyway, here was my old code:

        private SyndicationFeed GetFeed(string url)
        {
            using (HttpClient http = new HttpClient())
            {
                using (HttpResponseMessage resp = http.Get(url))
                {
                    resp.EnsureStatusIsSuccessful();
                    return resp.Content.ReadAsSyndicationFeed();
                }
            }
        }
 

And here's my new code:

   private SyndicationFeed GetFeed(string url)
    {
        HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
        using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
        {
            if (response == null)
                return null;
            if (response.StatusCode != HttpStatusCode.OK)
                return null;
            using (XmlReader reader = XmlReader.Create(response.GetResponseStream()))
            {
                try
                {
                    return SyndicationFeed.Load(reader);
                }
                catch (Exception)
                {
                    return null;
                }
            }
        }

Optical Art

June 18 2010

This picture is wack:

 

VSAchievements
Visual Studio Achievements
Karsten Januszewski (207 Points)