Fhir validate structure definition does not seem to work - c#

I have some custom code which creates a structure definition based on some user inputs. The way it works is to set up a differential by getting structure definition requirements from user, generates the snapshot and finally I persist it into local storage on Fhir Server.
I tried the following code snippet to validate the StructureDefinition before persisting it to database, but the validationResult is always null no matter what the structureDefinition I will pass to it.
Could anyone let me know of the correct way to validate a customized StructureDefinition?
var structureDefinition = ...
ICollection<ValidationResult> validationResult = null;
DotNetAttributeValidation.TryValidate(structureDefinition, validationResult);

There's a third (optional) parameter to TryValidate that is called 'recurse', you should try setting that to "true", otherwise the validate will only do the direct elements of the structuredefinition, not the data inside the types etc.

Related

Storing viewmodel data in Session creates problems with validation using FluentValidation

I'm currently working on a large project involving Sitecore CMS (7.2). For viewmodel validation we are using FluentValidations. Because of the combination of Sitecore and FluentValidations I seem to be running in some kind of technical deadlock. I sort-of found a solution myself, but I'm not sure whether this is the right approach or not. Here's the problem:
Situation
There is a Sitecore component which contains a HTML form. Via the modelbinder each value of this form is binded to it's corresponding field in the (complex) viewmodel. This is standard .NET MVC approach.
However, some values in the viewmodel are NOT part of the form. For instance, a date at which the mutation will be applied is calculated by the application. The user can only see this date-value as plain text, and thus can not edit it. It's still part of the viewmodel though. To make sure this value is being posted back to the model in code, one would normally use a hidden field. But if I use a hidden field, it means that users are able to spoof that date and because some validations depend on this value, they are able to spoof the entire validity of the form.
Moreover, in the same viewmodel I have a list of complex objects that I can't simply put in a hidden field (or I should serialize it to JSON, which I don't want).
The conclusion is that I need to store this data somewhere else. Somewhere the user can't spoof it, but I'm still able to validate user input with FluentValidations. I therefore decided to put the entire viewmodel in the users Session, and delete it directly after a succesful mutation.
Problem
By using session data I run into problems. Let's first see these steps:
(GET) Viewmodel is created. Calculated date is set and list of complex types is retrieved once from a (slow) webservice.
Entire viewmodel is stored as session data.
Form is shown to the user, who fills the form. Some data is only shown as readonly, like the date and list of complex types.
User submits form, FluentValidations kicks in to validate the data (POST).
That's where I run into problems. The validation done by FluentValidations kicks in before it reaches the POST controller method. That's exactly the way we want it, because that means validation errors are automatically added to the ModelState. However, because of security reasons I don't want to add this data as hidden fields to the cshtml file, which means they are empty at the time FluentValidations is going to validate the form.
This is creating problems because some of the form validations rely on the missing data. What I basically want is to merge the viewmodel that is stored in the session with the viewmodel that was posted to the controller method. But I have to do that before FluentValidations is going to do it's work.
My current solution
Gladly, I learned about FluentValidation's IValidatorInterceptor: an interface that can be used to 'do stuff' before or after the validations process kicks in. I used the BeforeMvcValidation method to do my merging process. The code is as follows:
public ValidationContext BeforeMvcValidation(ControllerContext controllerContext, ValidationContext validationContext)
{
if (controllerContext.HttpContext.Session == null)
return validationContext;
var sessionData = controllerContext.HttpContext.Session["some_identifier"];
if (sessionData == null)
return validationContext;
var mergedObjectToValidate = Utils.MergeViewModelData(sessionData, validationContext.InstanceToValidate);
// Unfortunately, we have to do this..
var privateSetterProperty = validationContext.GetType().GetProperty(ValidationContextInstancePropertyName);
if (privateSetterProperty == null)
return validationContext;
privateSetterProperty.SetValue(validationContext, mergedObjectToValidate);
return validationContext;
}
Basically this interceptor method allows me to do my merging-process before validation. So I thought I had the solution here, but as you can see I am using reflection to set a property. That is because the property InstanceToValidate in the ValidationContext object has a private setter. I simply can not set it without using reflection. Which is, obviously, a bit dirty.
It does work exactly as I want though! :) I do not need any hidden fields that can be spoofed (which is horrible for straight-trough-processing) and I can still use FluentValidations exactly as I always did before. Also, the MVC modelbinding-process is left untouched, which I prefer.
The actual question
So the above solution works exactly as you want so what are your questions?! Well, simple:
I'm using reflection to set a private property in a 3rd party library (FluentValidations). The obvious answer is: don't go that way. But in this case it works flawlessly. If the InstanceToValidate-property had a public setter, I wouldn't even be posting this question at all: I would feel like I nailed it. But unfortunately it is private, so are there any real reasons why I shouldn't do this, maybe someone being an expert in FluentValidations behaviour?
Let's say there is a genuine reason why I shouldn't go this way; is there another approach which has the same effect? Can I hook in even earlier, so before FluentValidations kicks in, perhaps some kind of 'hook' just after the MVC model-binding process but before validation kicks in?
Is this entire approach simply wrong and should I tackle it in a completely different way?
Thanks!

Contacting database from within data validation attribute

