by Alex Feldstein (noreply@blogger.com) at May 21, 2012 05:00 AM
Egret at the St. Augustine rookery
A couple of announcements about our fall conferences:
Remember, if you register for one conference, you’re free to attend sessions in the other conference as well: it’s BOGO (buy one, get one free). There are some sessions specifically intended for VFP developers, including Project PolarFox: State of the Union and Xbase++ 2.0 from a VFP Developer’s Perspective. Also, some of the Southwest Fox session will appeal to Xbase++ developers, such as Advanced Topics in Mercurial: Taking it to the Next Level, jQuery 101, and Office Automation Without Office.
I personally hope you’ll head right over to the brand new online registration form developed by my team at White Light Computing. You’ll receive an email when you submit your registration confirming we received it. You’ll get a confirmation message with a paid invoice as your receipt after we process the payment.
I also want to make a brief plea to you as well. We encourage you to register as soon as possible. Our final commitment to the conference center is due by July 2. In order to confirm that commitment, we must have a sufficient number of people registered by then to ensure that the conference is financially sound. So please register soon and spread the word about Southwest Fox to all the Visual FoxPro developers you know, and likewise for the Southwest Xbase++ conference.
Thanks for the continued support!
Only 152 days until we gather in Gilbert!
<iframe allowfullscreen="allowfullscreen" frameborder="0" height="360" src="http://www.youtube.com/embed/kSgrzMQv2Mc?rel=0" width="640"></iframe>
by Alex Feldstein (noreply@blogger.com) at May 19, 2012 09:05 PM
A couple of announcements about the fall conferences:
First, registration is now open for both Southwest Fox and Southwest Xbase++. Registrations have been already been pouring in, which is great news.
I blogged about this last year, but I think it bears repeating. Last year was a tough, scary year for us. By mid-August, we were in full panic mode, as we were so far below breakeven that it looked like a five-figure loss for us. Fortunately, a larger-than-usual number of people signed up after September 1; that combined with an increase in sponsorship took us over the top. So, one thing I ask: if you love Southwest Fox like we do, and want to see it continue, do us a favor and register early this year. That would take out the panic for us and allow us to plan for the type of conference we really want to host.
Second, speakers and sessions for Southwest Xbase++ are now available. Remember, if you register for one conference, you’re free to attend sessions in the other conference as well: it’s BOGO (buy one, get one free). There are some sessions specifically intended for VFP developers, including Project PolarFox: State of the Union and Xbase++ 2.0 from a VFP Developer's Perspective. Also, some of the Southwest Fox session will appeal to Xbase++ developers, such as Advanced Topics in Mercurial: Taking it to the Next Level, jQuery 101, and Office Automation Without Office.
I think it’s cool that we’ll have a whole new set of attendees (the Xbase++ folks) at the conferences this year. It’ll give us more chances to talk to fellow developers and share cool ideas.
Tamar, Rick, and I are all looking forward to seeing you in Phoenix this October!
by Doug Hennig (noreply@blogger.com) at May 18, 2012 04:58 PM
ORBx, my fav FSX flight sim 3rd party developer released the Creswell, Oregon airport today. Wow!
These are my first screenshots. See for yourself how detailed this is, with little or no impact in fps!
by Alex Feldstein (noreply@blogger.com) at May 17, 2012 11:17 PM
As you may know, AppHarbify is built with Nancy. One of the reasons I decided to build it in Nancy, other than the fact that Nancy is awesome, was that I wanted to put together a real project that can be used as an example of Nancy in action. All the code for AppHarbify is available on GitHub.
To go with that I am planning to put together some blog posts talking about various aspects of the code.
To start with I am looking at sessions.
Nancy ships with a single session provider implemented, CookieBasedSessions. You can of course add your own.
This provider stores the session, encrypted, in the users cookies. Which is really not too bad of a solution to get started. You are up and running with a single line of code added to your ApplicationStartup method in your Bootstrapper.
<script src="https://gist.github.com/2700887.js?file=bootstrapper.cs"></script>
Once enabled, you can simply access the Session property on Request.
Request.Session["Key"]
Now you don’t want to store too much data in a cookie-based session like this, as every request is sending the data back across the wire. Also it is theoretically possible the encryption could be broken. Side note: You can control the encryption provider with an optional second parameter to .Enable(). If you do not, then a new key is generated each time the app starts, invalidating all existing sessions.
If you do any work with sessions, you are likely to need to test them eventually. While the mechanism is a bit awkward, it is essentially pretty easy. My preferred method is to attach an event to the .Before pipeline in your testing Bootstrapper that injects the required session into the request.
<script src="https://gist.github.com/2700887.js?file=SessionTesting.cs"></script>
By adding this simple extension method and calling it on your Bootstrapper whenever you want to test a route that needs session information, you can very simply abstract away your real session storage mechanism without adding more layers of abstraction to your actual codebase.
While AppHarbify is currently running along fine using these cookie based session, for the reasons I have stated above it is not ideal. So the plan is to write Redis based session mechanism and take advantage of the easily installed Redis add-on at AppHarbor. Of course this code will be open-source and released independently of AppHarbify as a nuget package. So watch out for that!
by Chris Sainty (noreply@blogger.com) at May 17, 2012 07:21 AM
So I ran into an interesting behavior today as I deployed my first MVC 4 app tonight. I have a list form that has a filter drop down that allows selection of categories. This list is static and rarely changes so rather than loading these items from the database each time I load the items once and then cache the actual SelectListItem[] array in a static property.
However, when we put the site online tonight we immediately noticed that the drop down list was coming up with pre-set values that randomly changed. Didn't take me long to trace this back to the cached list of SelectListItem[]. Clearly the list was getting updated - apparently through the model binding process in the selection postback.
To clarify the scenario here's the drop down list definition in the Razor View:
@Html.DropDownListFor(mod => mod.QueryParameters.Category, Model.CategoryList, "All Categories")
where Model.CategoryList gets set with:
[HttpPost] [CompressContent] public ActionResult List(MessageListViewModel model) { InitializeViewModel(model); busEntry entryBus = new busEntry(); var entries = entryBus.GetEntryList(model.QueryParameters); model.Entries = entries; model.DisplayMode = ApplicationDisplayModes.Standard; model.CategoryList = AppUtils.GetCachedCategoryList();
return View(model); }
The AppUtils.GetCachedCategoryList() method gets the cached list or loads the list on the first access. The code to load up the list is housed in a Web utility class. The method looks like this:
/// <summary> /// Returns a static category list that is cached /// </summary> /// <returns></returns> public static SelectListItem[] GetCachedCategoryList() { if (_CategoryList != null) return _CategoryList; lock (_SyncLock) { if (_CategoryList != null) return _CategoryList; var catBus = new busCategory(); var categories = catBus.GetCategories().ToList(); // Turn list into a SelectItem list var catList= categories .Select(cat => new SelectListItem() { Text = cat.Name, Value = cat.Id.ToString() }) .ToList(); catList.Insert(0, new SelectListItem() { Value = ((int)SpecialCategories.AllCategoriesButRealEstate).ToString(), Text = "All Categories except Real Estate" }); catList.Insert(1, new SelectListItem() { Value = "-1", Text = "--------------------------------" }); _CategoryList = catList.ToArray(); } return _CategoryList; } private static SelectListItem[] _CategoryList ;
This seemed normal enough to me - I've been doing stuff like this forever caching smallish lists in memory to avoid an extra trip to the database. This list is used in various places throughout the application - for the list display and also when adding new items and setting up for notifications etc..
However, it turns out that this code is clearly causing a problem. It appears that the model binder on the [HttpPost] method is actually updating the list that's bound to and changing the actual entry item in the list and setting its selected value. If you look at the code above I'm not setting the SelectListItem.Selected value anywhere - the only place this value can get set is through ModelBinding. Sure enough when stepping through the code I see that when an item is selected the actual model - model.CategoryList[x].Selected - reflects that.
This is bad on several levels: First it's obviously affecting the application behavior - nobody wants to see their drop down list values jump all over the place randomly. But it's also a problem because the array is getting updated by multiple ASP.NET threads which likely would lead to odd crashes from time to time. Not good!
In retrospect the modelbinding behavior makes perfect sense. The actual items and the Selected property is the ModelBinder's way of keeping track of one or more selected values. So while I assumed the list to be read-only, the ModelBinder is actually updating it on a post back producing the rather surprising results. Totally missed this during testing and is another one of those little - "Did you know?" moments.
So, is there a way around this? Yes but it's maybe not quite obvious. I can't change the behavior of the ModelBinder, but I can certainly change the way that the list is generated. Rather than returning the cached list, I can return a brand new cloned list from the cached items like this:
/// <summary> /// Returns a static category list that is cached /// </summary> /// <returns></returns> public static SelectListItem[] GetCachedCategoryList() { if (_CategoryList != null) { // Have to create new instances via projection // to avoid ModelBinding updates to affect this // globally return _CategoryList .Select(cat => new SelectListItem() { Value = cat.Value, Text = cat.Text }) .ToArray(); }
…
}
The key is that newly created instances of SelectListItems are returned not just filtered instances of the original list. The key here is 'new instances' so that the ModelBinding updates do not update the actual static instance. The code above uses LINQ and a projection into new SelectListItem instances to create this array of fresh instances. And this code works correctly - no more cross-talk between users.
Unfortunately this code is also less efficient - it has to reselect the items and uses extra memory for the new array. Knowing what I know now I probably would have not cached the list and just take the hit to read from the database. If there is even a possibility of thread clashes I'm very wary of creating code like this. But since the method already exists and handles this load in one place this fix was easy enough to put in.
Live and learn. It's little things like this that can cause some interesting head scratchers sometimes…
Previous award recipients wish to continue the award and have created a committee to select a recipient for 2012. The committee consists of all 11 living previous recipients, Alan Griver (yag), and Sergey Berezniker representing the FoxPro community. To submit your nominations for the 2012 recipients, please email Doug Hennig (dhennig@stonefield.com) by June 15, 2012.The FoxPro Lifetime Achievement Award honors those individuals who have contributed a great deal to the FoxPro community over the years. See http://fox.wikis.com/wc.dll?Wiki~FoxProCommunityLifetimeAchievementAward~VFP for previous award recipients. These recipients wish to continue the award and have created a committee to select a recipient for 2012. The committee consists of all 11 living previous recipients, Alan Griver (yag), and Sergey Berezniker representing the FoxPro community.
To submit your nominations for the 2012 recipients, please post a comment here by June 15, 2012.
by Doug Hennig (noreply@blogger.com) at May 16, 2012 03:55 PM
The FoxPro Lifetime Achievement Award honors those individuals who have contributed a great deal to the FoxPro community over the years. See http://fox.wikis.com/wc.dll?Wiki~FoxProCommunityLifetimeAchievementAward~VFP for previous award recipients. These recipients wish to continue the award and have created a committee to select a recipient for 2012. The committee consists of all 11 living previous recipients, Alan Griver (yag), and Sergey Berezniker representing the FoxPro community.
To submit your nominations for the 2012 recipients, please email Doug Hennig (dhennig@stonefield.com) by June 15, 2012.What is good code? If it gives the correct result, but takes a convulted route to get there, is the code good? I’ve maintained for years that if the code yields the correct result, the code is right, but it must be performant and written following best practices and coding guidelines to be good.
I’ve recently been doing maintance on an old application. This is a C# WinForms application. It uses Click Once for deployment and all data access is via WCF services connecting to SQL Server on an internal server. The nature of the maintance is to yank out all the WCF and replace with direct SQL calls. (It’s not that WCF is bad, but it’s over kill for this app and it was poorly implemented.) Yesterday, I came across two examples of bad programming. So bad, that I had to share.
Here’s the first. I was looking through the data update code and found a method in a particular class. The first line in the method is:
if (true)
Um.. ok. If anyone can make a case that true can be false, I’ll put this line of code back in.
The second is much worse. It was an overloaded class constructor. One of the overloads had 144 parameters. Yes, you read that right. 144 parameters. It was a class that mapped to a table in the database, each parameter is a field in the database. What did this method do? Saved the value of each field to a property on the object. This code was written pre-Entity Framework, but what’s wrong with using a DataTable and pass that around? Here’s some advice for you. Anytime you get more than four or five parameters, it’s time to rethink the entire structure of the method and maybe even the class itself.
I’m back working on the app today, but I’m almost afraid to go back in. I have no idea what else is lurking in the depths of this code.
With the newest version of the Open Data Protocol (OData), Microsoft is bringing a richer data experience for developers, information workers and data journalists to consume and analyse data from any source publishing with the OData protocol. The goal is not to hide your data and keep it locked away, but to curate the data you provide to your partners, customers and/or the general public. By allowing a curated data experience, you will generate more revenue and allow your data more widespread adoption…more at the link below:
by Alex Feldstein (noreply@blogger.com) at May 15, 2012 09:47 AM
An important goal of AppHarbify is to make as much open source software as possible be AppHarbor-friendly. To speed this process along I will be creating and/or finding many libraries to solve common problems.
The first problem I have tackled is handling connection strings with Entity Framework. Specifically conventions based Code-First EF.
AppHarbor already has quite an elegant solution where you log into the Sequelizer add-on and set your desired connection string, then at deployment that connection string is either inserted or updated with the connection details for your instance.
Unfortunately AppHarbify can not rely on this mechanism as it can not set configuration variables inside an add-on.
What I found was a static property Database.DefaultConnectionFactory which holds the factory EF uses to create its database connections.
It was then a simple matter of detecting if we are on AppHarbor (by the presence of the AppSetting which AppHarbor stores the connection string in) and then replacing this factory with a new one that creates connections from the AppSetting.
https://github.com/csainty/AppHarbify.Tools/blob/master/src/AppHarbify.EF/ConnectionFactory.cs
To make this as simple as possible I then bundled this up as a NuGet package AppHarbify.EF.
Once installed it is a one-liner to enable your application to use the connection string in web.config when not on AppHarbor, and switch across to their AppSetting when you are.
AppHarbify.EF.ConnectionFactory.Enable();
There is one little snag with this approach. Migrations. The Migrations package, for reasons I have not yet investigated, chose to use their own mechanism for fetching the connection to the database. One that very strictly follows the convention of a connection string named after your DbContext.
So for Migrations to work, you need to strip the connection string out of your web.config when it is deployed too AppHarbor. With no connection string present it will then fallback through other means of creating the connection and settle on one that works for us. If AppHarbor is your only deployment target, this is simple. See https://github.com/csainty/JabbR/blob/AppHarbify/JabbR/Web.Release.config#L18
If you need to handle multiple deployment locations then this is going to get more tricky. I am hoping that the EF team can unify behind one strategy for database connection creation and make it extensible.
by Chris Sainty (noreply@blogger.com) at May 15, 2012 04:27 AM
On Friday last week I delivered a webcast on the new LightSwitch features in Visual Studio 11 beta. I think it went pretty well considering it was the first time I had done the session end-to-end :-). You can now view the on-demand webcast here:
(Click the “register” button, log in, and then select “download”.)
In the session we built an application called “Media Mate” that connects to the Netflix OData source to keep track of favorite movies and music. I showed off new features around all our OData work like how to consume external OData services. I also demonstrated how LightSwitch creates its own OData services adhering to your business rules and security settings so that other clients on different platforms can access your middle-tier easily and securely. I showed off some of the new UI enhancements and business types as well as some of the new deployment enhancements. I attached the presentation slides to the bottom of this post.
One demo hiccup happened where I messed up the search ability over the Netflix data. Doh! What I ended up doing is unchecking the IsSearchable property on the Title entity in the data designer which subsequently disabled the searching on the screen. So it was user error, not a beta bug ;-). At any rate, I think folks got the point. By the way, there are a lot of things you can do to improve search query performance in LightSwitch and I’ll follow up with a post about that soon.
I also demonstrated the updated Contoso Construction sample that you can download here:
Contoso Construction - LightSwitch Advanced Sample (Visual Studio 11 Beta)
For more information on the new features I demonstrated please see:
Also don’t forget to visit the LightSwitch Developer Center, your one-stop-shop for learning all about LightSwitch.
Enjoy!
Here's a little not so well known tip that's useful if you're using Web Connection: When output is rendered, the output automatically expand URLs that use the ~/path syntax, expanding any URLs found to fully application relative URLs on the page.
What it does is that you can write URLs like this (assuming a virtual directory of wconnect):
<a href="~/WebControls/Helloworld.wcsx">Hello World</a>
and expand that URL out to:
<a href="/wconnect/WebControls/Helloworld.wcsx">HelloWorld</a>
~/ paths basically say: Fix up the ~ to mean the base path of my Web Application. This allows you to create application rooted URLs consistently regardless of which virtual directory or root folder the URL is called from. This different than relative paths which depend on the current location of the page that is loaded in the browser - the path generated is a Web server root relative path that was generated by the server based on the active application's path.
This means if your app runs in a virtual directory called wconnect the root path resolves to /wconnect (root folder/wconnect subfolder). If you're running in the root of the site, the root path resolves to /. Why should this matter? If you're developing applications that target different environments the base path of the Application might change. For example, you might develop your application in a virtual directory for development, but deploy the live application into a root Web, or a virtual with different names. Using ~/ urls, no changes are required when the application is moved to the live server.
Web Connection 5.0 also introduced a code based equivalent in Process.ResolveUrl():
lcUrl = Process.ResolveUrl("~/WebControls/HelloWorld.wcsx")
which accomplishes the same thing for you in code so you can use this function for creating root relative paths from your code. This is especially useful for generic and reusable code which may not know where it is running from. The Web Control framework makes extensive use of ResolveUrl for any URL properties on which it always calls ResolveUrl(). ResolveUrl() ignores full path urls if passed and returns them as-is. Urls that contain ~/ in the path are translated.
Note that this feature started out as a feature specific to the the Web Control Framework, but it since then has migrated into the core framework and the wwPageResponse/wwResponseString objects to post-process in all output generated through the Response object. This means it works for Web Control Framework Pages, raw Response.Write() output, templates and scripts etc. It's only applied to HTML output when the Content Type is set to text/html.
Note that this ~/ pathing is different than relative pathing using ../ or rooted pathing which starts with a / on the root site. Rather the ~ syntax creates an application relative URL that is always the same regardless of where your app runs.
Whenever possible when creating URLs in your applications both in markup and code you should choose paths in this order:
Both relative paths and virtual paths are adaptable and the big advantage of these are that they are portable. If you move the site or move to a different virtual folder you don't have to change anything (ok - you have to change the cVirtualPath config property, for ~/).
Relative paths are native to HTML and are parsed as the page is loaded. ~/ paths are expanded on the server and if you're using the wwPageResponse class as your Response class in Web Connection (which is the default in Web Connection 5.0) then any embedded ~/ paths are automatically expanded for you.
The ~/ parsing is implemented as a post-processing feature of the wwPageResponse and wwResponseString classes. Basically Web Connection by default renders all of its output into a string first before potentially rendering the output into other outputs. For example, when running in file based mode Web Connection's output goes into a temporary file, but Web Connection (5.0) first renders the output to a string before explicitly writing the output to a file later. This switch occurred in Web Connection 5.0 to allow more control over the HTTP output created - using a string allowed for header manipulation because the final output doesn't get written to IIS until the response is complete. This means you can now add headers and cookies even when output has already been written to the Response.
In Web Connection 5.0 the wwPageResponse class handles all primary output, and the ~/ processing is hooked up in the Render method like this:
*** Fix up ~/ paths with UrlBasePath IF THIS.contentType = "text/html" AND VARTYPE(Process) = "O" lcBasePath = Process.cUrlBasePath IF !EMPTY(lcBasePath) this.cOutput = STRTRAN(this.cOutput,[="~/],[="] + lcBasePath) this.cOutput = STRTRAN(this.cOutput,[url(~/],[url(] + lcBasePath) ENDIF ENDIF
The code first makes sure we're dealing with HTML content only and then looks to translates any embedded URL expressions in attributes (the first STRTRAN) and in CSS styles (the second url() based syntax).
Based on this Web Connection will expand:
<a href="~/webcontrols/helloworld.wcsx">Hello World</a>
to:
<a href="/wconnect/webcontrols/Helloworld.wwd">Hello World</a>
Notice thought that this will produce different results:
<a href="~/webcontrols/helloworld.wcsx">~/webcontrols/HelloWorld.wcsx</a>
which produces:
<a href="/wconnect/webcontrols/helloworld.wcsx">~/webcontrols/HelloWorld.wcsx</a>
Note that the second ~/ tag wasn't expanded because it's not defined inside of an attribute - the plain string just stays as designed. If you want that sort of thing to work you have to use <%= Process.ResolveUrl() %> instead:
<a href="~/webcontrols/helloworld.wcsx"><%= Process.ResolveUrl("~/webcontrols/HelloWorld.wcsx") %></a>
You can also expand paths in css tags like the following:
<style> .salesitem { padding: 10px; padding-right: 30px; background-image: url(~/css/images/pin.gif); } </style>
which expands out to:
<style> .salesitem { padding: 10px; padding-right: 30px; background-image: url(/wconnect/css/images/pin.gif); } </style>
It also works for inline styles:
<a style="background-image:url(~/css/images/help.gif)"
href="~/webcontrols/Helloworld.wwd">Hello World</a>
which transforms into:
<a style="background-image:url(/wconnect/css/images/help.gif)"
href="/wconnect/webcontrols/Helloworld.wwd">Hello World example</a>
This feature is mostly transparent - there's nothing you have to set up or configure to make the render parse these values. There are two requirements though:
wwPageResponse
wwPageResponse is Web Connection 5.0's default response class and unless you've explicitly overridden it this is the class used. If you're using an older version of Web Connection or you have an old application that was migrated to Web Connection 5.0 you might want to check and potentially switch to this class.
cResponseClass = "wwPageResponse" && wwPageResponse40 for 4.x compatibility
in your Process class property definitions header.
VirtualPath Configuration
Process.ResolvePath and Process.cBaseUrl retrieve the application's base path from the VirtualPath setting in the YourApplication.ini file. Specifically it comes out of the process class configuration section. For example, here's the wwDemo configuration section:
[Wwdemo] Datapath=C:\WWAPPS\WC3\wwDemo\ Htmlpagepath=c:\westwind\wconnect\ Virtualpath=/wconnect/
The VirtualPath key specifies the virtual path that is used. Note that this path is used for various other things as well so you should always set this in your applications. Web Connection's configuration Wizard automatically sets this but if you manually copy applications always make sure to set these values explicitly.
If you haven't used this feature before - take advantage of it. As small as this feature is, it's very useful and greatly simplifies creation of cleaner and consistent URLs in your application. The post parsing mechanism is totally transparent - you don't have to do anything to make this work. No changes are required other than making sure that the application's INI file is set.




by Alex Feldstein (noreply@blogger.com) at May 12, 2012 08:40 PM
Cory Booker, the Mayor of Newark - New Jersey has my respect. He put it very well in a statement about equality under the law and the rights of citizens in this country.
<iframe allowfullscreen="allowfullscreen" frameborder="0" height="360" src="http://www.youtube.com/embed/Y4Z7tl7Vy8U?rel=0" width="640"></iframe>
It is avoiding what other states have done (NC most recently), which is tyranny of the majority. De Tocqueville would have approved.
by Alex Feldstein (noreply@blogger.com) at May 12, 2012 08:35 PM
For daily dose of LEGO minifig shots... pixelcatalyst.net/rsi is revived.
Check it out.
This time will make the postings really really consistent... : )
by Alex Feldstein (noreply@blogger.com) at May 11, 2012 10:12 PM
In deze podcast spreekt Maurice de Beijer met Tom Verhoeff over zijn sessies op de TechDays. Tom presenteerde een sessie over hoe je geld kan verdienen met Windows Phone 7 applicaties. Het lijkt op het eerste gezicht zo eenvoudig, je maakt een app en het geld stroomt binnen. Maar in de praktijk blijkt het toch iets lastiger te zijn en zijn er best wel veel details waar je op moet letten.
Links:
Je kan hem hier afluisteren.
Enjoy!
Microsoft SharePoint Server 2010 supports several commonly used Web browsers. This article describes different levels of Web browser support, browser compatibility for published sites, and how ActiveX controls affect features.
The Test Lab Guide: Configure SharePoint Server 2010 in a Three-Tier Farm describes how to install and configure SharePoint Server 2010 in a three-tier farm configuration (web front end/application server/database server), starting with the computers in the Base Configuration test lab.
ASP.NET Web API introduces a new API for creating REST APIs and making AJAX callbacks to the server. This new API provides a host of new great functionality that unifies many of the features of many of the various AJAX/REST APIs that Microsoft created before it - ASP.NET AJAX, WCF REST specifically - and combines them into a whole more consistent API. Web API addresses many of the concerns that developers had with these older APIs, namely that it was very difficult to build consistent REST style resource APIs easily.
While Web API provides many new features and makes many scenarios much easier, a lot of the focus has been on making it easier to build REST compliant APIs that are focused on resource based solutions and HTTP verbs. But RPC style calls that are common with AJAX callbacks in Web applications, have gotten a lot less focus and there are a few scenarios that are not that obvious, especially if you're expecting Web API to provide functionality similar to ASP.NET AJAX style AJAX callbacks.
RPC style HTTP calls mimic calling a method with parameters and returning a result. Rather than mapping explicit server side resources or 'nouns' RPC calls tend simply map a server side operation, passing in parameters and receiving a typed result where parameters and result values are marshaled over HTTP. Typically RPC calls - like SOAP calls - tend to always be POST operations rather than following HTTP conventions and using the GET/POST/PUT/DELETE etc. verbs to implicitly determine what operation needs to be fired.
RPC might not be considered 'cool' anymore, but for typical private AJAX backend operations of a Web site I'd wager that a large percentage of use cases of Web API will fall towards RPC style calls rather than 'proper' REST style APIs. Web applications that have needs for things like live validation against data, filling data based on user inputs, handling small UI updates often don't lend themselves very well to limited HTTP verb usage. It might not be what the cool kids do, but I don't see RPC calls getting replaced by proper REST APIs any time soon. Proper REST has its place - for 'real' API scenarios that manage and publish/share resources, but for more transactional operations RPC seems a better choice and much easier to implement than trying to shoehorn a boatload of endpoint methods into a few HTTP verbs.
In any case Web API does a good job of providing both RPC abstraction as well as the HTTP Verb/REST abstraction. RPC works well out of the box, but there are some differences especially if you're coming from ASP.NET AJAX service or WCF Rest when it comes to multiple parameters.
If you've looked at Web API demos you've probably seen a bunch of examples of how to create HTTP Verb based routing endpoints. Verb based routing essentially maps a controller and then uses HTTP verbs to map the methods that are called in response to HTTP requests. This works great for resource APIs but doesn't work so well when you have many operational methods in a single controller. HTTP Verb routing is limited to the few HTTP verbs available (plus separate method signatures) and - worse than that - you can't easily extend the controller with custom routes or action routing beyond that.
Thankfully Web API also supports Action based routing which allows you create RPC style endpoints fairly easily:
RouteTable.Routes.MapHttpRoute( name: "AlbumRpcApiAction", routeTemplate: "albums/{action}/{title}", defaults: new { title = RouteParameter.Optional, controller = "AlbumApi", action = "GetAblums" } );
This uses traditional MVC style {action} method routing which is different from the HTTP verb based routing you might have read a bunch about in conjunction with Web API. Action based routing like above lets you specify an end point method in a Web API controller either via the {action} parameter in the route string or via a default value for custom routes.
Using routing you can pass multiple parameters either on the route itself or pass parameters on the query string, via ModelBinding or content value binding. For most common scenarios this actually works very well. As long as you are passing either a single complex type via a POST operation, or multiple simple types via query string or POST buffer, there's no issue. But if you need to pass multiple parameters as was easily done with WCF REST or ASP.NET AJAX things are not so obvious.
Web API has no issue allowing for single parameter like this:
[HttpPost] public string PostAlbum(Album album) { return String.Format("{0} {1:d}", album.AlbumName, album.Entered); }
There are actually two ways to call this endpoint:
albums/PostAlbum
In this mechanism you're sending plain urlencoded POST values to the server which the ModelBinder then maps the parameter. Each property value is matched to each matching POST value. This works similar to the way that MVC's ModelBinder works. Here's how you can POST using the ModelBinder and jQuery:
$.ajax(
{
url: "albums/PostAlbum",
type: "POST",
data: { AlbumName: "Dirty Deeds", Entered: "5/1/2012" },
success: function (result) {
alert(result);
},
error: function (xhr, status, p3, p4) {
var err = "Error " + " " + status + " " + p3;
if (xhr.responseText && xhr.responseText[0] == "{")
err = JSON.parse(xhr.responseText).message;
alert(err);
}
});
Here's what the POST data looks like for this request:
The model binder and it's straight form based POST mechanism is great for posting data directly from HTML pages to model objects. It avoids having to do manual conversions for many operations and is a great boon for AJAX callback requests.
Using Web API JSON Formatter
The other option is to post data using a JSON string. The process for this is similar except that you create a JavaScript object and serialize it to JSON first.
album = {
AlbumName: "PowerAge",
Entered: new Date(1977,0,1)
}
$.ajax(
{
url: "albums/PostAlbum",
type: "POST",
contentType: "application/json",
data: JSON.stringify(album),
success: function (result) {
alert(result);
}
});
Here the data is sent using a JSON object rather than form data and the data is JSON encoded over the wire.
The trace reveals that the data is sent using plain JSON (Source above), which is a little more efficient since there's no UrlEncoding that occurs.
BTW, notice that WebAPI automatically deals with the date. I provided the date as a plain string, rather than a JavaScript date value and the Formatter and ModelBinder both automatically map the date propertly to the Entered DateTime property of the Album object.
Single parameters work fine in either of these RPC scenarios and that's to be expected. ModelBinding always works against a single object because it maps a model. But what happens when you want to pass multiple parameters?
Consider an API Controller method that has a signature like the following:
[HttpPost] public string PostAlbum(Album album, string userToken)
Here I'm asking to pass two objects to an RPC method. Is that possible? This used to be fairly straight forward either with WCF REST and ASP.NET AJAX ASMX services, but as far as I can tell this is not directly possible using a POST operation with WebAPI.
There a few workarounds that you can use to make this work:
If you have both complex and simple parameters, you can pass simple parameters on the query string. The above would actually work with:
/album/PostAlbum?userToken=sekkritt
but that's not always possible. In this example it might not be a good idea to pass a user token on the query string though. It also won't work if you need to pass multiple complex objects, since query string values do not support complex type mapping. They only work with simple types.
If you go by service based architecture guidelines every service method should always pass and return a single value only. The input should wrap potentially multiple input parameters and the output should convey status as well as provide the result value. You typically have a xxxRequest and a xxxResponse class that wraps the inputs and outputs.
Here's what this method might look like:
public PostAlbumResponse PostAlbum(PostAlbumRequest request) { var album = request.Album; var userToken = request.UserToken; return new PostAlbumResponse() { IsSuccess = true, Result = String.Format("{0} {1:d} {2}", album.AlbumName, album.Entered,userToken) }; }
with these support types:
public class PostAlbumRequest { public Album Album { get; set; } public User User { get; set; } public string UserToken { get; set; } } public class PostAlbumResponse { public string Result { get; set; } public bool IsSuccess { get; set; } public string ErrorMessage { get; set; } }
To call this method you now have to assemble these objects on the client and send it up as JSON:
var album = { AlbumName: "PowerAge", Entered: "1/1/1977" } var user = { Name: "Rick" } var userToken = "sekkritt"; $.ajax( { url: "samples/PostAlbum", type: "POST", contentType: "application/json", data: JSON.stringify({ Album: album, User: user, UserToken: userToken }), success: function (result) { alert(result.Result); } });
I assemble the individual types first and then combine them in the data: property of the $.ajax() call into the actual object passed to the server, that mimics the structure of PostAlbumRequest server class that has Album, User and UserToken properties.
This works well enough but it gets tedious if you have to create Request and Response types for each method signature. If you have common parameters that are always passed (like you always pass an album or usertoken) you might be able to abstract this to use a single object that gets reused for all methods, but this gets confusing too: Overload a single 'parameter' too much and it becomes a nightmare to decipher what your method actual can use.
If you recall, ASP.NET AJAX and WCF REST used a 'wrapper' object to make default AJAX calls. Rather than directly calling a service you always passed an object which contained properties for each parameter:
{ parm1: Value, parm2: Value2 }
WCF REST/ASP.NET AJAX would then parse this top level property values and map them to the parameters of the endpoint method.
This automatic type wrapping functionality is no longer available directly in Web API, but since Web API now uses JSON.NET for it's JSON serializer you can actually simulate that behavior with a little extra code. You can use the JObject class to receive a dynamic JSON result and then using the dynamic cast of JObject to walk through the child objects and even parse them into strongly typed objects.
Here's how to do this on the API Controller end:
[HttpPost] public string PostAlbum(JObject jsonData) { dynamic json = jsonData; JObject jalbum = json.Album; JObject juser = json.User; string token = json.UserToken; var album = jalbum.ToObject<Album>(); var user = juser.ToObject<User>(); return String.Format("{0} {1} {2}", album.AlbumName, user.Name, token); }
This is clearly not as nice as having the parameters passed directly, but it works to allow you to pass multiple parameters and access them using Web API.
JObject is JSON.NET's generic object container which sports a nice dynamic interface that allows you to walk through the object's properties using standard 'dot' object syntax. All you have to do is cast the object to dynamic to get access to the property interface of the JSON type.
Additionally JObject also allows you to parse JObject instances into strongly typed objects, which enables us here to retrieve the two objects passed as parameters from this jquery code:
var album = { AlbumName: "PowerAge", Entered: "1/1/1977" } var user = { Name: "Rick" } var userToken = "sekkritt"; $.ajax( { url: "samples/PostAlbum", type: "POST", contentType: "application/json", data: JSON.stringify({ Album: album, User: user, UserToken: userToken }), success: function (result) { alert(result); } });
ASP.NET Web API brings many new features and many advantages over the older Microsoft AJAX and REST APIs, but realize that some things like passing multiple strongly typed object parameters will work a bit differently. It's not insurmountable, but just knowing what options are available to simulate this behavior is good to know.
Now let me say here that it's probably not a good practice to pass a bunch of parameters to an API call. Ideally APIs should be closely factored to accept single parameters or a single content parameter at least along with some identifier parameters that can be passed on the querystring. But saying that doesn't mean that occasionally you don't run into a situation where you have the need to pass several objects to the server and all three of the options I mentioned might have merit in different situations.
For now I'm sure the question of how to pass multiple parameters will come up quite a bit from people migrating WCF REST or ASP.NET AJAX code to Web API. At least there are options available to make it work.
One of the design goals for LightSwitch in Visual Studio 11 was to modernize the look and feel of the UI. Back in March the team released the beta of the LightSwitch Cosmopolitan Shell and Theme. This theme and shell provides a bunch of improvements over the default one like displaying a logo at the top of the application, streamlined top-bar navigation menu, and a “Metro-style” command bar now located at the bottom of screens. This shell will become part of the product and the default shell and theme for new projects you build with LightSwitch in Visual Studio 11 at final release.
So I attempted to apply the Cosmo shell to my Contoso Construction application a while back and I got a couple remarks about how my icons were pretty much sticking out like a sore thumb. I used traditional colorful icons in the application and while that looks great with the standard shell, it doesn’t fit well with the Metro-style icons in the Cosmopolitan shell. Unfortunately I didn’t have time to redraw the icons -- and let’s face it, I’m not a designer.
Luckily there’s a FREE tool out there that you can use to quickly create Metro-style icons! Last night I was reviewing a LightSwitch e-book from Jan (to be released soon I hear!) and he mentioned this free tool so I had to go check it out, Syncfusion Metro Studio. And yes it’s free! Thank you Syncfusion for supporting the community (and particularly the developers who can’t draw!)
This tool comes with a bunch of icon templates you can use to get started designing your own Metro-style icons and it’s super easy to use.
Pick a template and then you can change the sizing, shape, foreground, and background color. You can also view & copy the XAML or save it as a PNG.
For LightSwitch applications that use the Cosmo shell, it’s best to go with a Transparent background so that the light grey of the command bar comes through. Although Metro Studio doesn’t let you choose a transparent background in the color picker, you can simply type it in the textbox (like I show above).
It took me about 20 minutes to update all the icons in the Contoso Contruction application and here’s what I came up with. Not bad for not being a designer :-). You can download the updated sample here:
Contoso Construction - LightSwitch Advanced Sample (Visual Studio 11 Beta)
Syncfusion Metro Studio is a huge time-saver and all the icons you create are royalty-free even for commercial applications. Have fun “Metro-styling” your apps!
Enjoy!
Office 365 was granted the Authority to Operate under the Federal Information Security Management Act (FISMA) by the Broadcasting Board of Governors, FISMA is important to customers because it creates a process for federal agencies to certify and accredit the security of their information management systems…more @ the link below:
Office 365 – FISMA becomes latest security certification for Office 365
by Tom Borgmann (noreply@blogger.com) at May 07, 2012 06:31 AM
Our May 8th meeting will feature Don Higgins -- one of the most successful VFP developers anywhere. Meet at 5:30 on the 15th floor of 200 S Wacker (Tech Nexus). Don wil go over ActiveVFP and how to make VFP work easily on the web. There will be samples of simple web programming, and even some Javascript examples. You don't want to miss this one!by Chicago FoxPro Users and Developers Group at May 07, 2012 04:14 AM
Tom wrote to ask how to use javascript in an RDL; his use case is collapsing and expanding groups.
As you must know, collapse-expand for groups is a native RDL feature, if you use the "toggle item" capability. Tom thinks this isn't efficient for his report, because the postback takes a long time. I'm not sure whether this is a network issue, or some inefficiency in the overall report design, and I'm definitely not sure that javascript will be any faster (it depends: how many rows need to be hidden and made visible on every action?).
But I had seen an interesting post on javascript injection for RDLs, and thought I would give it a shot.
Two additional, quick notes on the native feature:
Tom was surprised that the native collapse-expand feature does a postback. I'm not surprised. A lot of people treat collapse-expand like a better form of drill-down; they start with the groups all closed up and they don't bring back all the data unless they need it. If javascript were the collapse-expand mechanism, all the data for all the groups would have to be send up-front. Not so good.
Have you used the native collapse-expand mechanism, started with the groups closed up, and not been able to fix the toggle icon to behave the way you want? There's a trick to this. I'm not sure if it is a general issue, or just something I find unintuitive, so give me a shout-out if you'd like this explained.
I found the original post that I recommended to Tom here. I'd never had any reason or opportunity to want to do this. Still, it seemed to me that the author was showing a great trick: create an HTML placeholder that respected HTML markup, with an expression embedding some evaluated script that would write the URL for your .js into the header of the page.
The post is on an "InfoSupport" blog, but it looks like this specific author has moved on. He might be this guy.
Anyway... After I gave Tom the reference, I decided to play around with this myself, using Tom's requirement as the test. As it turned out, much as I liked the idea, it needed some improvement to work as we might expect. As a result, I'm writing up what I did here, both for Tom's use and yours.
The first improvement I made in what you'll see in the original blog post is minor: to really write script like that, don't mess around with a single string value, as the author did (cautioning, as he did so, that you need to remove all the spaces to be sure it would work!). Break it up so you can read, and debug it. You're definitely going to need to debug it. You'll see how I broke it out in a screenshot, below.
The second improvement is definitely not minor for Tom's use case. As you'll see if you read the original post, he injects the javascript in one link and then you have to click another link to invoke the script you injected. In a "collapse/expand" scenario, this doesn't make sense. You want to click and see the action, once, period. This proved to be a tricky thing to fix, but I think you'll like the result.
The third improvement is one I didn't need, but I will suggest to you anyway: the original trick is going to put multiple references to the same script into your header. If your script is lengthy (say, jquery), you can use my adapted version to reference only a small loader script, which then checks to see whether the big script is already loaded before attempting to load it again.
While this is a really good idea in some circumstances, it might put you back into the original requirement to have two different click actions, unless you don't mind that the very first click serve to load the larger script, but it won't perform the "real" action afterwards, because the newly-loaded script won't be referenceable at that point. After the first click, everything proceeds as planned. The user might never notice this -- or, in some situations, it might be entirely appropriate to separate the two actions.
The report I'm using in this example is a really simple example report I've used for a previous blog post. It really didn't matter what report I used, as long as it was something that had an appropriate group that somebody might want to collapse/expand. In this case I'm grouping Cities within Countries.
Keep in mind that our javascript is looking at the generated HTML in your report, so some of the code I'll use below should be adjusted for your layout. Nevertheless, I've tried to make it as generic as possible for the collapse-expand use case, and I've tested in FireFox and IE, so I hope it's largely usable for you.
Since my original report group header caption supplied the name of the Country, I'll adjust what actually displays to a prefix consisting of either "+" or "-", following by a single space, followed by the Country name.
You can use whatever convention you want, but your javascript has to be able to telll, first, what elements are headers (as opposed to detail lines) and, second, what state each header's detail group is currently in (collapsed or expanded).
As you'll learn from the original post, you also need to make sure that HTML tags are interpreted as styles.

