Architecture question

  • Thread starter Thread starter Michael Rodriguez
  • Start date Start date
M

Michael Rodriguez

If you're using a standard 3-tiered architecture, i.e. Data Layer-> Business
Layer->Presentation Layer, where is the recommended place to put data
validations? Specifically, data validations such as "Please enter a name."

It seems like the best place to put them, from the programmer's point of
view, is in the business layer. That way the same validations work for
either Winforms or Webforms. Also, if I redo my interface later, I don't
have to redo the work.

However, the best place to put them as far as my users are concerned is
probably the presentation layer. That way I can not only say "Please enter
a name", but I can set the focus to the name control and possibly even turn
on an error provider (which seem hokey at best).

Thoughts?

Mike Rodriguez
 
Michael,

Put them in the business layer and make them callable by the presentation
layer. My business layer returns record(s) and provides validation
mechanisms for individual fields and record-level validation, as well as
checking all the fields at once if desired.

This is always a thornier problem with web apps because the client-side
validation must be in a different language (JavaScript) and often has to
duplicate server-side validation logic, which ends up acting as a "safety
net". There really is no clean way around that other than to use server
controls for everything and rely on the server for all validation. This
makes development easier, but doesn't give the user the kind of "rich
experience" (immediate and specific feedback) they expect. And/or it
generates a lot of post back activity that burdens the server and slows down
the user.

Going in the other direction there's the matter of database rules /
constraints and where they should live. I think that most people seem to be
relying on the database itself to act as a "safety net" if nothing else --
at least for database-specific issues such as enforcing relationships
between tables.

In other words: in a web app, your presentation layer should validate
everything and should never let anything incorrect through to the business
layer, but the business layer is there as a safety net and a way to
formalize your business rules and share them across applications. Likewise,
your business layer should call the approparite things in the data layer
which should never issue any requests to the DB that would violate DB
integrity. But, the DB constraints are there as a safety net.

All of this effort makes more sense when you have many applications doing
overlapping tasks or sharing the same data. At the individual application
level, especially for a first project, sometimes it seems like a lot of
extra implimentation.

--Bob
 
Bob Grommes said:
Michael,

Put them in the business layer and make them callable by the presentation
layer. My business layer returns record(s) and provides validation
mechanisms for individual fields and record-level validation, as well as
checking all the fields at once if desired.

Hi Bob,

How exactly are you doing this? Do you just set the row.RowError to the
first error you find then display that in the winform? Do you also set the
focus to the field in question? If so, how do you pass that info back to
the presentation layer? Some code samples would be great... <g>

BTW, my particular case is mostly a windows app, although some webform
options are possible down the road.

Thanks,

Mike Rodriguez
 
Mike,

In a WinForms app you generally call the business layer validator for a
field from that control's Validating event, to determine whether or not the
value is correct, e.g. something along this line:

string strMessage;
if
(myBusinessObjectForTheAppropriateTable.FieldIsValid("FieldName",this.Text,ref
strMessage)) {
errProvider.SetError("");
// or do the above in the Validated event, which won't fire if
// we set the CancelEventArgs below.
} else {
errProvider.SetError(this,strMessage);
eventArgs.Cancel = true;
}

That would keep the focus on the errant control and put up an error
notification next to it.

The control knows what field it corresponds to in the DB. Or sometimes I
have what I call a BusinessView that orchestrates several tables and has the
attributes of interest from all of them.

There are really about 100 right ways to do this, and 1000 wrong ones. If
you're new to it, you might want to spend some time studying up on
multi-tier designs and possibly adopt one of many that are out there at low
or minimal cost as a starting point. For example, Rockford Lhokta (sp?) has
a pretty good framework out there that comes out of his book, and there are
various code generation products that can spit out your data and business
layer code for you.

One thing you will want if you do n-tier design, is a code generator.
Otherwise you will quickly drive yourself crazy writing alot of boring
gruntwork code.

--Bob
 
IMO you have to put them in each layer:

- In the presentation layer, to be able to get the label text of the
textbox, so you can compose an error message consistent with the user
interface, and also you can put the focus on the control.

- In the business layer, because your component can be called from who
knows...

- In the database, using a NOT NULL constraint, to avoid invalid data no
matter who tries to insert it.

--
Best regards,

Carlos J. Quintero

MZ-Tools: Productivity add-ins for Visual Studio .NET, VB6, VB5 and VBA
You can code, design and document much faster.
Free resources for add-in developers:
http://www.mztools.com
 
Bob,

I've been doing UIs for about 15 years, I'm just new to C# and the n-tier
design aspect of it. I did get a code generator, My Generation, that was a
*major* time saver. I generates my data layer, web service layer, and
business layer for me, all based on the tables in the db. I don't know what
I would do without it!

I have a couple of issues with the validating event approach. First of all,
what if they don't leave that field? They might just close the screen,
which would call my form level save changes event, but not the field level
event. Also, I'd rather not have to attach event handlers to every field.

Your initial response did give me an idea I hadn't thought of. I think I'll
have the business layer do the validations, as you said. But instead of
throwing exceptions, it will assign column error descriptions to the fields
in error. Then then the windows form can cycle through the columns of the
table and attach error providers to the appropriate controls. That way the
business layer does the logic and the winform layer does the presenting of
the errors. The best of both worlds...

Thanks,

Mike
 
Michael,

I have ValidateAll() and ValidateRecord() methods in my business layer, in
addition to Validate().

Validate() -- for validating indvidual fields
ValidateRecord() -- for record-level validation, that is, integrity between
different fields
ValidateAll() -- calls Validate() for all the fields, then ValidateRecord().

So ... if some UI quirk causes a field validation to be skipped, it's still
caught when the record is saved, because at that point I call ValidateAll().

I actually have a class in the business object called MessageList (derives
from System.Collections.Specialized.StringList) which the UI can access.
This allows the UI to present a complete list of complaints to the user if
desired; or, you have the option to present the message for just the first
error encountered.

--Bob
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top