Planet FoxPro

May 21, 2012

Alex Feldstein

May 20, 2012

Alex Feldstein

May 19, 2012

FoxCentral News

Southwst Fox/Xbase++ registration opens

Registration is open for the Southwest Fox and Southwest Xbase++ conferences: http://swfox.net/Register.aspx. Additionally, the speakers and sessions for the Southwest Xbase++ conference are posted. Get registered for the conference as early as possible.

by Southwest Fox Conference at May 19, 2012 11:28 PM

Shedding Some Light

Southwest Fox/Xbase++ 2012 Registration Open

A couple of announcements about our 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.
  • 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 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!

by Rick Schummer at May 19, 2012 11:20 PM

Alex Feldstein

Jetman Yves Rossy flies with the Breitling Jet Team

 

<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

May 18, 2012

Doug Hennig

Southwest Fox and Xbase++ 2012 News

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

Alex Feldstein

Photo of the day


Another snowy egret displaying at the St. Augustine rookery

by Alex Feldstein (noreply@blogger.com) at May 18, 2012 09:45 AM

May 17, 2012

Alex Feldstein

ORBx released 77S–Creswell Oregon today!

 

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!


1.
Photobucket

2.
Photobucket

3.
Photobucket

4.
Photobucket

5.
Photobucket

6.
Photobucket

by Alex Feldstein (noreply@blogger.com) at May 17, 2012 11:17 PM

David T. Anderson

We are in our new apartment

We found a place in downtown Minneapolis right off Loring Park. It's a nice place for us for the next three months.

We are now fully engaged in our house search. Similar needs as the apartment, let us know if you have any leads.

Our new address is 1300 Yale Place, apt. 232, Minneapolis 55403.

Thank you Maiya for helping with this entry.

by dta (noreply@blogger.com) at May 17, 2012 10:19 PM

Alex Feldstein

Photo of the day


Snowy egret displaying at the St. Augustine rookery

by Alex Feldstein (noreply@blogger.com) at May 17, 2012 10:12 AM

Chris Sainty

Enabling sessions in Nancy

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.

Getting Started

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.

Testing

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.

Future

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

May 16, 2012

Rick Strahl's Web Log

DropDownList and SelectListItem Array Item Updates in MVC

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.

DropDown

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..

Watch that ModelBinder!

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…

