I have a weird issue with a simple validation rule. I have a custom StringRequired rule. For some reason it works great in Debug and Release mode when run from VS2005. However, when I run the release version outside of VS the rule always fails! The only work around is to add code into the 'set' block on the business property that manually calls the rule, 'ValidationRules.CheckRules("ProperyA")'
Does anyone have any idea on this one?
Are you using PropertyHasChanged() or PropertyHasChanged("PropertyA")?
If the former, try the latter - you may be getting hit bit a JIT compiler optimization. And if the former, you are using the NoInlining attribute right?
Rocky,
I'm using the former, the PropertyHasChanged(). Also, I have no idea what the NoInlining attribute is.
Jon
In that case I suggest you switch all your CanReadProperty(),
CanWriteProperty() and PropertyHasChanged() calls to use the overloads that
require the property name be passed as a parameter. That should address your
issue.
Rocky
From: JonM
[mailto:cslanet@lhotka.net]
Sent: Friday, November 16, 2007 7:39 AM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] Validation rules not working in release mode
Rocky,
I'm using the former, the PropertyHasChanged(). Also, I have no idea
what the NoInlining attribute is.
Jon
The attribute prevents the JIT compiler from using an
optimization called “inlining”, where the compiler basically does a
copy-paste operation on your code to merge code from one method directly into
any code that calls the method.
Rocky
From: JonM
[mailto:cslanet@lhotka.net]
Sent: Friday, November 16, 2007 8:24 AM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] RE: Validation rules not working in release
mode
Okay. Thanks. So what does the no-inlining
attribute do?
JonM,
Follow this thread http://forums.lhotka.net/forums/thread/5749.aspx it explains in more detail.
Ken
The JIT compiler takes the code in one method and writes it in-line with the calling code so that there is 1 method, not 2.
When using the no-inlining attribute the JIT compiler skips that optimization.
Rocky's advice to use the overload is good for 2 reasons.
1. It solves your poblem.
2. It skips the stack trace method which could be a perofrmance hit - and may have other issues in the future. It also makes it clear what you are doing.
This is extremely easy to use with a code generator. I strongly recommend it.
Joe
Hi there,
Did you get resolution for your issue?
I am facing the same problem and i have tried both solutions suggested by Rocky.
One to use PropertyhasChanged() and Noinling, other to use PropertyHasChanged("Commenttext").
I am also using StringRequired validation rule from CSLA for the property "commentText".
thanks in advance. Will really appreaciate a reply to this.
The whole NoInlining concept, along with the overloads of methods that automatically determine property names has been obsolete now for several years. Any current version of CSLA has those methods actually marked as obsolete, so you should get compiler errors (or at least warnings) for using them.
They are broken. Do not use them.
The reason I switched away from them a few years ago was because the 64 bit JIT compiler in .NET uses other optimizations that can't be disabled. The whole automatic detection of property names was clearly not something .NET would support.
The only safe answer is to switch to the overloads of CanReadProperty/CanWriteProperty/etc that take an explicit property name. Remember that the strings and property names are case-sensitive.
Or move to CSLA 3.5 or hgiher and use managed properties, which do all that work for you - saving you around 50% of the code you used to write and maintain by hand.
Thanks Rocky. We are not currently upgrading to the newer version of CSLA. I will keep this in mind though.
In addition to Rocky's advice you may want to check for case sensitivity.
Property "commentText" should call PropertyHasChanged("commentText") and not PropertyHasChanged("Commenttext").
Joe
I implemented the change, then From VS, I set my mode both on my windows app and my Business layer (both in teh same solution), = Release. I run the solution in release mode, i test my code change and it seems to have fixed the issue.
I now, take the complied version to put it into the test server, and do the same test there and see that this fails. I still get the same issue described in this. What could i be doing wrong?
I have double checked that i have release mode set.
Did you switch your code to explictly provide the property name on all CanReadProperty, CanWriteProperty and PropertyHasChanged method calls?
So you are no longer using the overloads that automatically detect the property names (because they don't work on 64 bit machines)?
And you are sure that the spelling and capitalization of the property names is exactly the same as the property itself?
thanks for getting back.
Yes, I switched my code to explicity call out the property name - propertyhaschanged("propertya").
I checked the property names, it is spelt correctly and i understand it is case sensitive.
In that case I have no idea why it wouldn't work in release mode.
You can override PropertyHasChanged - try overriding it and throwing an exception or writing a trace log statement - basically I want you to see if that method is actually being invoked in release mode.
The only thing I can think, is that you have an exception being thrown from one of your rules. An exception that is only occuring in your release environment. And that exception is never seen because data binding hides it.
In other words, the rules are actually running, but one or more are failing and data binding is hiding that fact from you.
thanks. Let me experiement your thougts.
The weird thing is that i get a blank validation message box.
"You have to correct teh following errors and try again". but there are no errors listed. Thats why i thought the code change would fix this to begin with.
What is displaying this validation message box? Your code?
Copyright (c) Marimer LLC