Reputation: 38
I have to create an API where I need to provide a proper message to the user if he is not supplying the mandatory parameters in the GET request, I also need to make sure that the user has supplied the proper values in the parameters, the values can be integers, strings, dates OR the enums.
So I created a class SearchParameters which lists the information on the parameters for the request.
private static class SearchParameters
{
public static List<ParamInfo> ParamList = new List<ParamInfo>
{
new ParamInfo {Name ="location", IsMandatory = true , ExpecteDataType = typeof(ulong) } ,
new ParamInfo {Name ="service", IsMandatory = true , ExpecteDataType = typeof(ServiceType)} ,
new ParamInfo {Name ="start", IsMandatory = true , ExpecteDataType = typeof(DateTimeOffset)} ,
new ParamInfo {Name ="appointmentType", IsMandatory = true , ExpecteDataType = typeof(AppointmentType)} ,
new ParamInfo {Name ="status", IsOptional = true , ExpecteDataType = typeof(string)} ,
new ParamInfo {Name ="end", IsOptional = true , ExpecteDataType = typeof(DateTimeOffset)} ,
new ParamInfo {Name ="clinicianGender", IsOptional = true , ExpecteDataType = typeof(AdministrativeGender)} ,
new ParamInfo {Name ="_sort", IsForSorting = true , ExpecteDataType = typeof(string)},
new ParamInfo {Name ="_count", IsForPaging = true , ExpecteDataType = typeof(uint)}
};
}
where ParamInfo
are the instances of class
public class ParamInfo
{
public string Name { get; set; }
public bool IsMandatory { get; set; }
public bool IsRequired { get; set; }
public bool IsOptional { get; set; }
public bool IsForSorting { get; set; }
public bool IsForPaging { get; set; }
public Type ExpecteDataType { get; set; }
}
When user requests I have the parameters available in the list of Tuple where both Item1
& Item2
are strings, Item1
is the name of query parameter & Item2
is the value supplied by the user.
How can I make sure that the value of parameter(i.e Item2
) is of a proper datatype?
I tried something like this:
// Data tye verification
foreach (ParamInfo info in SlotSearchParameters.ParamList)
{
Tuple<string, string> param = searchparams.Parameters.Where(x => x.Item1.ToLower() == info.Name).FirstOrDefault();
if (param != null)
{
Type expectedType = info.ExpecteDataType;
// how can we check if the value of type of x.Item1 is as expected
// Can't procede
}
}
But since x.Item1
is always a string representation of the value supplied which can be Date, Int or string etc, I don't know what to do?
Upvotes: 1
Views: 95
Reputation: 35595
How can I make sure that the value of parameter(i.e Item2) is of a proper datatype?
Anyways, here are some ideas that will hopefully help you:
internal class Program
{
private static void Main(string[] args)
{
List<Tuple<string, string>> userInputValues = new List<Tuple<string, string>>(); // obviously implement the correct user values here
// This is the money below.
// you'll have only valid ParamInfo objects here:
List<ParamInfo> paramFactory = new ParamInfoFactory(userInputValues).ValidParameters;
}
public class ParamInfo
{
public string Name { get; set; }
public bool IsMandatory { get; set; }
public bool IsRequired { get; set; }
public bool IsOptional { get; set; }
public bool IsForSorting { get; set; }
public bool IsForPaging { get; set; }
public Type ExpecteDataType { get; set; } // <--- you really don't need this.
// where are you storing the item1.value?
// are you storing it as a string, or as the proper type that it represents?
}
public class ParamInfoFactory
{
public List<ParamInfo> ValidParameters { get; set; }
public ParamInfoFactory(List<Tuple<string, string>> userSuppliedValues)
{
ValidParameters = new List<ParamInfo>();
foreach (Tuple<string, string> userValue in userSuppliedValues)
{
if (UserInputValuesAreValid(userValue))
{
// all the values are valid. you can now create and add the parameters to your list.
// remember to instantiate it as you wish with the right values etc in there.
ValidParameters.Add(new ParamInfo());
}
}
}
private bool UserInputValuesAreValid(Tuple<string, string> userValue)
{
return IsNameValid(userValue.Item1) && IsDataValid(userValue.Item2);
}
private bool IsDataValid(string data)
{
return IsValidDate(data) || IsValidNumber(data); // you can also implement the IsValidEnum or any other method you want
}
private static bool IsValidDate(string data)
{
DateTime dateValue;
bool isDate = DateTime.TryParse(data, out dateValue);
return isDate;
}
//private static bool IsEnum(string data)
//{
// Colors colorValue;
// bool isEnum = Enum.TryParse(data, out colorValue);
// return isEnum;
//}
private static bool IsValidNumber(string data)
{
int number;
bool isNumber = Int32.TryParse(data, out number);
return isNumber;
}
private bool IsNameValid(string userInputName)
{
return SearchParameters.ParamList.Any(paramInfo => paramInfo.Name == userInputName.ToLower());
}
private static class SearchParameters
{
public static List<ParamInfo> ParamList = new List<ParamInfo>
{
new ParamInfo {Name ="location", IsMandatory = true , ExpecteDataType = typeof(ulong) } ,
new ParamInfo {Name ="service", IsMandatory = true , ExpecteDataType = typeof(ServiceType)} ,
new ParamInfo {Name ="start", IsMandatory = true , ExpecteDataType = typeof(DateTimeOffset)} ,
new ParamInfo {Name ="appointmentType", IsMandatory = true , ExpecteDataType = typeof(AppointmentType)} ,
new ParamInfo {Name ="status", IsOptional = true , ExpecteDataType = typeof(string)} ,
new ParamInfo {Name ="end", IsOptional = true , ExpecteDataType = typeof(DateTimeOffset)} ,
new ParamInfo {Name ="clinicianGender", IsOptional = true , ExpecteDataType = typeof(AdministrativeGender)} ,
new ParamInfo {Name ="_sort", IsForSorting = true , ExpecteDataType = typeof(string)},
new ParamInfo {Name ="_count", IsForPaging = true , ExpecteDataType = typeof(uint)}
};
}
}
}
Upvotes: 0
Reputation: 32750
You can add a validator to your ParamInfo
class:
public class ParamInfo
{
public string Name { get; set; }
public bool IsMandatory { get; set; }
public bool IsRequired { get; set; }
public bool IsOptional { get; set; }
public bool IsForSorting { get; set; }
public bool IsForPaging { get; set; }
public Type ExpecteDataType { get; set; }
public Predicate<string> Validator { get; set; }
}
And now:
public static List<ParamInfo> ParamList = new List<ParamInfo>
{
new ParamInfo { Name ="location",
IsMandatory = true,
ExpecteDataType = typeof(ulong),
Validator = s => s != null && ulong.TryParse(s, out var _); }
And you can use it like this:
foreach (ParamInfo info in SlotSearchParameters.ParamList)
{
Tuple<string, string> param = searchparams.Parameters.Where(x => x.Item1.ToLower() == info.Name).FirstOrDefault();
if (param != null &&
Validator(x.Item1) //
{
//whatever
}
}
}
Upvotes: 2
Reputation: 7918
For the purpose stated in your question, you should use either Parse()
(re: https://msdn.microsoft.com/en-us/library/system.int32.parse(v=vs.110).aspx) or TryParse()
(re: https://msdn.microsoft.com/en-us/library/zf50za27(v=vs.110).aspx) methods, e.g. int32.Parse ([your_string]);
Hope this will help.
Upvotes: 1