Allen Conway's .NET Weblog

Exploring all things .NET and beyond...

Get A Silverlight Control's Current Instance For Communicating Via The HTML Bridge

If you have a SilverLight control on an ASP.NET webpage, odds are eventually you will need to communicate with it, and this is done via JavaScript and the HTML Bridge. However you might find that the accessing the control's current state after user manipulation is not as straight forward as the documentation from the MSDN indicates.

In the MSDN and most examples, the suggestion is made that you explicitly register an instance of a scriptable type (your control's class) in the App class or the Page class. However there is a big difference on these (2) and also in the exact instance that you choose to register.

If in my control the main class is named 'MySLControl', so I decide to register its type in the 'Application_Startup' event of App.xaml like below:


Dim _MySLControl As New Silverlight.Custom.MySLControl
HtmlPage.RegisterScriptableObject("SLControl", _MySLControl)
The above will work perfectly and you will then be able to access your exposed <ScriptableMember()> types from JavaScript. However, there is a catch - the registered instance is a New instance of MySLControl so it will not contain the state of the control when called by JS.

So let's say you have a custom built online MP3 player you built with a 'Playlist' created by the user within the control. You want to use the HTML Bridge from your hosting ASP.NET app to communicate with the control and get some details on the playlist. If you access the registered control instance as coded above, you will not have access to any of the control's state after the user has interacted with it. Why? We registered a New instance and are not using the actual control's instance.

The change is (2) fold: First, move the registration of the type to a late event in the Page (control) itself like a wired up 'ControlLoaded' event as typical for many Silverlight controls. Second, register the current instance of the control and not a new instance. The code is displayed below:

Private Sub ControlLoaded(ByVal sender As Object, ByVal e As RoutedEventArgs)
'Register this control type so it can be accessible via JavaScript.
'This allows other platforms like ASP.NET to have a medium to communicate and raise events within the control.
'MUST use this instance or the current control state will not be accessible by the JS calling it via the HTML bridge.
HtmlPage.RegisterScriptableObject("SLControl", Me)
End Sub
The result? When you access your Silverlight control via JavaScript you will have access to the control in its current state including any interactions or manipulation done to the control by the client.

Accessing Instance Properties in Silverlight from JavaScript

I have been messing around with the HTML bridge between Silverlight and JavaScript recently and have a few different posts on this topic that may help others. While those doing Silverlight are starting to see "the writing on the walls" as they say and may become the next technology to 'retire' akin to ActiveX controls from the IE4 days, it is still quite prominent as of this post so topics and discussion on it are well worthwhile.

There are several posts about exposing methods and properties to JavaScript from Silverlight so I will not get into that here. However most of the examples are really 'vanilla' as usual and don't offer more than the basic information.

One thing I wanted to do was access an instance property in Silverlight from JavaScript. There really is no major trick to it and it is as straight forward to access as it should be... for once.

So let's begin by looking at the exposed properties on the Silverlight control below. There is a simple 'String' and then an instance property of 'MyCustomClass' which is the focus of this post. Let's assume 'MyCustomClass' has (2) simple String properties on it: 'Name' and 'Address'.

<ScriptableMember()>
Public Property Description As String

<ScriptableMember()>
Private _MyClass1 As New MyCustomClass
Public Property MyClass1() As MyCustomClass
Get
Return _MyClass1
End Get
Set(ByVal value As MyCustomClass)
_MyClass1= value
End Set
End Property
Next we need to register our class to be accessible by script as well which is shown below. This can be done in the constructor of the control. 'Me' (or 'this' for C#) is my Silverlight control class instance behind the .xaml control.

HtmlPage.RegisterScriptableObject("MySLControl", Me)
Now you *might* think you need to register another member above for the instance property, but you do not need to do that. You can drill down to it through the main class instance exposed as a scriptable member as shown below:
//Get instance of the Silverlight File Upload Control
var SLControl = document.getElementById("SilverlightControl");
if (SLControl != null)
SLControl.Content.MySLControl.Description = "Blah";
//Drill down through the instance property exposed on the Silverlight control
SLControl.Content.MySLControl.MyClass1.Name = "Allen Conway";
SLControl.Content.MySLControl.MyClass1.Address = "123 Oak Street";
One thing to take note of - notice how I used a long hand property for 'MyClass1' rather than an AutoProperty. If you use an AutoProperty and can't provide an object that has been instantiated for its backing value by default or when setting its value, the JavaScript block will throw an error stating "Object reference not set to an instance of an object" when accessing the MyClass1 instance properties.

That's all there is to it. You can just drill down to the instance property through the registered instance of the scriptable type.

Upcoming Developer Events in Central Florida

There are several very nice events in the Central Florida area for developers in the upcoming months and 2012 year. The 1st (2) events below are *free* so there is no reason not to attend them if you are within a 50-75 mile range and are able to make it. The latter (2) are phenomenal conferences for the .NET and Microsoft Community and do have a registration fee, so see if your employer will put out for some training!





Orlando Code Camp: March 31, 2012 at Seminole State College, Sanford, FL.
This will be my 3rd year at CodeCamp and I have to say how impressed I am by the volunteers of the community to put on a 1st class event like this. It is every bit on par with a paid conference like VSLive and in fact has some of the same presenters like John Papa. If this is the only event you can attend in a year it will be well worth your Saturday. The event is free.





Windows Developer Camp: April 11, 2012 at the Royal Pacific Resort, Orlando, FL.
This touts itself as a Windows 8 event helping developers to get primed on technologies like Metro Apps, HTML5, JavaScript, XAML, and much more. The event is free and a meal is included.





Microsoft TechEd: June 11-14, 2012 at the Orange County Convention Center, Orlando, FL.
This is a premier Microsoft sponsored event for the development and IT industry as a whole. I have not attended the TechEd conferences before, but I know many of the elite in our industry do and it is sure not to disappoint.





Visual Studio Live!: December 10-14, 2012 at the Royal Pacific Resort, Orlando, FL.
This is a 5 day full conference that I have attended 4 times in the past. It does have a registration fee, but if you sign up early you can save money. Their site describes the conference best: "This event offers 5 days of over 60 educational sessions in tracks such as HTML5, Cloud Computing, Windows 8 / WinRT, and — of course — Visual Studio 2010+/.NET4+. Attendees receive a first-rate education, along with exclusive networking opportunities and one-on-one time with speakers that prepare them for what's now, new and next in the .NET development platform."


In addition to the live events above you can always check out the plethora of online training and content available from Microsoft below:

Microsoft Events

I Want To Run An Agile Project... Really I Do!

I had been meaning to speak briefly to Agile Project Management, so when I received some information in the mail today about the Agile Project Management Certification Workshop I knew it must be an omen or something.

As I have watched .NET mature over the last 10 years, and watch developers get more immersed in the technology that is not so "new" like it was in the early 2000's, a lot of focus has shifted to incorporating more advanced architectures like MVC, MVP, MVVM, and DDD and project methodologies like Agile. I personally think this is all great stuff, and am enjoying the whole community blossom and grow on a broad scale like never before.

Unfortunately where as implementing a new application architecture is a 'behind-the-scenes' decision not having a direct impact to the end client, changing the way we run our projects most certainly does. Enter Agile. This is not new either, but it is gaining acceptance in .NET shops and being used by my estimation at a rapid pace, and for good reason.

The "Waterfall" model or even Iterative development or "Mini-Waterfalls" still have their challenges, a lot of which I feel are solved by Agile Project Management. However as mentioned above attempting to run projects using Agile involves heavy participation by the customer and a paradigm shift in thinking. This change is not as difficult for software development teams as it is for the customers because we are technical and think methodically in nature so it is a good fit.

The abandonment of having that 'bulls-eye' finish date or being able to say "Here is what I want, see you in 6 months!" is too much to digest for many customers. I heard once that if anyone ever asks "When will the project be all done?", the response should be "Next year on May 24th at 2:38 P.M.." This in turn should make a question arise like, "Geeze, how do you know the time so preciously?", and in turn gets "Exactly, we can't and we don't provide that specific of a date."

Shifting from any type of traditional Waterfall to Agile takes total commitment and backing from both software development teams, management, and the customers. If any part of this commitment fails then it will probably not end up in success. As I heard at VSLive! and on some MSDN webcasts, try not to become a "We do Agile Scrum but, ...." team. There are no "buts", just commitment to doing it right. I hear this common theme often, and always present the question: "But how do we get Management and the Customers to buy into this shift in thinking and managing projects?" The answer: "Terrific question, and it's hard. There is no single answer to that." Magic and persuasion I suppose.

Truly technical shops or large IT organizations have probably already adapted Agile methodologies on the software development teams knowing of its success to creating high performance software development teams that are constantly communicating and delivering. However the less technical companies or ones that have a compressed management style used to having things done the old fashioned way will have an uphill battle implementing Agile.

Which leads me to the best part of this post. At VSLive! in Orlando last December the instructor of a TFS course shared a link on YouTube called "I want to run an agile project." It pretty much highlights perfectly the challenges associated with implementing Agile Project Management. If you are a software developer that has struggled with any of these challenges or have interest in Agile development, watching the link below offers a lot of head nodding and laughs. Super big thanks to the creators as they hit the nail on the head and presented this perfectly!


One Of A Thousand Possible Reasons For The "Invalid Postback or Callback Argument" Exception

The "Invalid postback or callback argument." exception in .NET can be caused by a slew of different reasons stemming from ASP.NET not being able to validate that a control event originated from the user interface that was rendered by that control. The most common solution offered as we all know is to set Page.EnableEventValidation = "False". Wrong! That's not a good idea from a security standpoint.

The better option is to determine what is causing the issue, and the bad news is debugging the code will not typically lead to the answer. You have to understand the code you have written and its relationship to this property to think about what you have done to cause this issue.

My most recent cause and solution? I made an update to a control outside the UpdatePanel housing a control that initiated the event, and subsequently after postback had completed then redirected to another page from an ASP.NET menu. It immediately threw the "Invalid postback or callback argument" exception. The fix? Add the appropriate AsyncPostBackTrigger on the other UpdatePanel with the control being updated with the event that is doing the updating. As soon as I did this, I was obeying all the good security rules and no need to set Page.EnableEventValidation = "False" which I never want to do as a lazy resort because I can't figure out what I did incorrectly.

Should I Place My Business Logic In Code Or In Stored Procedures?

I see this age old question asked on forums, LinkedIn conversations, interviews, and in general developer discussions. To tell you the truth it has been discussed 1000 times before and I am going to add one more to the pile here.

This is a great debate/conversation, and I have been a part of it several times myself as well. I can honestly say there is no 'right' or 'wrong' in my opinion (OK maybe there is but let me be a little PC here as to not to offend those DB folks right from the start), but only 'pros' and 'cons' to each method. I think both have their advantages and disadvantages, and no option really screams out as the obvious choice on the surface unless there is say some significant performance advantage one way or the other. However I have my bias on 1 side of the argument as I will detail below.

In my experience this is usually who goes on each side of the debate: people with a stronger or more prominent SQL/Database background will opt for placing all the logic in the database where as true software engineers will tend to place those rules within the application and apply the appropriate architecture, design patterns, and frameworks to organize and describe them.

At the highest level Database folks will argue to place that logic in stored procedures or the database because then you can "make changes on the fly" without the hassle of "code recompile and pushing out new releases", where developers that want that logic in code will argue TSQL is such a limited language to debug and express complex business rules that can be evaluated so much better in code.

Well as far as I am concerned that is about as far as that side's (Database crowd) argument goes for me. While their argument is valid, recompiling and redeploying an app because of rule changes is typically not an impossible task. In fact with today's modern deployment options regardless of technology being used this argument is not as strong as it used to be.

In fact the whole idea of "making changes without redeployment" or "changes on the fly" is a bit skewed to begin with. Code of any type should never be changed in a production environment without being tested. Managed code is more likely to be tested using unit tests or at a minimum running the application through some end-user tests before deployment. The temptation to change a stored procedure without testing it fully is ever present, and without a stringent environment with DBAs locking down the database, this option could be exercised all too easily and is a bad idea.

As a developer I tend to try and place these rules (business rules, calculations, math, etc.) in .NET managed code. TSQL is not the easiest language to explain and implement complex business rules and is also more difficult to debug and test. My philosophy is typically to get the raw data back to the code and then manipulate it from there. You have so much more power with the .NET framework and managed code to explain the rules in code than with TSQL. While it is possible with TSQL, have you ever seen one of these 500 line stored procs with a gazillion rules that some database person was flexing their muscle at? Yuck! We are in the business of writing well formed code using OO principals and this is just not possible using TSQL and database languages.

Which side do I fall on? That's easy. I am a developer and engineer at heart and I believe in using the right design and architecture, and that those business rules (or a majority of them) should reside within the application. What's the database for? Getting data and executing some logic, but the brain of solving the business problem for me is not going to be within a stored procedure, view, or user defined function. The only time I flex a tad on this is with 1 off custom queries for say reporting where the Object Model does not currently support the data needed to create the output. In this case I might extend the logic a bit on the database side. If I can extend my Object Model to support the reporting without an extreme amount of work then by all means I will do it. However, when at all possible I keep any business rules or logic within the application.

So the answer is not always so straight forward, but hopefully this post help you think about where this logic should reside (......in the code. Wait, did I just say that!?!?). Now go ask this question on a SQL forum or blog and see what response you get. It will probably be along the lines of... "Put it all in Stored Procedures!!" Have fun coding :P

Applying and Using a SSL Certificate With A Self-Hosted WCF Service

(Please read my 1st post on this topic called Create A Self-Signed SSL Certificate Using IIS 7 if you need to know how to create a self signed SSL certificate)

If you create enough WCF services eventually you are probably going to need to self host your WCF Service as opposed to using IIS. The most common way of doing this is probably a Windows Service which is a great environment to host WCF services as they automatically begin and end with the server and OS being up or down and are always running in the background.

However when using a Windows Service you might find it is not as straight forward to use a SSL certificate with your exposed WCF service. This is true as there is no wizard style interface for applying SSL certificates to Windows Services like IIS provides, however after following the steps outlined here you will see that it is not so bad. Overall the process is easy to repeat for multiple services and ports once you are used to doing it.

The 1st step is to configure your WCF service to use a binding and configuration that supports HTTPS and SSL. For this example, we will use a simple WCF service that uses the 'basicHttpBinding' configuration. As with any WCF configuration, remember the references to the contract Interface and implementing class are case sensitive so if you run into any errors check your spelling. The main configuration changes to allow HTTPS on the service are to change the metadata publication binding to 'mexHttpsBinding' and by setting 'httpsGetEnabled' to 'true' on the service behavior. The SSL is handled by transport-level security using certificates. The entire service configuration is below:
 <system.serviceModel>

<!--WCF Services Defined-->
<services>
<service name="WcfServiceTest.MyWCFService"
behaviorConfiguration="MyWCFServiceBehavior">
<endpoint address=""
binding="basicHttpBinding"
bindingConfiguration="BasicHttpSSLBinding"
contract="WcfServiceTest.IMyWCFService" />
<endpoint address="mex"
binding="mexHttpsBinding"
contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="https://DevMachine1234:8050/WCFServices/MyWCFService" />
</baseAddresses>
</host>
</service>
</services>

<!--WCF Service Behavior Configurations-->
<behaviors>
<serviceBehaviors>
<behavior name="MyWCFServiceBehavior">
<serviceMetadata httpsGetEnabled="true" httpGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>

<!--WCF Service Binding Configurations-->
<bindings>
<basicHttpBinding>
<binding name="BasicHttpSSLBinding">
<security mode="Transport" />
</binding>
</basicHttpBinding>
</bindings>

</system.serviceModel>
Notice the 'baseAddress' value I used. The most important part here is that the host name of the service must match that of the SSL certificate I bind to the port selected. In my instance the machine name is 'DevMachine1234' and so is the name of my SSL certificate. You can actually create a SSL certificate named 'localhost' if you prefer and use that instead. If this is a true production service and you make the service address MyWcfService.com, then you will need to get a SSL cert with a matching name from a provider like Verisign or GoDaddy. Test this all and have a complete understanding before spending money on SSL certificates; no use wasting money on a misunderstood process.

Also notice I selected port '8050'. This is arbitrary, but remember there are certain port restrictions, and only 1 SSL certificate can be bound to any single port. We now need to apply the SSL certificate for our service (we are using a self-signed certificate for testing purposes) to the 8050 port before we can test our service.

The 1st thing we need is the Thumbprint value from the SSL certificate. We can use IIS to look at the installed SSL cert and grab the thumbprint value. Open up IIS, and select 'Server Certificates'. Double-click on the appropriate SSL certificate and go to the details tab. Scroll to the bottom and find the 'thumbprint' value of the certificate. Copy it out from the 1st character to the last into notepad and remove all spaces. Take caution to not copy the 1st space as it will translate into a '?' (question mark) when pasted into the command window to apply the SSL certificate in a later step. Save this for the next step.


Begin by clicking on the 'Start' button in windows and type in 'CMD' in the search box but do not press enter yet. Right-click the 'cmd' program and select 'Run as administrator' as shown below. This ensures we add the SSL certificate to the port with proper rights.


We need to use the 'netsh' tool (replacement in W2K8 and Windows 7 for the old httpcfg.exe tool) to apply the SSL certificate. We need the certificate thumbprint (gathered above) and an application ID value. The easiest way to get the 'appid' value is to use the GUID in the 'AssemblyInfo' file for the WCF project as pictured below. Copy it out as well and have ready for applying to the command window in the next step.


The command to add the SSL certificate to the port we configured in our WCF service is as follows:

netsh http add sslcert ipport=0.0.0.0:8050 certhash=3e49906c01a774c888231e5092077d3d855a6861 appid={2d6059b2-cccb-4a83-ae08-8ce209c2c5c1}

After applying the command and pressing enter you should see a message that the certificate was successfully added.


If you want, you can verify it has been added and view any SSL certificate that has been applied by entering the following command:

netsh http show sslcert

You will see the command window output in groups displaying any SSL certificates that have been applied as shown below. Notice you can see the SSL certificate 'hash' value which is the thumbprint value we used.


If you were doing this process in a production environment or on a remote server, make sure to apply the appropriate SSL certificate that has been imported and installed on the server 1st, to the port you need prior to starting the Windows Service (it actually will not work without it).

At this point we are ready to start our service on our local machine. In VS.NET I set my service (not the host in this instance) to be the startup project. I then begin debugging. You will notice the 'WCF Test Client' tool will pop-up and display all locally hosted services. This is probably were most folks will encounter some errors. Read the error description because they are typically meaningful and give direction on what to fix. Odds are it is caused by the SSL certificate not being applied to the same port configured, a mismatched name on the certificate to the service's domain name, or a mistake in configuration. Go over all steps again to make sure everything is correct. As you can see below our WCF service exposed via a HTTPS endpoint is up and running.


The last step to verify everything is working properly is to copy the address of the locally hosted service and consume it in another test application.

Add the copied address as a service reference to the project and make sure you do not receive any exceptions.

The successfully added service will be shown in Solution Explorer with the name you provided.


My recommendation is to get all of this working as I did in a local test environment 1st and understand all of the pieces. For those totally new to WCF it can be a lot to digest and fixing problems can take time and a deeper understanding of WCF so be patient.

For more information on the other commands available to the netsh.exe command line tool (like removing SSL certificates from a port), please see the following reference: