Server Side Validation

Server Side Validation

Old forum URL: forums.lhotka.net/forums/t/4370.aspx


stanc posted on Tuesday, February 19, 2008

There are some validations I need to perform that needs to access the DB. So, I created the validations and tied them to bogus properties, so that they wouldn't be called until I called them from the server side. On the DP Update and Insert, I am calling my validations and am exiting the update/insert call if any of the validations fail. All is good.

But now my question, I would like to throw an exception (Validation Exception) when this occurs. The problem is that about time the exception reaches the UI the DP has already caught it and re-thrown it as a DataPortal Exception. Is there a way around this? I could always just check the Broken Rules collection after the Save, but I feel this is a better way to make sure the UI doesn't miss the fact that the item wasn't saved.

I know I could also call the validation prior to calling the Save. The problem I have with that, is that it would require an additional call to the server if everything checks out.

Any input would be appreciated.

thanx

stan

RockfordLhotka replied on Tuesday, February 19, 2008

I think there are a few options, depending on what you'd like to do.

The DataPortalException includes the business object graph as it was when the exception was thrown on the server - that's really the point of this exception (that, and bringing back the full stack trace).

So one thing you could do is not throw a client-side exception at all, but instead return the object in its invalid state, including the broken rules from the server. The one drawback to this is that you'd have to figure out a way to unbreak them (or ignore them) so a subsequent Save() call would work.

This would look somewhat like this pseudocode:

protected override MyType Save()
{
  MyType result = null;
  try
  {
    result = base.Save();
  }
  catch (DataPortalException ex)
  {
    if (ex.BusinessException is ValidationException)
      result = ex.BusinessObject;
    else
      throw ex.BusinessException;
  }
}

Of course this would require the UI to check the object to see if it IsValid after the Save() call.

But this code snippet illustrates most of the capabilities embedded in DataPortalException, and you can probably see other interesting ways to use or rethrow the exception, etc.

rsbaker0 replied on Tuesday, February 19, 2008

stanc:

There are some validations I need to perform that needs to access the DB. So, I created the validations and tied them to bogus properties, so that they wouldn't be called until I called them from the server side.

We have standard business rules that do this, but why restrict them to the server side? 

I have a working theory that anything that is "broken " (per CSLA) should be detected in the property setter, whether this is done client or server side. So far, this is working very well for us. You just have to be sure that the DB access done in the validation rule is data portal safe.

I'll give you an example. Our application enforces referential integrity via the objects rather than at the DB level, and all the property setters that correspond to foreign keys have a referential integrity rule that probes the database when the property is set to ensure the corresponding primary record exists. It works great.

We had mainly intended this to protect the data from unintended user breakage, but the rules also fire when we are executing internal transactions that set the same properties. It's a lot of SQL thrown at the database (and I already have envisioned a mechanism to suspend it during transactions if necessary), but so far the whole process is much fast than the technology we are porting from.

 

JohnB replied on Tuesday, February 19, 2008

rsbaker0:
I'll give you an example. Our application enforces referential integrity via the objects rather than at the DB level, and all the property setters that correspond to foreign keys have a referential integrity rule that probes the database when the property is set to ensure the corresponding primary record exists.


So obviously you're hitting the database a lot. Are you using remoting/WCF? You mentioned that it works great but I'm curious about the number of trips you're making across the wire using this technique.

John

rsbaker0 replied on Wednesday, February 20, 2008

JohnB:
...So obviously you're hitting the database a lot. Are you using remoting/WCF? You mentioned that it works great but I'm curious about the number of trips you're making across the wire using this technique.
...

With the referential integrity case, we only hit the database when the user actually changes a property that corresponds to a foreign key (and there really is change in the value), and the whole object doesn't go across, it's just a simple Exists command (CommandBase) executed by the validation rule.

I would agree that care must be exercised, but I certainly think it's reasonable to have a client side validation rule make a data portal call.

I think the benefit of showing the user immediately what is wrong is better than waiting until they "save" the object, and the whole object has to go across and then you deal with the exception rather than blocking the save attempt in the first place.

vdhant replied on Wednesday, February 20, 2008

Just an observation, I am assuming that you are using a windows app and not a web client. If you are using a web client I would be interested in how you go with performance etc when you do a postback when ever the client changes data on an individual form element level. 

rsbaker0 replied on Wednesday, February 20, 2008

vdhant:

Just an observation, I am assuming that you are using a windows app and not a web client. If you are using a web client I would be interested in how you go with performance etc when you do a postback when ever the client changes data on an individual form element level. 

We have both a WinForms application and a web client.

Again, I don't disagree that you don't want a round-trip to the server on every element change, but in practice reasonable use of validation rules that involve a data portal call is proving to be acceptable.

JoeFallon1 replied on Thursday, February 21, 2008

In my web app I also use rules that hit the DB.

I changed the priority on those rules from 0 to 1 so they only run after all the "non-DB" rules are valid.

So it is theoretically possible that the user could post back the page and be told they have to fill out some more stuff - which they fill out - and then get told they have to do something else because now the DB rules kicked in and another modification is required. But in practice this is quite rare.

Joe

 

Copyright (c) Marimer LLC