Turning to the actual expression used for this caption, I'm following the original method, except for two small changes. First, as explained earlier, I'm breaking up the expression into separate strings for legibility:

I'll repeat that expression below, to make sure you can read it properly, but also to highlight the second, and most significant change I've made to the expression:
= "<a href=" & CHR(34) &
"javascript:eval(unescape" &
"('function addScript(scriptFile)" &
"{var head = document.getElementsByTagName(\'head\')[0];" &
"var script = document.createElement(\'script\');" &
"script.setAttribute(\'type\', \'text/javascript\');" &
"script.setAttribute(\'src\', scriptFile);" &
"head.appendChild(script);" &
"}" &
"var tObj = \'"& Fields!Country.Value.ToString().Trim() & "\';" &
"addScript(\'http://localhost/test/test3.js\'); ')" &
");" & CHR(34) & ">- "& Fields!Country.Value.ToString().Trim() & "</a>"
The highlighted line of code, as you can see, creates a variable and assigns it the name of the country, before adding the script reference. What does that do for us?
Quite a lot, actually. That's where my superior trick comes in, and it makes all the difference between needing to invoke the referenced script in a second action, and being able to use it right away.
Turning to the .js file, you'll find that it has a global piece of code, not contained in a function at all -- which will be evaluated as soon as the script is loaded:
toggle(tObj);
... and of course this single line of code is followed by an appropriate "toggle" function. I'm providing the full script here, which includes a lot of comments, plus the directions for using this injected script as a pre-loader for loading additional, more lengthy, scripts, including appropriate checks for only loading them once.
This really works and I think my javascript is kind of cool, even though it has to include the usual bonehead checks to handle cross-browser DOM object model incompatibilities. Do remember to look at the source for your particular report, if you find my method of drilling into TD elements doesn't work with your layout.
If you think you have a better way to pass the "which group are we adjusting" information from the RDL to the script, feel free to give it a try. But keep in mind that we don't have a "this" reference to the current anchor, or other niceties, and we can't add an id attribute into the <a> element we added to our expression, either. When we're evaluating the script, we're not actually on the anchor, which rules out the former, and SSRS won't let us do the latter, it seems.
A number of people asked about testing this technique, in questions to the original author. While it's true that you can't test it directly in BIDS' preview, because the clicks won't actually go anywhere, you don't necessarily need to deploy to a report server to see this work. You can Save As MHTML, and then open in Internet Explorer.
Be sure to tell IE to allow script to be executed from your local MHTML file (why are files on the local disk with script treated more stringently than files coming from a web server? I've never understood that).
To test in other browsers besides Internet Explorer, you can then tell IE to Save As a complete web file (HTML), and load that additional local file to the other browsers. If your script is at all complex, you will want to do this, because IE has the lousiest debugging facilities of the lot.
I could try to show you a screenshot of the result but... it just works. It doesn't seem special at all, never mind that it was a big deal to figure it out. Well, maybe just one screenshot for the road, but honestly there's nothing to see.
Whaddya think? Not sure it will really be faster at runtime for Tom's report, but there it is.

| TYPE | VFP | T-SQL |
|---|---|---|
| AutoIncrement field last value | GETAUTOINCVALUE | SCOPE_IDENTITY() / OUTPUT clause in SQL Server 2005 and up. <new> See also: Find the IDENTITY value of the last inserted row (discussion on @@IDENTITY, SCOPE_IDENTITY() and IDENT_CURRENT(), and which one to use). See also http://blog.sqlauthority.com/2007/03/25/sql-server-identity-vs-scope_identity-vs-ident_current-retrieve-last-inserted-identity-of-record/ |
| Inline Condition | IIF(condition,true value, false value) | CASE WHEN condition THEN true value ELSE false value END |
| BETWEEN | BETWEEN(field,low value, high value) | field BETWEEN lowvalue AND highvalue. Better yet, just use the SQL BETWEEN instead of the VFP between() in all cases when writing SQL (VFP or NOT) |
| True/False | .T. / .F. | No logical data type 1=1/1=2 |
| Check something is NULL | ISNULL(checked_value) | IS [NOT] NULL this syntax worked in VFP also |
| Get non NULL value from two expressions | NVL(checked_value,value_if_expression_is_null) | ISNULL(checked_value,value_if_expression_is_null) Also COALESCE ( expression [ ,...n ] ) - returns the first nonnull expression among its arguments. |
| String comparison | = for partial, == for exact. LIKE is supported since at least VFP v7 -- Mike Yearwood | LIKE |
| Empty Dates | {} | Not supported. Use NULL instead |
| <new> Checking for an empty string | EMPTY(fieldname). EMPTY() has never been Rushmore optimizable. Try fieldname = space(len(fieldname)) or UPPER(fieldname) = SPACE(LEN(fieldname)) especially if you have an index on UPPER(fieldname). -- Mike Yearwood | LEN(fieldname) = 0 |
| Current Date and Time | DateTime() | GetDate() or DATEADD(ms,-DATEPART(ms,GETDATE()),GETDATE()) because GetDate() return datetime with ms |
| Current Date | Date() | Date data type doesn't exist <new> In SQL Server 2008 there are new DATE and TIME types |
| Add/Subtract from a date | Use arithmetic operators Date() + 1 or Date() - 1 | DATEADD(day,1,Getdate()) or to substract use a negative integer You can directly add/subtract dates from getdate(): select getdate() - 31, getdate() + 30 Regarding the last comment - you can not do this with Dates in SQL Server 2008 see Compatibility Clash in 2008 |
| Compare two dates | logic symbols<,>,= | DATEDIFF ( datepart , startdate , enddate ) |
| Date constant or literal | curly braces and an uproot example: {^2006/01/31} | Several format with single quotes example: 'April 15, 1998' '15 April, 1998' '980415' '04/15/98'. However, only ISO constants are safe, e.g. only this type of constant '20101201' can be used in queries for the dates. |
| <new> Get the integer portion of a number | INT() | CAST(somenumber AS int) |
| Convert date to sortable string | DTOS(date-value) | CONVERT(char(8), date-value, 112) |
| Replace text in a string | STRTRAN() | REPLACE() |
| <new> Trim string | LTRIM(), TRIM() or RTRIM(), ALLTRIM() | LTRIM(), RTRIM(), LTRIM(RTRIM()) |
| <new> Number of occurrences of a character in a string | OCCURS() | How many occurrences in a string |
| Pad a string with space | PADR(somestring,numchars) PADL(somestring,numchars) | CAST(somestring AS char(numchars)) REPLICATE(SPACE(1), numchars - DATALENGTH(somestring )) + somestring , PADR(),PADL(),PADC() ![]() |
| Convert an integer to fixed length zero padded | PADL(intval,numchars, '0') | REPLICATE('0', numchars - DATALENGTH( CAST(intval AS varchar(numchars)) )) + CAST(intval AS varchar(numchars)) |
| Find text in a string | AT() $ | CHARINDEX(), PATINDEX() LIKE |
| <new> Return a string within in a string | SUBSTR() | SUBSTRING() |
| A string length | LEN() | DATALENGTH() LEN() - doesn't count trailing spaces |
| Checking a list of values | [NOT] INLIST(valuelookingfor, testval1, testval2, testval3) IN / NOT IN works in VFP also | valuelookingfor [NOT] IN (testval1, testval2, testval3) <new> If value is in another table, then INNER JOIN / LEFT JOIN with IS NULL may be a better alternative |
| Deleting all records | ZAP [IN nWorkArea | cTableAlias] | TRUNCATE TABLE tablename |
| Determine last query rowcount | _TALLY | @@ROWCOUNT |
| Replaces each character in a character expression that matches a character in a second character expression with the corresponding character in a third character expression. | CHRTRAN() | REPLACE ( string_expression , string_pattern , string_replacement ) |
| Removes all characters from a string except those specified. | <new> CHRTRAN(cString, CHRTRAN(cString, cFilter, "), ") | Igor's Nikiforov UDF StrFilter |
| Counts the words in a string. | GETWORDCOUNT() | Igor's Nikiforov UDF GetWordCount |
| Returns a specified word from a string. | GETWORDNUM() | Igor's Nikiforov UDF GetWordNum |