2011-06-17

WCF "Gotcha" When Sending an Invalid Enum Value Across the Boundary

The Silverlight application I'm working on for my employer at the time of this writing involves WCF services that provide data for the app.

It was working fine until a coworker ran a SQL query that changed an int field (which maps to an Enum in our code) to an invalid value on several records in a common test database a few of us were pointing to.

All of the sudden we were getting a FaultException (I can't remember the exact error - but it was one of those unrelated ones that mask the real exception message that caused the problem to begin with.) while trying to load a graph.

Further investigation revealed that our asynchronous calls to the WCF service client were retrying the same call three times and coming back with a failure.  Stepping down deeper into the code, we saw that our resultset seemed to be coming back fine from our data layer, leaving us wondering why it was behaving so strange.

My coworker put a breakpoint where our data layer returns the IEnumerable to the service so it can serialize/return the data to our app, and changed the resultset to an empty array of the given type instead of allowing the real resultset through.

Only a single attempt was made on the service instead of three and the data was received fine by the application...  However, when we reverted to allow the regular resultset through, it again made three attempts and returned the exception.

On the next run, we decided to look at the resultset closer in the QuickWatch window.  We didn't look carefully enough because everything looked correct... so we started removing one object at a time until we could prove that the culprit was corrupt data in our resultset.

Finally we expanded two objects in our collection at the same time in the QuickWatch window and started comparing.  We noticed that one instance's enum property was retuning the name of the assigned enum and another showed an integer value.

After asking why that would happen, it dawned on me that it must be an invalid enum value and therefore couldn't resolve to a name when ToString() was called.  I assume to fail gracefully, Microsoft had their Enum.ToString() try to do name first and just fall back to the value of the Enum's base type if it couldn't resolve the name, rather than throwing an Exception.

Examining the implementation of the enum quickly confirmed the suspicion.  After probing other coworkers, we discovered the erroneous query that had been run against the database.  :)

I assume what happens is an exception occurs when the WCF tries to serialize the object to send across the boundary... but the exception is swallowed up and the Fault Exception with the less-than-helpful error message is returned to the consumer of the service.

Moral of the story: Be careful when using Enums that map to data in your database.  Make sure they always match the allowed values in the database (which is easy to do if you have look-up tables and use an ORM (like PLINQO, etc.) to generate the enums for you. 

Also, if you use "switch" statements in your code on the enum value, make sure your default case handles an invalid enum value scenario.  For instance, you've made a switch statement that contains a case block for all valid enum values.  Your default case can throw an ArgumentOutOfRangeException so you can quickly detect when something like that happens.

This will be harder to detect in scenarios like the one I described above, because the code is still "valid" at compile and runtime until the sucker is serialized.  I don't know what the best practice solution is for that scenario, but I do know I want a better FaultException passed to me if serialization breaks before being passed from the WCF service.

Guess I have my work cut out for me tomorrow.

For those like me that have a hard time visualizing what I'm talking about... here's a contrived example.

public enum ReportType
{
  Html = 1,
  Excel = 2,
  Pdf = 3
}

The query to the database changed the offending records to 0, 4 or some other number that wasn't the valid values.  (Incidentally, my coworker really meant to change another int field's value... but ended up typing the wrong column name.)   Too funny.

And now you know... go forth and make sure you aren't bit by this problem.

Silverlight and Unit Testing - Reference Gotcha When Testing View Code

I'm new to Silverlight and am still learning my way around various nuances of the platform.

I like it so far and have been learning a lot. When a recent check-in was made by a co-worker to our project at work, we had around 90 of over 800 unit tests broken with this error in each of them:
The attachable property 'TransitionEffect' was not found in type 'ExtendedVisualStateManager'.

Being new to XAML, I had no idea where to start, except to go find the .xaml files resource dictionaries to try to figure out what the problem was.  Searching the internet made it sound like I had x:Name attributes with the same values from different dependent XAML files.

I should mention I was working in a UserControl XAML file to begin with, and started searching up the dependency hierarchy to see if the naming problem was the real issue.

The XAML files were quite large, so finding all the x:Name attributes and comparing them was going to take a while.  I opted to approach this using LINQPad.  I replaced quotes with double-quotes in the XAML so I could bring it into LINQPad as a string constant and loaded it into a XDocument object; using LINQ to XML to find matches from the other file's XAML for me.  After discovering one, I fixed it and re-ran my unit tests.  I still got the same error.

What I didn't understand was that the application ran fine and the effect was working... why on earth wouldn't it work in our unit tests?  It should have dawned on me that both the application project and the unit test project required the appropriate DLLs to be referenced in order for that namespace to be available.

Sure enough, the application project had them but the unit test project did not.  As soon as I added the references, the tests passed with flying colors again.

