X++ doesn't skip AOS validation when it should - validation

I've created a custom batchable class that is normally ran by a menu item calling SysOperationServiceController with the custom class name as the parameter. The custom class is marked as RunOn Server. In the code that I'm executing, I'm trying to delete a LogisticsLocation record, however, it's failing with error: "Cannot delete a record in Addresses (LogisticsPostalAddress).
The corresponding AOS validation failed." After stepping thru the logic of LogisticsPostalAddress.aosValidateDelete() code, I've found no good reason why this should fail, but this is not the reason for my question.
My goal is to attempt to bypass this AOS validation by logisticsLocation.skipAOSValidation(true). After working around the permission violation errors that I was getting, I found that I had to assert a SkipAOSValidationPermission first before skipping AOS validation. However, even though I do this, the aosValidateDelete() logic is still being hit. I'm also trying to avoid doing logisiticsLocation.doDelete() because I do want it to before the standard DeleteAction logic and cascade down to also delete the corresponding records.
Ultimately, my goal is to delete this record without error. And I cannot see any reason why it should fail, there is a DeleteAction with a Restricted option on LogisticsPostalAddress, however, it's for a table that doesn't have a relating record for. The logic inside LogisticsPostalAddress.aosValidateDelete() doesn't make sense altogether, which is why I'm looking to bypass. So my real question remains, why does it still attempt to AOS validate when I specifically tell it not to and I've jumped thru all the security hoops to do so? And how do I really skip this validation?
My Code:
while select dirPartyPostalAddressView
where dirPartyPostalAddressView.Party == dirPartyRecId //some local variable established earlier
join forUpdate logisticsLocation
where logisticsLocation.RecId == dirPartyPostalAddressView.Location
{
if (isRunningOnServer())
{
CodeAccessPermission::revertAssert();
skipValidPermission = new SkipAOSValidationPermission();
skipValidPermission.assert();
logisticsLocation.skipAosValidation(true);
}
logisticsLocation.delete();
}

Related

Change record owner in Dynamics CRM plugin

I am writing a Post PLugin changing the owner. When the owner has a substitution manager, the owner is changed to the substitution manager. I tried a service.Update and an AssignRequest, but these throw an exception.
When I post the request my entity cannot update (and then throws "The request channel time out while waiting for reply after 10:00:00"). But like I see there is no recursion, because when I logged it I have only one repetition of log and it has stopped before or on line with update.
var assignedIncident = new AssignRequest
{
Assignee = substManagerRef, //get it throw another method, alreay checked in test it`s correct
Target = new EntityReference ("incident", incedentId)
};
service.Execute(assignedIncident);
I tried to write target in another way
Target = postEntityImage.ToEntityReference()
I tried to write simple update but the problem is the same.
Entity incident = new Entity("incident" , incidentId);
incident["ownerid"] = substManagerRef:
service.Update(incident);
Can somebody help me with that? Or maybe show the way to solve it)
The plugin is triggering itself and gets in a loop. The system only allows a maximum of 8 calls deep within plugins and that is the reason it throws an error and rolls back the transaction.
To solve this issue redesign your plugin in the following way:
Register your plugin on the Update message of your entity in the PreValidation stage.
In the plugin pick up the Target property from the InputParameters collection.
This is an Entity type. Modify or set the ownerid attribute on this Entity object.
That is all. You do not need to do an update, your modification is now passed into the plugin pipeline.
Note: for EntityReference attributes this technique only works when your plugin is registered in the PreValidation stage. For other regular attributes it also works in the PreOperation stage.

Net::LDAP add() failed with no error message. How can I find the reason why the record did not validate?

I beat myself up for two days as I built a Ruby on Rails application that manages users in LDAP. While fine-tuning the inclusion and formatting of various attributes, I would frequently have ldap.add() fail with little feedback other than possibly an exception raised. I usually knew it was a data validation error, such as a missing required attribute or poorly formatted attribute values -- but I could not find anything on the server (Apache DS) or client end that would indicate which field failed, or why it was failing.
So...how do you see the reason why an LDAP add (or replace, delete, open...) failed?
Then I stumbled across ldap.get_operation_result, I had a real facepalm moment. I've intentionally recreated several of the issues I painfully solved through careful inspection with get_operation_result in my arsenal, and each time it described exactly what the problem was.
This function is useful in the case of rescuing an exception, or if add(), modify(), delete(), etc. simply returns false.
ldap.add(dn: dn, attributes: attributes)
Rails.logger.info("ldap.add: #{ldap.get_operation_result}")
The snippet above saved my sanity, not to mention hours of tedious hunt-and-peck testing.
For example, here is just one part of an error message it revealed that I did not provide the required sn attribute:
ERR_279 Required attributes [sn(2.5.4.4)] not found within entry uid=david,o=users,dc=example,dc=com"
It will also show messages related to bad server connection credentials, etc.
HTH

