More on MembershipProvider API design

I blogged recently about what I saw as flaws in the design of the ASP.NET MembershipProvider API. Robert McLaws responded in comments:

Mike, your argument is incorrect. Microsoft development guidelines clearly state that exceptions are expensive and should be avoided whenever possible. The Provider Model was not designed to make the decision for you on whether or not something is exception-worthy, that is why this specific function returns a boolean. If the exception is going to be thrown, it should happen either inside your custom Provider (which is again not recommended because they are expensive) or from your method call.



I stand by my original argument, but perhaps I need to elaborate on my position. I am well aware of the cost of exceptions, and I agree that one should be cognizant of the overhead. Still, I feel strongly that as long as exceptions are not abused (for flow control, for example), they ought to be the preferred way to handle “exceptional” events in code. Doing otherwise, just because Structured Exceptions incur overhead, but without having a measured reason to do so, is a clear example of Premature Optimization.

Back to the MembershipProvider API. Robert stipulates that the designers of the API did not want to force the SEH paradigm onto its users and thus chose the approach where function calls return boolean “success” flags. On first glance this argument has merit, so lets assume Robert is right in his assumption. I still have two problems with the API.

First of all, the ChangePassword call is not something I would expect to be executed with such frequency that the failure rate would be high enough for the Exception handling overhead to matter regardless of how busy your web site is!!! So, either the method declaration was chosen to match other method(s) that do match this pattern (which one(s)?!?); or we are back to premature optimization; or Microsoft decided that Structured Exceptions are not appropriate for web development in general. That last one I just don't believe.

The other problem I have with the ChangePassword definition is that even if we were to assume that Robert is correct, that Microsoft measured and concluded that exceptions caused too much overhead for MembershipProvider scenarios, that using them was just not appropriate here, I still think they need to rethink the naming convention. At the very least ChangePassword and its ilk should become TryChangePassword to match a similar convention adapted for type convertion for these, presumably same considerations.

posted @ Friday, August 6, 2004 8:12 PM

Print

Comments on this entry:

# re: More on MembershipProvider API design

Left by Drew Robbins at 8/6/2004 9:27 PM
Gravatar
Just a thought. One thing to be careful of is providing a way for outsiders to intentionally cause exceptions (by intentionally failing login attempts or change password attempts). Since there is some expense to an exception, it could give attackers a trivial way to launch a Denial-of-Service attack on your website. With that said, I'm not aware of any way to authenticate against Windows without doing try/catch on a login attempt that fails with an exception.

# re: More on MembershipProvider API design

Left by Robert W. McLaws at 8/7/2004 12:43 PM
Gravatar
I agree with Drew. Why would you want a login attempt, or a password change, to fail with an exception? Saying that "they're won't be enough traffic" is seriously irresponsible as an application developer.

I do agree however that the methods are a little restrictive. You should file a bug in the MSDN Product Feedback Center, and then post a link here so we can vote on it. I can also contact the guy that wrote the code directly and ask him if he can add a method overload that accepts a user object in the method calls.

# re: More on MembershipProvider API design

Left by Eric Newton at 11/11/2004 1:45 PM
Gravatar
I'm not really sure I'm understanding what you're arguing.

I would say that a call to ChangePassword should either WORK SUCCESSFULLY, ie the password changed, or an EXCEPTION occurred (db not available, bad datatype, etc). ChangePassword IMO should never return false, so I'm with you on that.

However, ValidateUser *should only* return a boolean because the question is being asked "Is this user valid: Yes or No." If the db is not available, then THAT is an exception, not when the user doesnt exist in the db... ValidateUser should just return FALSE or possibly a "UserNotFound" flag via an enum or something.

Same with Membership.CreateUser. It has a create status enumeration that indicates maybe why it returned Null instead of a MembershipUser.

I dont feel this is Premature Optimization, just common sense coding practice. Think about it, in most cases, exceptional situations cannot be handled by code... that's a lot of AI to try to "figure out" what happened and how to proceed, as code. Of course you can always ask the user, but usually the user doesnt know WTH happened ;-)

# re: More on MembershipProvider API design

Left by Michael Teper at 11/11/2004 8:17 PM
Gravatar
Eric, its been a while since I posted this, but I don't recall taking an issue with the ValidateUser method. In any case, it appears the ASP.Net team listened and the API will get a facelift for the Beta 2 drop.

# Thank you very much for such a good work

Left by Burro Leoving at 7/13/2006 8:30 AM
Gravatar
Very many thanks for a good work. Nice and useful. Like it! Burro Leoving.
Comments have been closed on this topic.