Custom Validation rules

Custom Validation rules

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


jigjosh posted on Tuesday, April 14, 2009

I have very simple BusinessBase Objects like City, state , country , employee and so on, I want to validate that Name is not duplicate
i mean when user enter duplicate name at same time the object become invalid

pl let me know how to make common rule for the same

thanks

jignesh

RockfordLhotka replied on Tuesday, April 14, 2009

This is a very complex problem, if I understand your question correctly.

You want to make sure that two different users are notified that they are entering the same Name value at the same time?

This has been discussed on the forum numerous times, and it is very complex.

To solve this problem, you obviously need a way for the computers of the two users to interact with each other in real time. So every computer using your application must be connected to all other computers using your application, so they can all send the keystrokes of every user to every other computer.

That's pretty unrealistic. So the closest thing to this is to have a central "message server" that all the computers connect to, and instead of sending every keystroke, they send every field value as the user tabs off the field.

Even then, the communication level is pretty unrealistic. So a publish-subscribe model is used, so when a user starts adding a Customer, the application asks the message server for all messages related to "add or edit customer data". And the application starts sending all changed field values to the message server with the "add or edit customer data" tag.

The problem of course, is that Windows has no built-in mechanism to do any of this. So you'll need to invent your message server, your communication protocol and deal with all sorts of error cases (like what happens when a subscriber computer just disappears off the network - how do you detect this and clean up any open communication channels, etc).

And what's even worse, is all this work is really just for a hint that there might be a problem. You really don't know if a value is a duplicate until the point when you try to commit the update into the database. That is the only point you know for sure that there's a duplicate value. Everything else is just a hint, but due to timing issues it is absolutely possible for two users to enter duplicate values and never know it until the second user's value is known to be a duplicate in the database.

In short - this is not a CSLA validation rule issue - this is an issue dealing with concurrent computing, publisher/subscriber message patterns, network communication and data concurrency.

If you have a pub/sub messaging server, then it can become a CSLA validation rule, and it really isn't that hard to do.

JoeFallon1 replied on Tuesday, April 14, 2009

Rocky's answer is comprehensive.

If you just want to add a rule to do the check in your BO you could use code like this in your BO:

ValidationRules.AddRule(AddressOf ActiveRecordExists, New ActiveRecordExistsRuleArgs("Vendno", "vend"), 1)

And code like this in your Rules class:

'New records must exist.
'Edited records must exist unless it is the originally saved value.
Public Function ActiveBuyerExists(ByVal target As Object, ByVal e As RuleArgs) As Boolean
Dim ruleArg As ActiveRecordExistsRuleArgs = DirectCast(e, ActiveRecordExistsRuleArgs)
Dim propertyName As String = ruleArg.PropertyName
Dim propertyDescription As String = ruleArg.PropertyDescr
Dim tableName As String = ruleArg.TableName

Dim value As String = CStr(CallByName(target, propertyName, Microsoft.VisualBasic.CallType.Get))
Dim origvalue As String = CStr(CallByName(target, "Orig" & propertyName, Microsoft.VisualBasic.CallType.Get))

Dim bizObject As Csla.Core.BusinessBase = DirectCast(target, Csla.Core.BusinessBase)

If (bizObject.IsNew) OrElse (Not bizObject.IsNew AndAlso value <> origvalue) Then

If CheckValue.ActiveBuyerExists(tableName, value) Then
Return True
Else
e.Description = GetDescription(target, propertyName, propertyDescription) & " does not exist or is not active."
Return False
End If

Else
Return True
End If
End Function


Public Class ActiveRecordExistsRuleArgs
Inherits MyRuleArgs

Private mTableName As String
Private mLineNoFieldName As String

Public ReadOnly Property TableName() As String
Get
Return mTableName
End Get
End Property

Public ReadOnly Property LineNoFieldName() As String
Get
Return mLineNoFieldName
End Get
End Property

Public Sub New(ByVal propertyName As String, ByVal tableName As String, Optional ByVal lineNoFieldName As String = "lnno", Optional ByVal propertyDescription As String = "")
MyBase.New(propertyName, propertyDescription)
mTableName = tableName
mLineNoFieldName = lineNoFieldName
End Sub

Public Overrides Function ToString() As String
Return MyBase.ToString & "?tableName=" & mTableName & "&lineNoFieldName=" & mLineNoFieldName.ToString
End Function

End Class

Copyright (c) Marimer LLC