should a validation function access the repository directly?

I have the following in my application:
Action Orm entity (From telerik open access)
Repository(Of Action)
AppService(Holds an instance of the repository)
when I need to save an instance, I send the instance to the AppService. the AppService then calls a validator to validate the instance to save. the validator is based on http://codeinsanity.com/archive/2008/12/02/a-framework-for-validation-and-business-rules.aspx
(full code on https://github.com/riteshrao/ncommon)
so basically my save function in the AppService looks like this
Public Sub AddAction(ByVal Item As Data.Model.Action)
Contract.Requires(Of ArgumentNullException)(Item IsNot Nothing, "Item is nothing.")
Dim validateResult As Rules.ValidationResult = _ActionValidator.Validate(Item)
If Not validateResult.IsValid Then
Throw New Validation.ValidationException(validateResult)
End If
Try
_ActionRepository.Add(Item)
_unitOfWork.SaveChanges()
Catch ex As Exception
_unitOfWork.ClearChanges()
Throw New DataServiceException(ex.Message, ex)
End Try
End Sub
for checking properties of the Action item the sample code works great. my question begins when i need to make sure that the same action is not added twice to the DB for the same customer (ie. id is difference, name is the same and customer is the same)
as I see it I have a few options:
option 1: check for a duplicate action using something like
function(validatedItem) item.Customer.Actions.Any(function(item) item.id<>validatedItem.id andalso item.name=validatedItem.name))
basically I go from the action being saved back to the customer and then back to all his actions and check if any action exists with a different id and same name
the down sides are:
a. for this to work, when accessing the customer property of the item, the entire customer object is read from DB which is redundant in this case
b. the Any function is being evaluated on the client as item.Customer.Actions returns IList(Of Action)
Option 2: let the validation class have access to the action repository. then i could simply do something like
'assume I already have validatedItem
repository.Any(function(item) item.id<>validatedItem.id and item.customerid=validatedItem.customerid and item.name=validatedItem.name)
this will result in an Exists query being sent to the DB but the downside(?) is that the validation framework should not access the repository directly (as far as I have seen in the very few examples i could find that do use validation and ORM)
Option 3: let the validation class have access to the AppService and use the AppService to check for existence of a duplicate.
problems:
a. I create a circular reference (AppService->Validation Class->AppService)
b. I need to create a lot of useless functions in the AppService for loading items based on criteria that is only relevant for the validation
Any ideas what is the best course here?
The simplest is not to check duplicates in the database from your domain.
When a collection of entities is part of you aggregate then it is a non-issue since you would not permit the duplicate to be added to the collection. Since the aggregate is stored as a whole you would never run into the problem.
For scenarios where you do not want a duplicate, say, e-mail address and no collection of the entities is represented by an aggregate (such as the Users in a system) you can just let the database enforce the uniqueness. Simply pick up the exception and report back. In many instances your validation would not be able to enforce the uniqueness simply because it doesn't have/implement the required locks that a database system would have.
So I'd simply leave that up to the database.

Entity framework Conflicting changes detected. This may happen when trying to insert multiple entities with the same key

I have entity User with a couple of one-to-one and many-to-many relations and Identity primary key, and generic repository which created on each request.
I have an registration form with client and server validation and i decided to turn off client validation to test how server would behave in such case.
I turned off client validation to test the registration form and put some invalid values so i get back form saying that i have some errors, after i fixed that i got very interesting error
saying:
_context.SaveChanges(); //towing the error below:
Conflicting changes detected. This may happen when trying to insert multiple entities with the same key
It was strange for me because i detached the entity User but when i found this How to clean-up an Entity Framework object context?
so instead detaching only User entity i decided to try to clean object context completely running that code:
var objectStateEntries = this.objectContext
.ObjectStateManager
.GetObjectStateEntries(EntityState.Added);
foreach (var objectStateEntry in objectStateEntries)
{
if(objectStateEntry.Entity != null)
this.objectContext.Detach(objectStateEntry.Entity);
}
So after that all working well and i didn't get Conflicting changes detected error any more, but i am still wondering why such situation was taking place, may be some one may explain?
You may find your answer here:
context.ObjectStateManager.GetObjectStateEntries(System.Data.Entity.EntityState.Added| System.Data.Entity.EntityState.Unchanged);

Avoiding duplicate code in input validation