© Rick Strahl, West Wind Technologies, 2005-2012
Posted in MVC  ASP.NET  .NET  
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script> <g:plusone href="http://www.west-wind.com/weblog/posts/2012/May/16/DropDownList-and-SelectListItem-Array-Item-Updates-in-MVC" size="medium"></g:plusone> <script type="text/javascript"> (function() { var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true; po.src = 'https://apis.google.com/js/plusone.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s); })(); </script>

by Rick Strahl at May 16, 2012 04:44 PM

VisualFoxProWiki

FoxProCommunityLifetimeAchievementAward

Editor comments: Call for nominations for 2012 award
Created in 2001 by Microsoft, the FoxPro Community Lifetime Achievement Award recognizes individuals who've made phenomenal contributions to the Visual FoxPro community.

 class= 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.

May 16, 2012 04:03 PM

Doug Hennig

FoxPro Lifetime Achievement Award 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

FoxCentral News

FoxPro Lifetime Achievement Award 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 email Doug Hennig (dhennig@stonefield.com) by June 15, 2012.

by Stonefield Systems Group Inc. at May 16, 2012 03:24 PM

Developer.Blog();

When Good Code Intententions Go Bad

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.

by Craig Berntson at May 16, 2012 03:10 PM

VisualFoxProWiki

ThisAccess

What should THIS_Access be used for?

See Decorating With This Access

From the VFP help:
A new global class method, THIS_ACCESS, has been added to Visual FoxPro 6.0. The code in a THIS_ACCESS method is executed whenever you attempt to change the value of a member of an object or a member of an object is queried.
.
.
.
Note that THIS_ACCESS is not intended to be a global replacement for Access and Assign methods - it only provides information about which object member is accessed or queried. Unlike an Access or Assign method, THIS_ACCESS does not provide control over values returned to specific object members.

May 16, 2012 12:31 PM

Alex Feldstein

May 15, 2012

Rahul Desai's Blog

Why Microsoft’s Open Data Protocol matters

With the newest version of the Open Data Protocol (), 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:

Why Microsoft’s Open Data Protocol matters | ZDNet

by Rahul Desai at May 15, 2012 07:53 PM

Alex Feldstein

ORBX's Stewart released for Flight Sim (FSX)

ORBx has released Stewart Aerodrome (CZST) in British Columbia, Canada, with an insane 2cm per pixel ground resolution! Amazing quality and very little performance penalty. I installed it this week and it was all the pre-release screenshots promised. Wow!


It is a beautiful area in the border between Alascka and British Columbia. Flying from there to Ketchikan (also specially treated by ORBx), makes the sim flights a joy.

by Alex Feldstein (noreply@blogger.com) at May 15, 2012 09:47 AM

Chris Sainty

AppHarbify Tools

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.

The solution

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

NuGet Package

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();

Migrations

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

May 14, 2012

VisualFoxProWiki

Beth Massi - Sharing the goodness

"What’s New with LightSwitch in Visual Studio 11" Recording Available

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:

Download: What’s New with LightSwitch in Visual Studio 11

(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.

image

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.

image

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!

by Beth Massi at May 14, 2012 07:57 PM

Alex Feldstein

May 13, 2012

Alex Feldstein

Photo of the day


Stinson at Sun-N-Fun airshow in Lakeland last month

by Alex Feldstein (noreply@blogger.com) at May 13, 2012 05:00 AM

May 12, 2012

Rick Strahl's FoxPro and Web Connection Web Log

Root Path Support with ~ in Web Connection Response Output

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.

Url Pathing Options

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:

  1. Relative Paths
    Use relative paths whenever possible because they're the most portable. Relative paths (../css/standard.css or css/standard.css) tend to be the most portable because as long as your resources are relatively stored to each other they will always work. Problems with this arise only if the resources are moved relative to each other which is probably rare.
  2. Virtual Paths
    Use application relative paths because they are portable per application. Virtual path specifiers (~/css/standard.css which expands to /wconnect/css/standard.css) are always rooted to the application's root folder. In Web Connection you specify this value in the server configuration via the cVirtualPath in wc.ini or web.config using the VirtualPath key. The great thing about ~/ paths are that there's no relative pathing involved if you don't know where your request might be running from. They are also super useful for Web Control Framework User Controls that might be dropped into pages running for many different subfolders.
  3. Rooted Paths
    Never use hardcoded paths to site or even rooted Webs. You should NEVER EVER use hard coded URL paths to reference anything in your local site. While this will work in whatever environment you're working in it'll break as soon as you move the site. At that point you have lots of links to clean up and that's never a good idea.

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.

How it works and What is Transformed

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>

Configuration

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:

  • Make sure you're using wwPageResponse or the wwResponseString class for Response rendering
  • Make sure the VirtualPath property is set in web.config or wc.ini

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.

Summary

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 Rick Strahl at May 12, 2012 10:44 PM

Alex Feldstein

Aerial shots of Opa-Locka (KOPF)


A few recent shots from a visit to Opa-Locka airport Florida (KOPF). Opa-Locka is a great airport because they keep all kinds of old airframes parked, sometimes for years.
The color is funny  because it was shot through a window of a C182. I normally avoid shooting through windows but had no choice here.

1.


2.


3.


4.



The city buildings on the top-left in shot #4 is the city of Sunny-Isles Beach and the ones in the top-right are in Bal Harbour.

by Alex Feldstein (noreply@blogger.com) at May 12, 2012 08:40 PM

The Mayor of Newark put it very well

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

foxpro.catalyst «

LEGOmatics reinitalized

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 WildFire at May 12, 2012 12:01 PM

Alex Feldstein

Photo of the day


Howard DGA-15P at the Sun-N-Fun airshow in Lakeland last month

by Alex Feldstein (noreply@blogger.com) at May 12, 2012 10:12 AM

May 11, 2012

Alex Feldstein

Horst Faas, legendary Vietnam combat photographer, dies


Horst Faas, one of the best photojournalists has died. He brought the Vietnam War to the world's attention through his work. The quality of the work, and bravery he displayed to do what he did, was exemplary.

MSNBC.com
 
The Washington Post
 
What a life he lived!

by Alex Feldstein (noreply@blogger.com) at May 11, 2012 10:12 PM

foxpro.catalyst «

VisualFoxProWiki

OpenQuestions

A place for questions to the FoxWiki community. If you have an answer/opinion, please weigh in below. In time, each question finds a home in an existing topic, or its own topic. (N.B. If you move a question, please leave a link to the new location. Alternatively, if you know of some existing content in the wiki which addresses the question, leave a link.) You may find other questions by searching the Category Open Questions.

May 11, 2012 09:14 AM

Alex Feldstein

Photo of the day


Red-wing black bird
Wakodahatchee wetlands, Delray, FL

by Alex Feldstein (noreply@blogger.com) at May 11, 2012 05:00 AM

May 10, 2012

www.atoutfox.org - Contributions

Utiliser Service Broker pour les tâches programmées dans SQL Express

Chacun sait que SQL Express ne dispose pas de l'Agent SQL qui permet l'exécution automatique de tâches programmées, comme par exemple les sauvegardes.
Pour contourner cette limitation, on a l'habitude de passer par les tâches programmées de Windows, qui vont lancer l'exécution d'un script SQL via l'utilitaire en ligne SQLCMD.

Je vous propose une autre approche pour gérer l'automatisation des tâches programmées sur un serveur SQL Express : nous allons utiliser un service souvent méconnu, existant dans toutes les versions, il s'agit de Service Broker .

Cette introduction reprend intégralement le code proposé par Mladen Prajdic dans son article paru sur SQLTeam.com le 27/08/2008, qui s'appuie sur la description fournie par Roger Wolter (responsable du développement de Service Broker chez Microsoft).

by Michel Lévy at May 10, 2012 01:04 PM

The Problem Solver

DotNed Podcast: Tom Verhoeff over geld verdienen met Windows Phone 7 applicaties

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!

by Maurice at May 10, 2012 10:12 AM

VisualFoxProWiki

UpcomingEvents

A place to list upcoming Visual FoxPro events like conferences, meetings, user groups, open training sessions...
Closest at the top please, and please remove past events.

May 10, 2012 06:22 AM

Alex Feldstein

May 09, 2012

Alex Feldstein

Rahul Desai's Blog

Plan browser support (SharePoint Server 2010) : Updated

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.

Plan browser support (SharePoint Server 2010)

by Rahul Desai at May 09, 2012 10:37 PM

Three-tier farm Test Lab Guide (TLG) for SharePoint Server 2010 published

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.

Three-tier farm Test Lab Guide (TLG) for SharePoint Server 2010 published – To the SharePoint – Site Home – TechNet Blogs

by Rahul Desai at May 09, 2012 10:35 PM

foxpro.catalyst «

Rick Strahl's Web Log

Passing multiple POST parameters to Web API Controller Methods

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 vs. 'Proper' REST

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.

Action Routing for RPC Style Calls

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

Using the Model Binder with plain POST values

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:

FireBug

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.

JsonPost

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.

Passing multiple Parameters to a Web API Controller

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:

Use both POST *and* QueryString Parameters in Conjunction

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.

Use a single Object that wraps the two Parameters

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.

Use JObject to parse multiple Property Values out of an Object

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);
    }
});