I have a clientside typeahead that pulls back a json list and presents options to the user for a specific list of places that they can enter for an input field.
On the server I want to make sure that the submitted form data matches one of these places. Realistically it should unless someone was being malicious and posting data from fiddler or something like that.
I supply the data to the typeahead from a list stored in Redis. I've read that it's bad practice to contact a database from within an attribute but I would like to check for the existence of the place in the redis list before allowing the logic flow to continue.
I could cache the list statically on startup in each webserver instance however this now means that if the list changes at all then all the servers would have to be restarted to get the changes.
Perhaps instead of using Validation Attributes I should be using a fluent validator?
http://fluentvalidation.codeplex.com/wikipage?title=ValidatorFactory&referringTitle=Documentation
I've read that it's bad practice to contact a database from within an
attribute [...]
Your attribute does not need to know about any database or anything of that matter. What your attribute needs to do is to call a Service to do the job. The implementation of the Service will be hidden from your Attribute's point of view.
interface IValidationService
{
bool DoesPlaceExist(Place place);
}
class RedisValidationService : IValidationService
{
bool DoesPlaceExist(Place place)
{
// crazy redis magic ...
}
}
class PlaceValidationAttribute : ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var validationService = new RedisValidationService(); // ideally use IoC
var isValid = validationService.DoesPlaceExists(new Place(value));
// ... this is over simplified to just show the idea
// return blah blah
}

Selectively Serialize and Deserialize

I have a User object in my Linq-To-Sql mapping. There is a password attribute on it that I want to deserialize when submitted by a user--for example, during login. I never want to pass this attribute back to the user, though, since it will contain the encrypted version of the actual password and I'd rather not expose any information about the password or the encryption method. Is there a way to object-wide tell Linq-To-Sql to never pass the Password attribute when returning a User object?
I use https for encryption, mostly because just in accessing the service, you by default enforce your encryption, which saves on client side code. You have a few possible answers though:
Blank out the password when you return the User Object from the WCF side. (You can change the value of the password of the object, and just not save the change.. then return the object to the client )
Use a custom object for your login response that returns only the necessary information for your client.
Implement a Data Transfer Object pattern, with a nuget package like AutoMapper.
If you aren't salting and hashing your passwords, please please please consider it.
In the case where I never want to serialize an object, it is best to hook into the OnSerializing event. Since I'm using Linq-To-Sql, the OnSerializing event has already been captured by my DataContext's designer.cs for tracking serialization state for lazing loading entity references. Adding another function decorated with [OnSerializing] throws an error in System.ServiceModel.Activation, so I had to find another route. Here's my solution:
Modify DataContext.designer.cs
In DataContext.designer.cs, I added
[global::System.Runtime.Serialization.OnSerializingAttribute()]
[global::System.ComponentModel.EditorBrowsableAttribute(EditorBrowsableState.Never)]
public void OnSerializing(StreamingContext context)
{
this.serializing = true;
// custom function to handle my logic
this.ClearPassword();
}
Add Method to my custom Class Definition
In my User.cs file, I have a partial class definition. Therefore, all I need to do is add the ClearPassword method to my partial class definition:
partial class User
{
private void ClearPassword()
{
this.Password = null;
}
//* OTHER CODE *//
}
Now, no matter how I'm interacting with User objects, passwords are never passed to the client, as desired.

How to differentiate between user specified null and default value in WCF data contract

I need to define a WCF API to enable user to update large object. While I can define few smaller methods and let the user update specific parts of the large object at a time. But for some reason I am not able to do that. The other way I tried is defined the data contract as collection of key-value (key is an enum and value is some string) and let the user add whatever he wants to update. This api very compact but it's not very intuitive and can be confusing for the user. Also since the value is of string type, so it's not very type safe.
So I now I have create one api, where the user can update the entire object.
for example:
public UpdateResult UpdateAPI(UpdateParam param){}
Now the UpdateParam class will several nullable fields.
Q: If there is a null value in one of the fields, how can differentiate at the server side,
the null value was specified by the user or it's default non-specified one? Is there something in the incoming soap message that can help differentiate?
Any help would be greatly appreciated.
Similar questions asked are
1. Data member default values, how to figure out whether something was really sent?
2.
no, as far as i know there is no way to tell the conditions apart if you only have a nullable field ...
however, you could provide an additional bool per property that could serve as a flag to indicate if the value was set by the user or is still on its default value
You can implement the setters of your properties to automatically set the corresponding bool when your properties are set

Where is the most convenient place to validate a property length of a saveable object?

I wonder where is the most convenient place to validate a property length on a persistent object.
Let's say, there is a table called Country in my Db with CountryCode nvarvhar(3).
And I have a mapped object Country wiht property CountryCode which can be saved into Db.
Where should I check if the Country code set by user does not exceed 3 characters:
In the setter of property CountryCode
OR at the time of saving into Db
Can you please advice?
Thanks
I've found that it is easiest to allow properties to be set to any value (of the correct data type anyway) and then validate it before saving it.
I like to use the validation attributes built into .Net. This keeps the logic associated with the property. There is a StringLengthAttribute class that should do the trick for what you are asking for.
The attributes are in the System.ComponentModel.DataAnnotations namespace (you'll need to reference the assembly of the same name).
MVC and EntityFramework have a built in way to validate the data. If you need to perform the logic yourself, here is some code that might help you get started...
var ctx = new ValidationContext(obj, null, null);
Validator.ValidateObject(obj, ctx);
According to code secure recomendations, all checks should be performed as early as possible. Additionally, it's recommended that each party performs the checks by itself without relying on other parties verifications.

Categories