Welcome To Our Beautiful Home, Excuse The Legacy Mess Everywhere

by Jon Davis 7. December 2012 09:42

Rant time again. Oh the things that get me worked up to finally blog again.

Office 365 - Outlook.com conflict
Sadly, while this image I found on Google Images represents the messaging I saw, it does not represent what I saw. My experience wasn’t quite so pretty.

First I couldn’t access my mail that I was getting notified about from Live Messenger, Microsoft’s site said that Office 365 users can’t upgrade to Office.com.

This account can't be used to access Outlook.com

You're currently signed in with an Office 365 email account, which can't be used with Outlook.com. Please click here to sign out of your Office 365 account, then use another Microsoft account to sign in to Outlook.com (for example, your hotmail.com, live.com, or msn.com account). 

Well that would be all fine and fair, except that I had no recollection of having anything to do with Office 365, and I was still getting these “new mail” alerts from Live Messenger every time I log into (not boot, log into) my work computer. There was no way to fix the problem. If I went to Office 365’s web site and attempted to sign in, I got in a bizarre redirect loop. Clearly I had no actual Office 365 account because I never got involved with Office 365, but somewhere, somehow, a flag got buried in my profile that identified me as an Office 365 user when attempting to get into Hotmail / Outlook.com.

Then yesterday or this morning I got a splashy marketing email from Microsoft saying that my account was ready to upgrade to Outlook.com. This email comes just hours after I was told I couldn’t upgrade. I figured there was maybe a 5% chance that the email was accurate in its portrayal of my account being upgradeable, that something had changed in my account overnight and that Microsoft was so proud of itself they decided to make the email look splashy. Of course, I was right, I still got this ridiculous message saying Office 365 users can’t upgrade.

Again, I wasn’t an Office 365 user. I may have poked at it once to see what it was. Since I could find no recourse, I went about deleting my profile so I could re-create it. I read the up-front warnings about account deletion carefully before proceeding, being sure it didn’t say that I wouldn’t be able to recreate the account with the same e-mail address ever again or for some long period of time. I saw nothing like that. So *click*, gone, deleted. So as I go to recreate it, it tells me the e-mail address is in use. Great. I did some Googling and discovered in an Xbox forum that there is a 90-day waiting period, at least on Xbox, before the email address that was used to originally create the now-deleted account can be reused to create another one.

Curious as to whether some of the older link-ins to the “create a new [Microsoft/Xbox/whatever] account” might skip over the locked email matter, which of course everything I tried still failed, I couldn’t help but note that these link-ins are still calling new accounts “MSN Hotmail” accounts, and with some really old graphics and formatting. REALLY, Microsoft?

image

Seriously, Microsoft, can’t you get your ducks in order?!

1. Don’t ever lock out a group of users from accessing a service without providing a means for those users to remove themselves from that group. I was “an Office 365” account user, but I didn’t want to be, I had no intention to be, I don’t remember how I become one--perhaps play-testing what was out there, but I had already used this account to use Windows Live Messenger, Hotmail (hence my notifications), and a Windows 8 login profile (which has now been destroyed due to this Office 365 horsecrap, thanks!), and instead of deleting my account I should have been able to get into some kind of obvious interface and just drop that incompatible feature.

2. Better yet, with all the consolidations you guys have done for all the IDs as “Microsoft Accounts”, at least in promises throughout the news media, you should not have allowed an incompatibility to exist! Instead there should have been a conversion process that would immediately take place. But no, you had to go and BLAME THE USER, spin around, and walk away! I get better treatment at the Department of Motor Vehicles!

3. Microsoft, if someone is deleting a user profile, tell them up front, “You will not be able to recreate an account with the e-mail address you used to create this account for 90 days” right in there next to the delete button! I had to have it already deleted before I considered sleuthing forums (!!) to find a hint at the 90 days, and I still don’t know for sure if the 90 days on Xbox accounts translates to 90 days for my account.

4. Remember Passport, Microsoft? I mean, it is the original branding of what is now Microsoft Accounts. Do you remember? Well, a lot of customers do, and they're treated to a miserable experience when they go to http://passport.net/ in Chrome. Not to mention, when they go to sign up for a Microsoft Accounts account there, they get the experience of jumping around between three or four brands and never land on Microsoft Accounts. So, again, did you forget about Passport.net, Microsoft?

5. By the way, signing in with my personal account into answers.microsoft.com, I was greeted with this, and it never went away. Ever.

image

Microsoft, your Microsoft Accounts, all of its forms, is a product. Your product is of immensely poorly constructed quality it’s hard to know where to begin. How is it that I got into a redirect loop when I attempted to access the Office 365 web site to try to find something to turn off or remove myself from? Why is it that depending on which community web site I’m accessing, when I access the same “log in” dialog and choose to create a new account I am presented with such the disgusting legacy of an “MSN Hotmail” account setup? Microsoft, all of your new users using this navigation path are going to see that crap. Do you want to relinquish the marketing verbiage of MSN Hotmail or not? If not, why then would you allow these legacy interfaces to be so commonly exposed to the general public? It would be something else entirely if I was trying to access some rarely used feature of Microsoft’s web site, but no, this was a navigation path that Microsoft would probably hope every last human being with an Internet connection would follow.

