다음을 통해 공유


Avoid LightSwitch URI Casing Issue Using the URL Rewrite Module

Late last year, some customers on the LightSwitch forums started reporting an issue that certain situations would cause an error with the message:

“The context is already tracking a different entity with the same resource Uri.”

or

“An error occurred while processing this request.” 

One of the ways that this could repro was if the user changed a value on the first page of records on an editable grid form, went to the next page (without saving first) then paged back to the previous page.  When this happened, the record would appear with its old value and wouldn’t have the * next to it to indicate that the record was modified.  If you hit Save at this point, you’d get an error that read “An error occurred while processing this request”.  The problem wouldn’t repro all the time for all users (always fun times for a tester), but we eventually figured out that the problem would occur if the casing of the application name differed between what the user had entered in the browser and what the application had been named on the IIS Server.

For example, if I had deployed my LightSwitch app by setting the Site/Application field in the publish wizard like this:

image

 

…then the application would have the casing “SchoolBooks” on the web server and entities returned from the server would have this casing in their URI.  If a client uses the URL https://myserver/SchoolBooks to launch the application, everything goes swimmingly and users won’t hit the errors mentioned above.  If, however, the user entered https://myserver/schoolbooks (all lowercase) then the trouble starts.

The issue is not specific to LightSwitch and the underlying cause is a well-known issue in the WCF Data Services stack regarding case sensitivity.  At the time we found the issue being reported on the LightSwitch forums, our guidance was to make sure the users entered the correctly cased URL when launching the application.  This obviously is less than ideal as you have no control over what users will enter.

One way to assure that the client does supply the correct URL when the application is launched is to use the IIS URL Rewrite Module.  This module can do all kinds of cool stuff, but for our purposes it can help us by redirecting requests that come in with the “wrong” casing to the one we want.  It does this by using a system that allows the administrator to define a set of rules to detect incoming URLs and rewrite or redirect them, in certain situations.

First, install the module so you can use it in IIS (note that you need IIS 7.0 or higher).  After installing, open IIS Manager, click on the website that you need to create the redirect rule for:

image

 

You should now see “URL Rewrite” in the “IIS” section of the features pane, double-click on it…

image

 

…then pick “Add Rule(s)” under the “Actions” pane on the far right:

image

 

On the “Add Rule(s)” dialog, pick “Blank rule” from the “Inbound rules” section and hit OK

image

 

Now we’ll fill out the info for the rule.  First, name the rule (I’ll just name mine the name of my app) and enter the pattern as I have done below:

image

 

The Pattern field is where we put the regular expression that we want to match on.  Note that since we created this rule at the “Default Web Site” level, the URL that we’re checking will be relative to that (i.e. we don’t have to worry about the web site name, only what comes after the initial slash).  The pattern that I have entered above means that it will match when the URL begins with “schoolbooks” (case insensitive, since “Ignore case” is checked).  The (.*) at the end will capture the remaining string in the URL (we’ll need that later when we specify our redirect URL).

We now need to enter a “Condition” to our rule.  The condition needs to tell the rule to “fail” when the URL starts with exactly “ SchoolBooks” (i.e. we don’t want to redirect if “SchoolBooks” was hit, either through the user typing the right URL or through our initial redirect").

In the “Conditions” section, hit the “Add…” button:

image

 

Enter the following in the “Add Condition” dialog and hit OK:

image

 

What this is saying is that the rule should only be enforced if {R:1} (the first capture group in our regular expression, which will be the “schoolbooks” part of the URL) does not exactly match “SchoolBooks” (case sensitive since “Ignore case” is unchecked").

So again, the rule will run if the URL is “https://myserver/schoolbooks”, but will not if it is “https://myserver/SchoolBooks”

Lastly, we need to specify what to do if the rule detects the wrongly cased URL.

In the “Action” section, change the “Action type” to “Redirect” and enter the following in the “Redirect URL” field:

image

 

So this means that we’ll redirect to the URL that is “SchoolBooks” + whatever came after the “schoolbooks” part of the initial URL.

If our URL was “https://myserver/schoolbooks/default.htm”

{R:1} = “schoolbooks”

{R:2} = “/default.htm”

…so our final redirect URL will be “https://myserver/SchoolBooks/default.htm”

 

Now just hit the “Apply” button in the “Actions” pane and you’re done.

image

 

Now I can see if the rule worked.  If I fire up Fiddler and try to hit https://myserver/schoolbooks/

image

 

I get this in the Response:

image

 

And of course the next request has the right URL

image

 

And, if we created our “Condition” correctly, we don’t keep redirecting to this  URL until the browser gives up (this happened to me a couple times when making these rules because I kept forgetting the colon in {R:1} and {R:2}, turns out those are important).

So that’s it, no more casing problem.  Hope this works for you.

 

Notes:

The problem with casing ONLY applies to the application name.  The website name will automatically get lower-cased by the browser.  So if I type https://MYSERVER/SCHOOLBOOKS in the address bar, the browser will automatically change that to https://myserver/SCHOOLBOOKS

If you deploy your application to a website that is dedicated to this app (i.e. isn’t running other web apps) you can omit the “Application” part of the “Site/Application” field of the publish wizard and just supply the Site part.  The URL for your app will then be https://myserver (no app name, no problem).

LightSwitch apps deployed as an Azure Cloud Service or to an Azure Web Site are deployed in the manner described above, so they don’t have the problem.

If you don’t want to use the URL Rewrite Module and you are publishing to website with multiple applications, your best bet is probably to:

  1. Enter a lowercase name for your Application as users would be more likely to type all lowercase when typing the URL
  2. Send users a shortcut to open the app and advise them to always use that to launch.

Comments

  • Anonymous
    April 16, 2013
    Thanks a lot for the article. Even though my issue wasn't lightswitch related, it helped me narrow down wcf case sensitivity issue.

  • Anonymous
    June 13, 2013
    Thanks a lot dude! I really works!!!!

  • Anonymous
    July 25, 2013
    Great step by step article.... Congrats... :-)

  • Anonymous
    January 24, 2014
    Thank you Dave, your post was critical for me to understand this important error for a banal reason.

  • Anonymous
    May 09, 2014
    Thanks a lot for it information, was very usefull, for us.