Reputation: 13
I have a database which stores user inputs in an abstract stringified form. These user inputs have a varchar column which describes its type (string, decimal, bool, dropdown etc).
Now this get's send to the front end to display some input elements in the browser. This works great!
However since the input is so generic the value is also a varchar. The problem I am facing is that I need to do some validation on the value. (e.g. some string input have a maxLength or regex specified, a decimal can have a min and max value).
so once I get back the value the user entered it is in string format and I want to parse it to the correct native type so I can start validating it.
I would like a function which returns the parsed value in it's correct type.
so I would have a function which is something like this:
public {something here} ParseValue(InputObject object, string type) {
// parse here based on type
// InputObject has a few properties like value, min, max, regex etc
// all as a string.
// for instance if type is datetime I want to return a new object
// which has parsed the value, min and max as datetime.
// it should also be possible for the type to be decimal and min, max
// and value should be decimal in the outputObject
}
I am coming from a dynamically typed background so I have no idea how to do something like this. or even if it is possible.
any help is appreciated!
Upvotes: 0
Views: 73
Reputation: 373
You'd be best off if you don't directly try to evaluate the type by the Database-Datatype and instead store the "real" type in a seperate DB-Column. Except if you build an association between C#-Types and Database-Types because you can do something like this then:
String val = "123";
String type = "System.Int32";
Type tempType = Type.GetType(type);
if (tempType == null)
return null;
dynamic result = Convert.ChangeType(val, tempType);
Of course this would be applicable to the boundary values also. Note that Convert.ChangeType only works for very popular Types and is not universally useable and that it throws an Exception if theres something failing which need to be catched also.
Upvotes: 1
Reputation: 2855
What you could do is create an interface IValidatable
that defines a method like Validate()
. Then you could use that as a return type. Then you just parse your value using a switch (probably delegate this to some method or class) to an implementation of IValidatable
. E.g.
public interface IValidatable {
bool Validate();
}
public class ValidateableInteger : IValidatable {
private int _value;
public ValidateableInteger(int i) {
_value = i;
}
bool Validate() {
//code where you validate your integer.
}
}
Note that this is not very flexible as you only have 1 method called validate, though clearly you can define multiple more generic methods that could implement different validations.
Moreover you can create more specific interfaces for e.g. numeric types (e.g. IValidateableNumeric
and ValidateableInt : IValidateableNumeric
)
Note that you're basically typing your input here though, which is kindof weird and unnecessary given the fact that you can just work with typed data to begin with.
In the end I would discourage people from bypassing type system this way. In this case especially there are plenty better ways of creating form elements while using typed data (checkout the Razor template engine).
Upvotes: 0