Suppose you have a subsystem that does some kind of work. It could be anything. Obviously, at the entry point(s) to this subsystem there will be certain restrictions on the input. Suppose this subsystem is primarily called by a GUI. The subsystem needs to check all the input it recieves to make sure it's valid. We wouldn't want to FireTheMissles() if there was invalid input. The UI is also interested in the validation though, because it needs to report what went wrong. Maybe the user forgot to specify a target or targetted the missles at the launchpad itself. Of course, you can just return a null value or throw an exception, but that doesn't tell the user SPECIFICALLY what went wrong (unless, of course, you write a separate exception class for each error, which I'm fine with if that's the best practice).
Of course, even with exceptions, you have a problem. The user might want to know if input is valid BEFORE clicking the "Fire Missles!" button. You could write a separate validation function (of course IsValid() doesn't really help much because it doesn't tell you what went wrong), but then you'll be calling it from the button click handler and again from the FireTheMissles() function (I really don't know how this changed from a vague subsystem to a missle-firing program). Certainly, this isn't the end of the world, but it seems silly to call the same validation function twice in a row without anything having changed, especially if this validation function requires, say, computing the hash of a 1gb file.
If the preconditions of the function are clear, the GUI can do its own input validation, but then we're just duplicating the input validation logic, and a change in one might not be reflected in the other. Sure, we may add a check to the GUI to make sure the missle target is not within an allied nation, but then if we forget to copy it to the FireTheMissles() routine, we'll accidentally blow up our allies when we switch to a console interface.
So, in short, how do you achieve the following:
Input validation that tells you not just that something went wrong, but what specifically went wrong.
The ability to run this input validation without calling the function which relies on it.
No double validation.
No duplicate code.
Also, and I just thought of this, but error messages should not be written in the FireTheMissles() method. The GUI is responsible for picking appropriate error messages, not the code the GUI is calling.
"The subsystem needs to check all the input it receives to make sure it's valid"
Think of the inputs not so much as a list of arguments, but as a message, it gets easier after that.
The message class has an IsValid member function, it remembers if IsValid was called and what the result was. It also remembers its state, if the state changes then it needs to be re validated. This message class also keeps a list of validation errors.
Now, the UI builds a TargetMissiles message, and the UI can validate it, or pass it directly to the MissileFiring subsystem, it checks to see if the message was validated, if not it validates it, and proceeds / fails depending.
The UI gets the message back, with the list of validations already populated.
The messages with their validation sit in a separate library. No code is duplicated.
This sound OK?
This is what Model-View-Controller is all about.
You build up a model (a launch which is composed of coordinates, missile types and number of missiles) and the model has a validate method which returns a list of errors/warnings. When you update the model (on key-up, <ENTER>, button-press) you call the validate method and show the user any warnings, errors, etc. (Eclipse has a little area just under the tools bar in a dialog that does this, you might want to look at that.)
When the model is valid, you activate the launch missiles button so that the user knows that they can launch the missiles. If you have an update event that is called particularly frequently or a part of the validation that is particularly costly, you can have a validate_light method on the model that you use for validating only the parts that are easy to do.
When you switch to a console based UI you build up the model from the command line arguments, call the same validate method (and report errors to stderr) and then launch the missiles.
Double the validation. In many case the validation is trebled (FKs and not null fields in the DB for example). Depending on your platform it may be possible to code the validation rules once. For example your front end and backend code could share C# business classes. Alternatively you could store the validation rule as metadata that both the backend and front end can access an apply.
In reality the fact that you need different responses to a validation problem (for example the Fire Missile button shouldn't even be enabled until the other inputs are valid) there will be different code associated with the same rule.
I'd suggest an input validation class, which takes the input type (an enumeration) in its' constructor, and provides a public IsValid method.
The IsValid method should return a boolean TRUE for valid and FALSE for invalid. It should also have an OUT parameter that takes a string and assigns a status message to that string. The caller will be free to ignore that message if it wants to, or report it up to the GUI if that's appropriate for the context.
So, in pseudocode (forgive the Delphi-like syntax, but it should be readable to anybody):
//different types of data we might want to validate
TValidationType = (vtMissileLaunchCodes, vtFirstName,
vtLastName, vtSSN);
TInputValidator = class
public
//call the constructor with the validation type
constructor Create(ValidationType: TValidationType);
//this should probably be ABSTRACT, implemented by descendants
//if you took that approach, then you'd have 1 descendant class
//for each validation type, instead of an enumeration
function IsValid(InputData: string; var msg: string): boolean;
And then to use it, you'd do something like this:
procedure ValidateForm;
var
validator: TInputValidator;
begin
validator := TInputValidator.Create(vtSSN);
if validator.IsValid(edtSSN.Text,labelErrorMsg.Text) then
SaveData; //it's valid, so save it!
//if it wasn't valid, then the error msg is in the GUI in "labelErrorMsg".
end;
Each piece of data has its own meta data (type, format, unit, mask, range etc.). Unfortunately this is not always specified.
The GUI controlls need to check the input with the metadata and give warnings/errors if the data is invalid.
Example: a number has a range. The range is provided by the metadata, but the range check is provided by the control.

Resources