Server side validation

Coordinator
Sep 11, 2008 at 9:22 PM
Though this control will focus mainly on the client-side validation, we must also implement server side validation for two main reasons that I see:
  • The user may have JavaScript disabled.  We should be returning a validation message for that scenario.
  • Even if the AJAX based validation works, we need to properly handle the BaseValidator methods that set Page.IsValid.
Thoughts on how best to do that? 

Maybe we should call the web service via reflection, in EvaluateIsValid()? 
Developer
Sep 12, 2008 at 2:42 AM
Rather than call the web service through reflection, I think a better approach would be to move the user name checking code to a helper class that both the web service and the EvaluateIsValid method can access.

IMO, a web service should normally have almost no code inside of it. Rather, it is a entry point into a business function. Today I may want to execute my business function through a web service; tomorrow I may want to access it through WCF; and next week I may need to back track and call it through remoting! If I place the business functionality inside the web service itself, I'm going to have copy it over and over to handle all of those cases, which we know is unmaintainable.
Coordinator
Sep 12, 2008 at 3:53 AM
How would that helper class figure into the user created ASMX?  Would they need to create both the ASMX and another class, for default functionality?

See also: http://www.codeplex.com/UsernameAvailability/Thread/View.aspx?ThreadId=35298
Developer
Sep 12, 2008 at 5:48 AM
I think I spoke (posted) too soon.

There's a bit of a dilemma here, which you suggested we get around using reflection that I simply missed when I first read the post.

If we want the control's EvaluateIsValid and the ASMX's IsUsernameAvailable method to share the same method to check username availability, the method must exist in either the control library as a static method that's accessible by the control and by the web service, or the EvaluateIsValid method must use reflection to execute the method stored in the ASMX (as you suggested).

When I posted initially, I made a bad assumption that the Membership provider pattern would be used to check the username's availabilty. If this assumption had been correct, then the code to check the username would always be the same and the provider would just be switched out using the web.config. Then, a helper method could be written, placed inside the control library (developed by the control writter) that simply called into the Membership class and the control's EvaluateIsValid and the ASMX could share this method.

But, I don't think it stated anywhere that the control is limited to only use the Membership provider to check for availability. I think it can, but that's probably up to the page developer's discretion; although the Membership Provider model does provide for some flexibility at the page developer level.
Sep 12, 2008 at 2:58 PM
I think for the best flexibility and compatibility, we should closely follow the pattern of the CustomValidator, which takes the name of a server-side method, and accesses it via reflection.   The advantage of this is that it allows us to "hard-code" the webservice and client-side script.  The user provides one simple method, and the control handles everything else.  The disadvantage is that this method has to be somewhere that the webservice can instaniate it -- that probably means in a class by itself, and not a method of the page class.
Sep 13, 2008 at 11:53 PM
Is there a problem with calling the webservice again server side?
Sep 14, 2008 at 11:35 PM

>> Is there a problem with calling the webservice again server side?

Not really a "problem", but calling a server method from another server method and fast & easy.   Calling a websevice from a server method is slow & complicated.

Coordinator
Sep 15, 2008 at 2:38 PM
Calling a web service on the server side isn't very difficult.  You can create an instance of it and call it like anything else:

MyService serv = new MyService();
MyService.HelloWorld();

The problem here is how to do so dynamically, with the user supplied service and method.  This should be possible through reflection.
Sep 15, 2008 at 6:11 PM
Except you probably don't want to be doing a synchronous call to a webservice on the server.  Making a asynchronous call added to the complexity.
Coordinator
Sep 15, 2008 at 8:09 PM
If we call it asynchronously in EvaluateIsValid(), is there a way that we can still provide an accurate Page.IsValid?
Sep 15, 2008 at 9:07 PM
Hmmm... Good point.  For best turnaround time, I'd guess we'd need to call the BeginCheckAvailability on postbacks in the control.Load() method, and have the callback update the IsValid property, with IsValid's getter, Validate and EvaluateIsValid blocking until the callback is received.
Coordinator
Sep 16, 2008 at 8:58 PM
That sounds like a great idea to me.  Want to take a shot at implementing it?