Don’t get me wrong, I understand that Microsoft has to take a phased approach to this stuff; let’s roll out new marketing changes and new reorganizations in phases, people will just suffer through the legacy stuff for a while. I call bullcrap!! This is 2012, business practices we’ve settled for need to change. If you want to output something of quality, you don’t launch a hybrid mess of ancient and new and call it “new”, you call it “hybrid mess of ancient and new”! Who do you think you’re fooling, Microsoft, when you greet people with “log into your Microsoft Account” with elegant branding but then as soon as they begin setting up their profile they get this 2005-esque MSN Hotmail experience? It was the same user story! Creating a Microsoft Account to access a service/community. How many Microsoft Account stories are there, really? I count five: Log in, log out, create a new account, manage your account, delete your account. Yet it seems no one managing Microsoft Account considered that it might make a poor level of quality to have two completely different branding experiences while navigating through any of these puny five stories. As huge and important as Microsoft Accounts is ... Really, Microsoft?!

Side note: I make such rants because I’m hoping Microsoft is listening, not because I think people should walk away from Microsoft services because I absolutely don’t think that. Microsoft needs to clean this stuff up. This has been going on with Passport / MSN / Live / Microsoft Accounts forever. (Speaking of Passport, have you navigated to http://passport.net in Chrome lately? Its layout is so broken it’s tempting to think it’s not alive anymore.) I am also hoping everyone who is not at Microsoft (basically almost everyone who reads my blog) can take a lesson from this about user experiences and what not to settle for.

Currently rated 2.5 by 2 people

  • Currently 2.5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Canvas & HTML 5 Sample Junk

by Jon Davis 27. September 2012 15:48

Poking around with HTML 5 canvas again, refreshing my knowledge of the basics. Here's where I'm dumping links to my own tinkerings for my own reference. I'll update this with more list items later as I come up with them.

  1. Don't have a seizure. http://jsfiddle.net/8RYtu/22/
    HTML5 canvas arc, line, audio, custom web font rendered in canvas, non-fixed (dynamic) render loop with fps meter, window-scale, being obnoxious
  2. Pass-through pointer events http://jsfiddle.net/MtGT8/1/
    Demonstrates how the canvas element, which would normally intercept mouse events, does not do so here, and instead allows the mouse event to propagate to the elements behind it. Huge potential but does not work in Internet Explorer.
  3. Geolocation sample. http://jsfiddle.net/nmu3x/4/ 
    Nothing to do with canvas here. Get over it.

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , , , ,

Javascript | Software Development

Automatically Declaring Namespaces in Javascript (namespaces.js)

by Jon Davis 25. September 2012 18:24

Namespaces in Javascript are a pattern many untrained or undisciplined developers may fail to do, but they are an essential strategy in retaining maintainability and avoiding collisions in Javascript source.

Part of the problem with namespaces is that if you have a complex client-side solution with several Javascript objects scattered across several files but they all pertain to the same overall solution, you may end up with very long, nested namespaces like this:

var ad = AcmeCorporation.Foo.Bar.WidgetFactory.createWidget('advertisement');

I personally am not opposed to long namespaces, so long as they can be shortened with aliases when their length gets in the way.

var wf = AcmeCorporation.Foo.Bar.WidgetFactory;
var ad = wf.createWidget('advertisement');

The problem I have run into, however, is that when I have multiple .js files in my project and I am not 100% sure of their load order, I may run into errors. For example:

// acme.WidgetFactory.js
AcmeCorporation.Foo.Bar.WidgetFactory = {
createWidget: function(e) {
return new otherProvider.Widget(e);
}
};

This may throw an error immediately because even though I’m declaring the WidgetFactory namespace, I am not certain that these namespaces have been defined:

  • AcmeCorporation
  • AcmeCorporation.Foo
  • AcmeCorporation.Foo.Bar

So again if any of those are missing, the code in my acme.WidgetFactory.js file will fail.

So then I clutter it with code that looks like this:

// acme.WidgetFactory.js
if (!window['AcmeCorporation']) window['AcmeCorporation'] = {};
if (!AcmeCorporation.Foo) AcmeCorporation.Foo = {};
if (!AcmeCorporation.Foo.Bar) AcmeCorporation.Foo.Bar = {};
AcmeCorporation.Foo.Bar.WidgetFactory = {
createWidget: function(e) {
return new otherProvider.Widget(e);
}
};

This is frankly not very clean. It adds a lot of overhead to my productivity just to get started writing code.

So today, to compliment my using.js solution (which dynamically loads scripts), I have cobbled together a very simple script that dynamically defines a namespace in a single line of code:

// acme.WidgetFactory.js
namespace('AcmeCorporation.Foo.Bar');
AcmeCorporation.Foo.Bar.WidgetFactory = {
createWidget : function(e) {
return new otherProvider.Widget(e);
}
};
/* or, alternatively ..
namespace('AcmeCorporation.Foo.Bar.WidgetFactory');
AcmeCorporation.Foo.Bar.WidgetFactory.createWidget = function(e) {
return new otherProvider.Widget(e);
};
*/

As you can see, a function called “namespace” splits the dot-notation and creates the nested objects on the global namespace to allow for the nested namespace to resolve correctly.

Note that this will not overwrite or clobber an existing namespace, it will only ensure that the namespace exists.

a = {};
a.b = {};
a.b.c = 'dog';
namespace('a.b.c');
alert(a.b.c); // alerts with "dog"

Where you will still need to be careful is if you are not sure of load order then your namespace names all the way up the dot-notation tree should be namespaces alone and never be defined objects, or else assigning the defined objects manually may clobber nested namespaces and nested objects.

namespace('a.b.c');
a.b.c.d = 'dog';
a.b.c.e = 'bird';
// in another script ..
a.b = { 
c : {
d : 'cat'
}
};
// in consuming script / page
alert(a.b.c); // alerts [object]
alert(a.b.c.d); // alerts 'cat'
alert(a.b.c.e); // alerts 'undefined'

Here’s the download if you want it as a script file [EDIT: the linked resource has since been modified and has grown significantly], and here is its [original] content:

function namespace(ns) {
var g = function(){return this}();
ns = ns.split('.');
for(var i=0, n=ns.length; i<n; ++i) {
var x = ns[i];
if (x in g === false) g[x]={}; 
g = g[x];
}
} 

The above is actually written by commenter "steve" (sjakubowsi -AT- hotmail -dot-com). Here is the original solution that I had come up with:

namespace = function(n) {
var s = n.split('.');
var exp = 'var ___v=undefined;try {___v=x} catch(e) {} if (___v===undefined)x={}';
var e = exp.replace(/x/g, s[0]);
eval(e);
for (var i=1; i<s.length; i++) {
var ns = '';
for (var p=0; p<=i; p++) {
if (ns.length > 0) ns += '.';
ns += s[p];
}
e = exp.replace(/x/g, ns);
eval(e);
}
}

Currently rated 4.0 by 2 people

  • Currently 4/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , ,

Javascript | Pet Projects

Why jQuery Plugins Use String-Referenced Function Invocations

by Jon Davis 25. September 2012 10:52

Some time ago (years ago) I cobbled together a jQuery plug-in or two that at the time I was pretty proud of, but in retrospect I’m pretty embarrassed. One of these plugins was jqDialogForms. The embarrassment was not due to its styling—the point of it was that it could be skinnable, I just didn’t have time to create sample skins—nor was the embarrassment due to the functional conflict with jQuery UI’s dialog component, because I had a specific vision in mind which included modeless parent/child ownership, opening by simple DOM reference or by string, and automatic form serialization to JSON. Were I to do all this again I would probably just extend jQuery UI with syntactical sugar, and move form serialization to another plugin, but all that is a tangent from the purpose of this blog post. My embarassment with jqDialogForms is with the patterns and conventions I chose in contradiction to jQuery’s unique patterns.

Since then I have abandoned (or perhaps neglected) jQuery plugins development, but I still formed casual and sometimes uneducated opinions along the way. One of the patterns that had irked me was jQuery UI’s pattern of how its components’ functions are invoked:

$('#mydiv').accordion( 'disable' );
$('#myauto').autocomplete( 'search' , [value] );
$('#prog').progressbar( 'value' , [value] );

Notice that the actual functions being invoked are identified with a string parameter into another function. I didn’t like this, and I still think it’s ugly. This came across to me as “the jQuery UI” way, and I believed that this contradicted “the jQuery way”, so for years I have been baffled as to how jQuery could have adopted jQuery UI as part of its official suite.

Then recently I came across this, and was baffled even more:

http://docs.jquery.com/Plugins/Authoring

Under no circumstance should a single plugin ever claim more than one namespace in the jQuery.fn object.

(function( $ ){

  $.fn.tooltip = function( options ) { 
    // THIS
  };
  $.fn.tooltipShow = function( ) {
    // IS
  };
  $.fn.tooltipHide = function( ) { 
    // BAD
  };
  $.fn.tooltipUpdate = function( content ) { 
    // !!!  
  };

})( jQuery );

This is a discouraged because it clutters up the $.fn namespace. To remedy this, you should collect all of your plugin’s methods in an object literal and call them by passing the string name of the method to the plugin.

(function( $ ){

  var methods = {
    init : function( options ) { 
      // THIS 
    },
    show : function( ) {
      // IS
    },
    hide : function( ) { 
      // GOOD
    },
    update : function( content ) { 
      // !!! 
    }
  };

  $.fn.tooltip = function( method ) {
    
    // Method calling logic
    if ( methods[method] ) {
      return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
    } else if ( typeof method === 'object' || ! method ) {
      return methods.init.apply( this, arguments );
    } else {
      $.error( 'Method ' +  method + ' does not exist on jQuery.tooltip' );
    }    
  
  };

})( jQuery );

// calls the init method
$('div').tooltip(); 

// calls the init method
$('div').tooltip({
  foo : 'bar'
});

// calls the hide method
$('div').tooltip('hide'); 
// calls the update method
$('div').tooltip('update', 'This is the new tooltip content!'); 

This type of plugin architecture allows you to encapsulate all of your methods in the plugin's parent closure, and call them by first passing the string name of the method, and then passing any additional parameters you might need for that method. This type of method encapsulation and architecture is a standard in the jQuery plugin community and it used by countless plugins, including the plugins and widgets in jQueryUI.

What baffled me was not their initial reasoning pertaining to namespaces. I completely understand the need to keep plugins’ namespaces in their own bucket. What baffled me was how this was considered a solution. Why not simply use this?

$('#mythingamajig').mySpecialNamespace.mySpecialFeature.doSomething( [options] );

To see about proving that I could make both myself and the “official” jQuery team happy, I cobbled this test together ..

(function($) {
    
    $.fn.myNamespace = function() {
        var fn = 'default';
        
        var args = $.makeArray(arguments);
        if (args.length > 0 && typeof(args[0]) == 'string' && !(!($.fn.myNamespace[args[0]]))) {
            fn = args[0];
            args = $(args).slice(1);
        }
        $.fn.myNamespace[fn].apply(this, args);
    };
    $.fn.myNamespace.default = function() {
        var s = '\n';
        var i=0;
        $(arguments).each(function() {            
            s += 'arg' + (++i).toString() + '=' + this + '\n';
        });
        alert('Default' + s);
        
    };
    $.fn.myNamespace.alternate = function() {
        var s = '\n';
        var i=0;
        $(arguments).each(function() {            
            s += 'arg' + (++i).toString() + '=' + this + '\n';
        });
        alert('Alternate' + s);
        
    };

    $().myNamespace('asdf', 'xyz');
    $().myNamespace.default('asdf', 'xyz');
    $().myNamespace('default', 'asdf', 'xyz');
    $().myNamespace.alternate('asdf', 'xyz');
    $().myNamespace('alternate', 'asdf', 'xyz');
    
})(jQuery);

Notice the last few lines in there ..

    $().myNamespace('asdf', 'xyz');
    $().myNamespace.default('asdf', 'xyz');
    $().myNamespace('default', 'asdf', 'xyz');
    $().myNamespace.alternate('asdf', 'xyz');
    $().myNamespace('alternate', 'asdf', 'xyz');

When this worked as I hoped I originally set about making this blog post be a “plugin generator plugin” that would make plug-in creation really simple and also enable the above calling convention. But when I got to the some passing tests, adding a few more tests I realized I had failed to notice a critical detail: the this context, and chainability.

In JavaScript, navigating a namespace as with $.fn.myNamespace.something.somethingelse doesn’t execute any code within the dot-notation. Without the execution of functional code, there can be no context for the this context, which should be the jQuery-wrapped selection, and as such there can be no context for the return chainable object. (I realize that it is possible to execute code with modern JavaScript getters and setters but all modern browsers don’t support getters and setters and all commonly used browsers certainly don’t.) This was something that I as a C# developer found easy to forget and overlook, because in C# we take the passing around of context in property getters for granted.

Surprisingly, this technical reasoning for the string-based function identifier for jQuery plug-in function invocations was not mentioned on the jQuery Plugins documentation site, nor was it mentioned in the Pluralsight video-based training I recently perused. It seemed like what Pluralsight’s trainer was saying was, “You can use $().mynamespace.function1()” but that’s obscure! Use a string parameter instead!” And I’m like, “No, it is not obscure! Calling a function by string is obscure because you can’t easily identify it as a function reference distinct from a parameter value!”

The only way to retain the this context while removing the string-based function reference is to invoke it along the way.

$().myNamespace().myFunction('myOption1', true, false);

Notice the parenthesis after .myNamespace. And that is a wholly different convention that few in jQuery-land are used to. But I do think that it is far more readable than ..

$().myNamespace('myFunction', 'myOption1', true, false);

I still like the former, it is more readable, and I remain unsure as to why the latter is the accepted convention over the former, but my guess is that a confused user might try to chain back to jQuery right after .myNamespace() rather than after executing a nested function. And that, I suppose, demonstrates how the former pattern is contrary to jQuery’s chainability design of every().invocation().just().returns().jQuery.

Currently rated 5.0 by 2 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , , ,

Javascript

Personal Status Update [September 19, 2012]

by Jon Davis 19. September 2012 12:16

I know, I know, I promised I’d pick up some steam on my blog and then suddenly I got quiet. Here’s the deal .. when I started picking up a bit more steam a couple months ago, I was looking for my next permanent job. Well, I found it. And, I’m kind of floored by its potential, as well as the preexisting knowledge that I’d be surrounded by some amazing people as well as be given high expectations of technical and professional maturity. This is my dream job.

I’ll post more but for now I need to catch up on some Pluralsight training, perhaps (finally) get some Microsoft certifications (MCPD and perhaps at some point even MCM), get a couple project successes behind me, and ultimately prove my worth to my employer. They’re watching. o.O

Oh, by the way, remember using.js? I created it waaay back in 2008 and it was surprisingly popular. Anyway, today I finally moved it over to GitHub. https://github.com/stimpy77/using.js Recent Javascript design patterns training on Pluralsight as a refresher got me motivated to blow the dust off of it and put it in a more publically enjoyable space. Cheers.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

ASP.NET MVC 4: Where Have All The Global.asax Routes Gone?

by Jon Davis 23. June 2012 03:03

I ran into this a few days back and had been meaning to blog about it, so here it finally is while it’s still interesting information.

In ASP.NET MVC 1.0, 2.0, and 3.0, routes are defined in the Global.asax.cs file in a method called RegisterRoutes(..).

mvc3_register_routes

It had become an almost unconscious navigate-and-click routine for me to open Global.asax.cs up to diagnose routing errors and to introduce new routes. So upon starting a new ASP.NET MVC 4 application with Visual Studio 11 RC (or Visual Studio 2012 RC, whichever it will be called), it took me by surprise to find that the RegisterRoutes method is no longer defined there. In fact, the MvcApplication class defined Global.asax.cs contains only 8 lines of code! I panicked when I saw this. Where do I edit my routes?!

mvc4_globalasax

What kept me befuddled for far too long (quite a bit longer than a couple seconds, shame on me!) was the fact that these lines of code, when not actually read and only glanced at, look similar to the Application_Start() from the previous iteration of ASP.NET MVC:

mvc3_globalasax

Eventually I squinted and paid closer attention to the difference, and then I realized that the RegisterRoutes(..) method is being invoked still but it is managed in a separate configuration class. Is this class an application settings class? Is it a POCO class? A wrapper class for a web.config setting? Before I knew it I was already right-clicking on RegisterRoutes and choosing Go To Definition ..

mvc4_globalasax_gotodef

Under Tools –> Options –> Projects and Solutions –> General I have Track Active Item in Solution Explorer enabled, so upon right-clicking an object member reference in code and choosing “Go To Definition” I always glance over at Solution Explorer to see where it navigates to in the tree. This is where I immediately found the new config files:

mvc4_app_start_solex

.. in a new App_Start folder, which contains FilterConfig.cs, RouteConfig.cs, and BundleConfig.cs, as named by the invoking code in Global.asax.cs. And to answer my own question, these are POCO classes, each with a static method (i.e. RegisterRoutes).

I like this change. It’s a minor refactoring that cleans up code. I don’t understand the naming convention of App_Start, though. It seems like it should be called “Config” or something, or else Global.asax.cs should be moved into App_Start as well since Application_Start() lives in Global.asax.cs. But whatever. Maintaining configuration details in one big Global.asax.cs file gets to be a bit of a pain sometimes especially in growing projects so I’m very glad that such configuration details are now tucked away in their own dedicated spaces.

I am curious but have not yet checked to determine whether App_Start as a new ASP.NET folder has any inherent behaviors associated with it, such as for example post-edit auto-compilation. I’m doubtful.

In future blog post(s), perhaps my next post, I’ll go over some of the other changes in ASP.NET MVC 4.

Currently rated 4.8 by 9 people

  • Currently 4.777778/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

ASP.NET | Web Development

LiveStream No Longer Free, Now $45 Per Month

by Jon Davis 1. March 2012 13:18

This is not a developer post at all, I wanted to share it with the world to see if this might get this picked up by Google as I am somewhat bewildered that a Google search does not reveal this information at all.

I have been enjoying a side personal interest in video production for several months now. I recently found a venue to focus this interest—a weekly group event at my church. I’ve become the videographer there during Wednesday evening meetings, and I’ve restored the execution of the group’s vision to LiveStream the meetings by providing the tools needed to get the job done, i.e. connectors from my camera, converters to a PC, etc.

Unfortunately, after some recent changes to LiveStream that they are still undergoing it appears that with the “New Livestream” the ability to produce and publish live content or share video clips for free is going to be going away completely. This ability is apparently being replaced by “Producer Accounts” which will apparently cost $45 each month. This is what I posted on their Forums @ http://www.livestream.com/forum/showpost.php?p=31605&postcount=40:

There does appear to be a Search field at the top of the site, don't know if it was recently added or not, but it doesn't seem to work to find either of the two channels I support. I agree that category browsing MUST be returned.

My concern, however, is that the profile page on the "new" site shows nothing. The old page for http://www.livestream.com/{channelname} works "fine", but in the new site with http://new.livestream.com/accounts/79748 it's flat disabled. There is no support whatsoever for even producing live content for free. The messaging when logged in says, "Upgrade to a Producer Account to Create Events - We see that you currently have a New Livestream Viewer Account (Free). To create events and post text, video clips, photos and live video, you'll require a New Livestream Producer Account." Even video clips and live video requires a "producer account" which starts at $45/mo.

Presumably, the old site and its featureset are going to go away completely. So, apparently, it's over, guys. No more free LiveStreaming.

These observations could be temporary or perhaps misread, but it looked pretty obvious to me that this is what is going on.

image

*click* on Upgrade Now ..

image

 UPDATE: Heard back from LiveStream:

"The reason your channel is not showing up in search is most likely because it has not yet been verified. To be clear, the original Livestream isn't going anywhere. We plan to continue to offer free streaming for the foreseeable future.

Currently rated 3.0 by 2 people

  • Currently 3/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Adding Compiled .ResX Resources To NuGet Packages

by Jon Davis 16. November 2011 17:05

At my current workplace, we are using NuGet internally for managing internal ASP.NET MVC 3 project templates. If you open up Visual Studio’s Tools -> Options dialog window and expand Package Manager, you will find a “Package Sources” section where you can define locations for acquiring NuGet packages. We have a second location defined in this section with the path being a directory on our LAN. There are several advantages of taking this approach to managing team resources, not the least of which is the fact that updating our template source code repositories over SVN will not, and should not, update (read: break) the development workflows for people already working on their projects unless those individuals manually invoke an Update-Package command from the Package Manager Console. This scenario is obviously not ideal for many teams but it is quite useful for ours since each project instance has its own lifecycle and is short-lived.

One of the dependencies of our ASP.NET MVC templates is the utilization of .resx files for managing various pieces of content such as the labels on the forms. Have a resource file gives specific members of the organization a very specific and anticipated location to update the content to suit the needs of the project instance. The content items are also programmatically accessible when the Access Modifier is set to public; a .Designer.cs file is generated and injected into the project automatically by Visual Studio, appearing as a generated code-behind file for the .resx file, which exposes the API required to programmatically read content from this file by item name so that the developer does not have to stream the .resx out manually as an embedded resource stream. Microsoft .NET also automatically pulls the content from the suitable resource file when the culture is added to the filename, based on the user’s culture of the current thread; in other words, if a resource file is called FormFields.resx, but the user is French-Canadian (fr-CA), then the content in FormFields.fr-CA.resx is automatically used. Of course, we have to manually synchronize the user’s culture with the thread, that is a separate discussion, but the point is that it can be beneficial, and in our case it is, to utilize .resx resources in a project.

Unfortunately, when installing a NuGet project that contains .resx file content, the generated designer C# file that exposes programmatic access to the items in the resources file does not get added correctly, nor is the metadata on the .resx file that declares the resource’s Access Modifier to be “Public”, which is how Visual Studio knows to inject that generated file. Our template’s C# codebase depends upon the presence of the generated C# object members for the .resx, so in the absence of the generated code-behind file the project importing this template will not compile. Our workaround had been to open up the .resx file, change the Access Modifier back to “Public”, save it, and Rebuild. This worked fine, but it has been a huge annoyance.

So we decided to look into automatically fixing this within the Install.ps1 PowerShell script which NuGet invokes upon installing a package. Visual Studio’s DTE automation object and its Project object are both injected to the Install.ps1 script that PowerShell invokes.

param($installPath, $toolsPath, $package, $project)

We store our resources in a Resources directory in the project, so iterating through the project items to identify our .resx files was straightforward enough.

$resitems = @{}
foreach ($item in $project.ProjectItems) 
{
    if ($item.Name -eq "Resources") {
        foreach ($resitem in $resources.ProjectItems) {
            if ($resitem.Name.ToLower().EndsWith(".resx")) {
               $resitems.Add("Resources\" + $resitem.Name, $resitem.FileNames(0))
            }
        }
    }
}

Unfortunately, I found no way within EnvDTE automation to modify the properties the .resx file that pertain to the generated file! At best, the ProjectItem object exposes a Properties member that lists out various bits of metadata, but I found nothing here that can be changed to cause the .resx file to use a generated file.

The best I could find and tried to play with was a property called “IsDesignTimeBuildInput” that I thought I could apply to the .Designer.cs file, but attempting to set this value to true proved unfruitful:

# where $cb2 is the .Designer.cs file
$cb2.Properties.Item("IsDesignTimeBuildInput").Value = $TRUE

.. results in ..
Exception setting "Value": "Invalid number of parameters. (Exception from HRESULT: 0x8002000E (DISP_E_BADPARAMCOUNT))"

I did manage to get a code-behind file added to the .resx file, however.

switch ($item.ProjectItems) { default {
	if ($_.Name.ToLower() -eq $resitem.Name.ToLower().Replace(".resx", ".designer.cs")) {
		$hasCodeBehind = $TRUE
		$codebehinditem = $_
	}
}}
if ($hasCodeBehind -eq $TRUE) {
	$fn = $resitem.FileNames(0)
	$cbfn = $codebehinditem.FileNames(0)
	$codebehinditem.Remove()
	$cb2 = $resitem.ProjectItems.AddFromFile($cbfn)
}

At this point, it would prove obviously beneficial to use a comparison tool such as Beyond Compare (which I used) to compare the contents of the .resx file, the .Designer.cs file, and the .csproj file (the Visual Studio project file) between my half-restored NuGet injection and a properly working project instance. Doing this, I found that there are absolutely no changes made to the .resx file to toggle its code-behind / generator behavior, and of course the .Designer.cs is just the output of the generator so it has no flags, either. All of this metadata is therefore made to the project (.csproj) file.

And since there do not seem to be any EnvDTE interfaces to support these project file changes, it seems that the change must be made in the project XML directly. This can cause all kinds of unpredictable problems, the least of which is an ugly dialog box for the user, “Project has changed, reload?” Nonetheless, this is what’s working for us, and it’s better than a broken build that requires us to manually open the .resx file.

The full solution:

param($installPath, $toolsPath, $package, $project)

#script to fix code-behind for resx
set-alias Write-Host -Name whecho
whecho "Restoring resource code-behinds (this may cause the project to be reloaded with a dialog) ..."
$resitems = @{}
foreach ($item in $project.ProjectItems) 
{
    if ($item.Name -eq "Resources") {
        $resources = $item
        foreach ($resitem in $resources.ProjectItems) {
            $codebehinditem = $NULL
            if ($resitem.Name.ToLower().EndsWith(".resx")) {
                $hasCodeBehind = $FALSE
                switch ($item.ProjectItems) { default {
                    if ($_.Name.ToLower() -eq $resitem.Name.ToLower().Replace(".resx", ".designer.cs")) {
                        $hasCodeBehind = $TRUE
                        $codebehinditem = $_
                    }
                }}
                if ($hasCodeBehind -eq $TRUE) {
                    $fn = $resitem.FileNames(0)
                    $cbfn = $codebehinditem.FileNames(0)
                    $codebehinditem.Remove()
                    $cb2 = $resitem.ProjectItems.AddFromFile($cbfn)
                }
                $resitems.Add("Resources\" + $resitem.Name, $resitem.FileNames(0))
                whecho $resitem.Name
            }
        }
    }
}
$project.Save($project.FullName)
$projxml = [xml](get-content $project.FullName)
$ns = New-Object System.Xml.XmlNamespaceManager $projxml.NameTable
$defns = "http://schemas.microsoft.com/developer/msbuild/2003"
$ns.AddNamespace("csproj", $defns)
foreach ($item in $resitems.GetEnumerator()) {
	$xpath = "//csproj:Project/csproj:ItemGroup/csproj:Compile[@Include=`"" + $item.Name.Replace(".resx", ".Designer.cs") + "`"]"
	$resxDesignerNode = $projxml.SelectSingleNode($xpath, $ns)
	
	if ($resxDesignerNode -ne $NULL) {
	
		$autogen = $projxml.CreateElement('AutoGen', $defns)
		$autogen.InnerText = 'True'
		$resxDesignerNode.AppendChild($autogen)
		
		$designtime = $projxml.CreateElement('DesignTime', $defns)
		$designtime.InnerText = 'True'
		$resxDesignerNode.AppendChild($designtime)
	}
	
	$xpath = "//csproj:Project/csproj:ItemGroup/csproj:EmbeddedResource[@Include=`"" + $item.Name + "`"]"
	$resxNode = $projxml.SelectSingleNode($xpath, $ns)

	$generator = $projxml.CreateElement('Generator', $defns)
	$generator.InnerText = 'PublicResXFileCodeGenerator'
	$resxNode.AppendChild($generator)
	
	if ($resxDesignerNode -ne $NULL) {
		$lastGenOutput = $projxml.CreateElement('LastGenOutput', $defns)
		$lastGenOutput.InnerText = $item.Name.Replace("Resources\", "").Replace(".resx", ".Designer.cs")
		$resxNode.AppendChild($lastGenOutput)
	}

}
$projxml.Save($project.FullName)

UPDATE: Just an update on this, we have abandoned this approach to editing the XML. The project XML can be manipulated in-memory using the MSBuild automation object. Hints of what to do are found here:

http://nuget.codeplex.com/discussions/254095

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Upgrade / Update Rooted Android HTC EVO 4G Including HBOOT 2.16 Update

by Jon Davis 10. October 2011 06:50

I am just putting this out there for the Googlebots to pick up because I just went through hell trying to gather this information. The Android rooting community is awfully crude.

I had a somewhat stale version of Unrevoked-rooted Android installed on my HTC EVO 4G phone and it had 2.10.001 of HBOOT installed. Sprint pushed a new system update a month and a half or two months ago, and any such system update requires backing up (Titanium Backup), updating, re-rooting, and restoring. The latest from the Android rooting community is http://revolutionary.io which seems to require v2.15 or v2.16 of HBOOT. In my case, I got this unfriendly error: supersonic with 2.10.001 is not supported at this time.

So the obvious next path to take is to update HBOOT. Google for “how do I update HBOOT” or “update HBOOT”' or “upgrade HBOOT” or “download latest HBOOT”, etc., and you get a gajillion hits to absolute crap. Tons of forum.xda-developers.com forum posts, et al, but with no explanation on how to upgrade HBOOT. Eventually I figured that maybe the latest OTA update package download might bundle in an HBOOT update, so I kicked off a download of PC36IMG_SuperSonic_GB_Sprint_WWE_4.53.651.1_Radio_2.15.00.0808_NV_2.15_release_209995_signed.zip

This seemed to do the trick. Before I ran that, though, I should add, revolutionary.io’s web site referenced an IRC channel. Someone on the Unrevoked team proved INCREDIBLY helpful months ago when that was the primary method of rooting the EVO 4G, so I figured that was a likely good path. All I wanted to do was to validate that the above-mentioned .zip file was the correct approach, as well as seek assistance on steps to properly deploy in case my guesswork fails me.

Unfortunately, the guys I ran into on revolutionary.io team got bitten by the old IRC social crudeness bug. Not only did they complain that my questions were more appropriate for a “general Android discussion channel” and pointed me at http://revolutionary.io/topic.jpg, when I said that it couldn’t be more on-topic since their own EXE indicated that only v2.15/2.16 is supported they not only immediately banned me from the channel but they blocked my IP from their web server. (As if I didn’t have other access points.)

Just be wary. Rude and crude people lurk in those parts.

To root access developers, you might find more success in life if you replace that whole “ban the n00bs” mentality with a donation button.

Currently rated 4.3 by 6 people

  • Currently 4.333333/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

So I Was Wrong About Silverlight On Windows 8 ...

by Jon Davis 26. September 2011 05:28

So the news is already old as of a week ago. Windows 8's shell has no support for Silverlight--it supports HTML5, C++, and its own flavor of XAML + C#, which marks Microsoft's third common XAML flavor (the first two being WPF and Silverlight). And although the desktop flavor of IE10 supports plug-ins, the HTML5 support in Metro comes without plug-in support altogether. I expected otherwise, given the rumors and expectations of others in the industry who expected Silverlight to become WPF's heavily-refactored-by-accident successor.

On the other hand, it makes sense as to why.

Think of Metro as Silverlight's Windows counterpart rather than as Silverlight's would-be host / container. Silverlight is what Metro would have tried to be, but could not fit, on a WP7 device. Metro is built for the Windows shell, Silverlight is built for a web browser and for a mobile device. Metro is what Silverlight would have tried to be, but could not suffice, on an ARM-based tablet. Metro runs XAML + C#. Silverlight runs XAML + C#. Metro hosts HTML5 with WinRT. Silverlight hosts HTML4 in a WebBrowser component with script hooks. Metro hosts native C++ and Direct3D. WP7.x supports XNA and Silverlight 5 supports XNA combinations.

I think you're getting what you want in Metro as Silverlight equivalence but better suited for Windows, except for binary compatibility which is frankly unnecessary and irrelevant. For example, although Silverlight already had a stripped-down flavor of .NET, the uniquenesses of WinRT and WinRT's limitations as its own heavily stripped-down flavor of .NET are appropriate for the Windows Metro shell and not for Silverlight's browser host nor for a phone device.

I'm sorry that this blog post is rather short, but I can't get this notion of Metro being Silverlight's counterpart rather than its host out of my mind. It makes perfect sense to me, and I think it should put people at ease.

By the way, for those who are concerned about the XNA support in Silverlight 5 not being available in Metro (few C# developers like C++), give it time, the C++ support will enable shims. If nothing else we can use future Metro ports of Adobe AIR, and Adobe has just introduced 3D performance that is thousands of times faster than current flavors of Flash / AIR.

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

C# | Silverlight | Windows | Metro


 

Powered by BlogEngine.NET 1.4.5.0
Theme by Mads Kristensen

About the author

Jon Davis (aka "stimpy77") has been a programmer, developer, and consultant for web and Windows software solutions professionally since 1997, with experience ranging from OS and hardware support to DHTML programming to IIS/ASP web apps to Java network programming to Visual Basic applications to C# desktop apps.
 
Software in all forms is also his sole hobby, whether playing PC games or tinkering with programming them. "I was playing Defender on the Commodore 64," he reminisces, "when I decided at the age of 12 or so that I want to be a computer programmer when I grow up."

Jon was previously employed as a senior .NET developer at a very well-known Internet services company whom you're more likely than not to have directly done business with. However, this blog and all of jondavis.net have no affiliation with, and are not representative of, his former employer in any way.

Contact Me 


Amazon Collection

Most Recent of Many Library Investments

Calendar

<<  May 2013  >>
MoTuWeThFrSaSu
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789

View posts in large calendar