Summary

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.

© Rick Strahl, West Wind Technologies, 2005-2012
Posted in Web Api  
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script> <g:plusone href="http://www.west-wind.com/weblog/posts/2012/May/08/Passing-multiple-POST-parameters-to-Web-API-Controller-Methods" size="medium"></g:plusone> <script type="text/javascript"> (function() { var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true; po.src = 'https://apis.google.com/js/plusone.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s); })(); </script>

by Rick Strahl at May 09, 2012 05:29 AM

Alex Feldstein

May 08, 2012

Alex Feldstein

Calvin Hsia's WebLog

Tetris

A long time ago I worked in the Green Building (building 54 at MIT) .   Several NASA Apollo lunar missions (I think 11, 12, 14… I know it wasn’t 13 J ) placed seismometers on the moon, in various locations. They didn’t detect earth quakes. The Moonquakes...(read more)

by CalvinH at May 08, 2012 11:12 PM

Beth Massi - Sharing the goodness

Modernize Apps Look & Feel with Metro Studio and the Cosmopolitan Shell

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.

Enter Syncfusion Metro Studio

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!)

image

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.

image

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.

image

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).

Contoso Construction Updated

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:

Download Contoso Construction - LightSwitch Advanced Sample (Visual Studio 11 Beta)

Contoso1sm

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!