The required references, for those that get the exact same error:
Microsoft.Expression.Effects
Microsoft.Expression.Interactions
(both part of the Silverlight v4.0 Toolkit)

Moral of the story: When you add references to your application project, make sure you add them to the corresponding unit test project if necessary as well.

Now the next question... Why was I required to have those when I wasn't rendering any UI, but merely using the View classes in the unit test?  It seemed as if the XAML was still being parsed.

This makes sense, being as your View classes are declared as partial and the other piece to this partial puzzle is the XAML file.  Remember that whenever the View class is constructed, the InitializeComponent method is called, which parses the XAML and sets up everything declared there (correct me if I'm not describing that accurately!)

That said, if you're going to unit test a view file, you have to make sure that anything required by the XAML files are also referenced.  It's easy to take care of that for the C# files because you get compile-time errors, but you don't necessarily with the declarative XAML files.  A drawback, but one that can be handled if we're aware.

Bottom line... remember that both the XAML and corresponding C# file make up your View class and both files' reference requirements must be met to ensure all namespaces/code are available for your unit tests.

I hope this will save you (and myself) a lot of time in the future if I ever encounter this problem again.

2010-08-26

Making sure JavaScript gets called after an AJAX Partial Postback in ASP.NET

ScriptManager.RegisterStartupScript(Page page, Type type, string key, string script, bool addScriptTags)

Notice the first parameter of this method, as it has an overload that takes a Control as its first parameter.  When you use the Control overload, it only registers the startup script once on the initial rendering of the page.

If you use the Page overload listed above, it will register it for every asynchronous postback to ensure your JavaScript is executed everytime.

Remember to use ScriptManager and not ClientScriptManager...

From the Remarks on the MSDN article for the overload listed above:
"You use this method to register a startup script block that is included every time that an asynchronous postback occurs. To register a script block for a control that is inside an UpdatePanel control so that the script block is registered only when the UpdatePanel control is updated, use the RegisterStartupScript(Control, Type, String, String, Boolean) overload of this method.

If you want to register a startup script that does not pertain to partial-page updates, and if you want to register the script only one time during initial page rendering, use the RegisterStartupScript method of the ClientScriptManager class. You can get a reference to the ClientScriptManager object from the ClientScript property of the page."

Also very important:
Make sure you have the following using statement in your codebehind...
using System.Web.UI;

If you don't, you will get the error:
Cannot access internal property 'ScriptManager' here

2010-07-30

Having Two Consecutive Hyphens in XHTML Comments Causes Anomalies in Firefox

Check out my experiment page to see the different side effects this issue causes.

If you're seeing weirdness when having hyphens in your (X)HTML comments, it's most likely because you're using two adjacent to each other, which is a big no-no according to the W3C.

Avoid using hyphens in your comments to avoid the issues... dumb, but required.

I know we're all prone to yell at Mozilla and tell them they're doing it wrong, because all the other latest versions of other browsers will still honor the comments, but Firefox isn't necessarily doing it wrong, because as I understand it, they're allowed by the standard to not honor the comment if there are two adjacent hyphens together.  In one way I think it's good that Firefox doesn't, because it forces we, the web authors, to follow standards.

On the other hand, I think the standard is flawed and that nothing between the start and end of a comment should matter... so part of me wishes Firefox would do like the other browsers and still honor the comments.

Oh well, go the safe route and keep hyphens out of your comments.

2010-06-10

Visual Studio 2008 Crashes When You Stop Debugging After Rearranging Windows

I don't know what caused it... but somehow I managed to get Visual Studio 2008 in a state where it would crash if I tried rearranging debug and properties windows, etc and then later stopped the debugger.  Not only did it crash, but the app hung and would only close if I opened Task Manager and killed the devenv.exe process.

I started hunting and found this hotfix on MSDN, but then noticed in the comments a nicer solution to try before applying the hotfix.  The solution is simple:
  1. Start debugging
  2. Window >> Reset Window Layout
  3. Stop debugging
This worked great for me... your mileage may vary.  If it doesn't work, try downloading the hotfix.

2010-05-16

Introducing document.queryString for JavaScript

I got sick of not having a quick/easy reference object in JavaScript for getting a query string parameter's value.  JavaScript has always offered the window.location.search property to get the entire query string, but who wants to parse that every time?

So I set out to see how long it would take me to make a quick parser that would load it into a nice object that I could jam on the document.

Roughly 30 minutes later, I had one.  It also handles param names that contain periods (person.firstname) which is nice for those that do that with their ASP.NET MVC projects.

I don't have any docs yet, but see the quick write up at my JavaScript Jedi website if you'd like to see it in action and perhaps try it for yourself.

Enjoy!

2010-03-12

Syncfusion MVC Grid - Prevent "A potentially dangerous Request.Form value was detected from the client" error

While working on an ASP.NET MVC project, using the Syncfusion Essential Grid for MVC, we had two pages utilizing the grid.  One page worked fine for displaying the data and paging/sorting.

The other page would show the results, but would fail on the AJAX calls back for paging/sorting.  It baffled me for several hours.  I compared all the settings between the two pages and I couldn't detect any differences between how each was set up.

I finally got frustrated and launched the site in Firefox, using Firebug to monitor the requests.
Props to Firebug, as it was the key to helping me find the solution; as AJAX calls don't show you ASP.NET error HTML when a request breaks... Firebug showed me.  The result was enlightening:


"A potentially dangerous Request.Form value was detected from the client..."
Interesting.  Do you see the "br"eaking issue here?

That's right... ASP.NET does request validation on all requests by default, to ensure prevention of cross-site scripting (See the MSDN article "How To: Prevent Cross-Site Scripting in ASP.NET" for more explanation.)

We were adding the tags into the HeaderText() calls on the cells in the grid setup on columns where the data in that column was guaranteed shorter than the header text, so we could avoid growing the table unnecessarily wide.

As soon as I removed those tags, it worked like a champ.

So be warned, don't put any HTML tags in your HeaderText calls, or you'll be bitten the same.  I hope this saves someone else several hours of pain.  I know it will save me in the future when I run into other Syncfusion grids in our app that are mysteriously not performing their AJAX calls correctly.  That'll be the first thing I look at.

(And did I mention that Firebug rocks?!)

2009-08-04

PLINQO! (No, not the game on Price is Right.)

My friend Tyler introduced me to PLINQO, a killer looking LINQ to SQL ORM data layer, for a side project I'm collaborating with him on.

I'm total newb to it, but I drooled when he gave me a quick crash course on how it works. It's giving me a wonderful opportunity to brush up on the LINQ skills and remember why I love .NET development so much.

I'm excited to see how it plays out for me... if I like it enough, I'll start using it in my own personal projects.

One thing I've been impressed with in the VERY short time I've used it so far, is how easy it is to pick up and run with.

How can you not like this:
public string[] GetStateEmployeeNames( int stateId )
{
string[] stateEmployees = (
from se in this.DataContext.StateEmployee
join e in this.DataContext.Employee on se.EmployeeId equals e.EmployeeId
where se.StateId == stateId
orderby e.Name
select e.Name).ToArray();

return stateEmployees;
}

It's goodness... I can't wait to see what other ease and power PLINQO will offer. Stay tuned...

2009-06-29

Ensure XHTML Strict Compliance by Removing Name Attribute from Form tag in ASP.NET

Many of us web developers are trying to be "good citizens" and conform to the higher standards of XHTML in our apps.

By default, ASP.NET will add the name="FormName" attribute to the rendered XHTML.

To force ASP.NET to omit the name attribute, simply add the following tag to the system.web section of your web.config file for your app:

<xhtmlConformance mode="Strict" />


Be warned, however; unfortunately it doesn't seem to make ASP.NET render HyperLinks properly. I have an asp:HyperLink that happens to have an ampersand (&) in the Text and ToolTip properties. The ToolTip properly renders a title="" attribute with the ampersand encoded as &amp; ... but the text between the open and close <a> tags doesn't have the ampersand properly encoded.

The only advice I can give you there is to:
1. Use the word "and" instead of an ampersand
2. Make static "a" tags instead of using the ASP.NET HyperLink object, if you can. If someone knows a smoother/quicker/more elegant solution, please leave a comment with it!

2009-04-29

"The breakpoint will not currently be hit" "The source code is different then the original version"

Today, I was debugging an ASP.NET website. I was at a breakpoint when a co-worker called me over to their desk to help with a defect they were trying to reproduce.

I needed to use remote desktop to look at something on my own machine, so I did so. While I was accessing it via remote desktop, my Visual Studio decided to crash.

Aftwerward I started seeing the following on breakpoints I was trying to hit:
"The breakpoint will not currently be hit. The source code is different then the original version"

I thought that a reboot would help, but to no avail.

After talking to another co-worker that had seen it in the past, he informed me that he fixed it by deleting all of the Temporary ASP.NET Files.

Sure enough, it worked like a champ. However, I had to shut down anything that had handles on those files (like the ASP.NET development server, Visual Studio, etc.) before I could complete the delete.

So to fix the problem:
  1. Close out Visual Studio and make sure any instances of ASP.NET development server are closed as well.
  2. Delete everything from "C:\Windows\Microsoft.NET\Framework\v.2.0.50727\Temporary ASP.NET Files" (where v.2.0.50727 is the version of the .NET Framework your site is running on.)

Hope this helps someone else... it sure helped me.