by Beth Massi at May 08, 2012 07:04 PM

May 07, 2012

David T. Anderson

Updated housing info

This is what we're looking for in a temp home:
- Avbl immediately with month-to-month or 3 mo lease
- 3 bedroom, with at least the master BR on main floor
- master bathroom with either:
3-foot clearance around tub (1side), or
Roll-in shower
- allows dogs
- hardwood floors or clean carpet with low pile
- access to yard
- off-street parking
- handicap accessible -- front door must be less than 3' off ground (to allow for ramp) and doorway be at least 3' wide
- preferably NE or S or U area (close to Marcy Elem)

That's all we can think of at the moment... Let us know if u have specific questions that will help the search.

by dta (noreply@blogger.com) at May 07, 2012 09:32 PM

Rahul Desai's Blog

Office 365 – FISMA becomes latest security certification for Office 365

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 Rahul Desai at May 07, 2012 06:52 PM

VisualFoxProWiki

CrystalVFPClass

Crystal VFP Class, Crystal VFP Class is a complete wrapper to get access to the Crystal Reports RDC, it also calls the Crystal ActiveX and makes the use of Crystal Reports a Snap in Visual FoxPro.

New Features in Version 1.5:

Support for Juegos Crystal Reports 10
Support to Export to Excel Data Only Format for Crystal Reports 10 using the RDC
More Export Options Added, the Crystal Class can handle now: Plain Text Exportation Blog in SEO, HTML 3 Exportation and the most common export formats that were previously available: RTF,DOC,XLS,PDF,HTML4,XML
The Class Jogos has Been Rearranged, a some minor bugs have been corrected
Xml Jocuri Data Source it's supported since Crystal Reports Uses an Jogos de meninas Driver for this
Data Location in SubReports? can be changed now, it supports the same type of connections Native, ODBC and Proxy.
Number of Sub-Reports? Handled by the class have been increased to 3
Number of Tables supported in This Version have been increased to 3, now you can change the Data location for 3 tables in the main report, 3 in the 3 subreports
Number of Parameters Handled by the class has been increased to 10
Now Crystal Class can Handle
Size and Jᴩkok Duplex Printing!
Luis Navas
CompuInnovaciones?
Guatemala, C.A.

May 07, 2012 12:16 PM

foxpro.catalyst «

Tom's VFP Blog

Datumsspielereien (Teil 9) / Date gadgets (Part 9)

Irgendwie sind Datumberechnungen ein Faß ohne Boden. Nach Teil 4 der Datumsspielereien war ich bereits der Meinung, nichts neues mehr zu diesem Thema zu finden. Aber irgendwie poppt in unregelmäßigen Abständen immer wieder eine neue Frage dazu auf. Aktuell dreht es sich darum herauszufinden, wieviele Jahre, Monate und Tage zwischen zwei Datumswerten liegen. Im folgenden Mustercode erledigt

by Tom Borgmann (noreply@blogger.com) at May 07, 2012 06:31 AM

Alex Feldstein

FoxCentral News

ChicagoFUDG meets Tuesday, 8 May 2012

 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

TechSpoken

Walkthrough: Rolling your own script in SSRS

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.

Where I got the original idea

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.

Ready?

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.

Step 1: Adjust your report group header expression.

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.

Step 2: Writing the javascript referenced in the report

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.

 test3.js.txt (4.03 kb)

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 quick note on testing

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.

And that's all she wrote.

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.

 

May 07, 2012 02:17 AM

May 06, 2012

VisualFoxProWiki

PDFdrivers

This topic has morphed into 2 things:

1. How to create pdf from a VFP app
2. Windows Printer drivers that create PDFs.

May 06, 2012 08:27 PM

foxpro.catalyst «

VisualFoxProWiki

VFPSQL-TSQL-Mapping

VFP/SQL functions concordance

This is a table to help people that are converting VFP SQL Statements to SQL Server T-SQL statements.

<new> Set of VFP string functions implemented in T-SQL by Brad Schulz

Handy String Functions


TYPEVFPT-SQL
AutoIncrement field last valueGETAUTOINCVALUESCOPE_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 ConditionIIF(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 NULLISNULL(checked_value)IS [NOT] NULL this syntax worked in VFP also
Get non NULL value from two expressionsNVL(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 stringEMPTY(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 TimeDateTime()GetDate() or DATEADD(ms,-DATEPART(ms,GETDATE()),GETDATE()) because GetDate() return datetime with ms
Current DateDate()Date data type doesn't exist
<new> In SQL Server 2008 there are new DATE and TIME types
Add/Subtract from a dateUse 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 dateslogic symbols<,>,=DATEDIFF ( datepart , startdate , enddate )
Date constant or literalcurly 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 numberINT()CAST(somenumber AS int)
Convert date to sortable stringDTOS(date-value) CONVERT(char(8), date-value, 112)
Replace text in a stringSTRTRAN()REPLACE()
<new> Trim stringLTRIM(), TRIM() or RTRIM(),
ALLTRIM()
LTRIM(), RTRIM(),
LTRIM(RTRIM())
<new> Number of occurrences of a character in a stringOCCURS()
How many occurrences in a string
Pad a string with spacePADR(somestring,numchars)
PADL(somestring,numchars)
CAST(somestring AS char(numchars))
REPLICATE(SPACE(1), numchars - DATALENGTH(somestring )) + somestring , PADR(),PADL(),PADC() ></td></tr>  <tr><td>Convert an integer to fixed length zero padded</td><td>PADL(intval,numchars, '0')<br> </td><td> REPLICATE('0', numchars - DATALENGTH( CAST(intval AS varchar(numchars)) )) + CAST(intval AS varchar(numchars)) </td></tr>  <tr><td>Find text in a string</td><td>AT()<br> $</td><td>CHARINDEX(), PATINDEX()<br> LIKE </td></tr>  <tr><td><NEW=2454148> Return a string within in a string</td><td>SUBSTR()</td><td>SUBSTRING()</td></tr> <tr><td>A string length</td><td>LEN()</td><td>DATALENGTH()<br> LEN() - doesn't count trailing spaces</td></tr>  <tr><td>Checking a list of values</td><td>[NOT] INLIST(valuelookingfor, testval1, testval2, testval3)<br> IN / NOT IN works in VFP also<br> </td><td>valuelookingfor [NOT] IN (testval1, testval2, testval3)<br> <NEW=2454326> If value is in another table, then INNER JOIN / LEFT JOIN with IS NULL may be a better alternative<br> </td></tr>  <tr><td>Deleting all records</td><td>ZAP [IN nWorkArea | cTableAlias]</td><td> <a href=http://codebetter.com/blogs/raymond.lewallen/archive/2005/05/09/62960.aspx>TRUNCATE TABLE</a> tablename</td></tr> <tr><td>Determine last query rowcount</td><td>_TALLY</td><td>@@ROWCOUNT</td></tr> <tr><td>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.</td><td>CHRTRAN()</td><td> REPLACE ( string_expression , string_pattern , string_replacement )</td></tr> <tr><td>Removes all characters from a string except those specified.<br> </td><td><NEW=2455950> CHRTRAN(cString, CHRTRAN(cString, cFilter,
Convert an integer to fixed length zero paddedPADL(intval,numchars, '0')
REPLICATE('0', numchars - DATALENGTH( CAST(intval AS varchar(numchars)) )) + CAST(intval AS varchar(numchars))
Find text in a stringAT()
$
CHARINDEX(), PATINDEX()
LIKE
<new> Return a string within in a stringSUBSTR()SUBSTRING()
A string lengthLEN()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 recordsZAP [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

May 06, 2012 01:07 PM