JdbcTemplate is returning empty result - spring

could you help me previously its giving the perfect result but now its not give me
private String SQL_SERVICE_CONFIGS1 = "SELECT cc.client, ac.association_code, as1.service_name, as1.service_type, as1.service_implementation, as1.endpoint_url FROM association_config ac, association_services as1,client_configs cc WHERE as1.association_id=ac.id AND cc.id=ac.client_config_id AND ac.association_code= ?";
public List<AssociationConfiguration> getAssociationConfigurations(String clientId, String associationId) {
String sql = SQL_SERVICE_CONFIGS1;
Object[] args = new Object[] {};
if (associationId != null && associationId.trim().length() > 0) {
args = new Object[] { associationId.trim() };
}
return (List<AssociationConfiguration>) jdbcTemplate.query(sql, args,
new AssociationConfigurationRowMapper());
}
}

Related

hive UDF - convert StringObjectInspector to String

I am writing generic UDF. If I use UDF directly it works, however if I use UDF with other function (distinct, max, min) it's not even calling evaluate function.
I want to see what's happening and so trying to log the values. However need to understand how to convert StringObjectInspector to String.
Code
#Description(name = "Decrypt", value = "Decrypt the Given Column", extended = "SELECT Decrypt('Hello World!');")
public class Decrypt extends GenericUDF {
Logger logger = Logger.getLogger(getClass().getName());
PrimitiveObjectInspector col;
StringObjectInspector databaseName;
StringObjectInspector schemaName;
StringObjectInspector tableName;
StringObjectInspector colName;
#Override
public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException {
System.out.println("****************************** initialize called ******************************");
logger.info("****************************** initialize called ******************************");
if (arguments.length != 5) {
throw new UDFArgumentLengthException("Decrypt only takes 4 arguments: T, String, String, String");
}
ObjectInspector colObject = arguments[0];
ObjectInspector databaseNameObject = arguments[1];
ObjectInspector schemaNameObject = arguments[2];
ObjectInspector tableNameObject = arguments[3];
ObjectInspector colNameNameObject = arguments[4];
if ( !(databaseNameObject instanceof StringObjectInspector) ||
!(schemaNameObject instanceof StringObjectInspector) ||
!(tableNameObject instanceof StringObjectInspector) ||
!(colNameNameObject instanceof StringObjectInspector)
) {
throw new UDFArgumentException("Error: databaseName, schemeName, tableName and ColName should be String");
}
this.col = (PrimitiveObjectInspector) colObject;
this.databaseName = (StringObjectInspector) databaseNameObject;
this.tableName = (StringObjectInspector) tableNameObject;
this.schemaName = (StringObjectInspector) schemaNameObject;
this.colName = (StringObjectInspector) colNameNameObject;
logger.info("****************************** initialize end ******************************");
logger.info(col.toString());
logger.info(col);
logger.info(databaseNameObject.toString());
logger.info(databaseNameObject);
logger.info(colName.toString());
logger.info(colName);
logger.info(colNameNameObject);
logger.info(colNameNameObject.toString());
return PrimitiveObjectInspectorFactory.javaStringObjectInspector;
}
#Override
public Object evaluate(DeferredObject[] deferredObjects) throws HiveException {
System.out.println("******************** Decrypt ********************");
logger.info("******************** Decrypt ******************** ");
if(col.getPrimitiveJavaObject(deferredObjects[0].get()) == null){
return null;
}
String stringToDecrypt = col.getPrimitiveJavaObject(deferredObjects[0].get()).toString();
String database = databaseName.getPrimitiveJavaObject(deferredObjects[1].get());
String schema = schemaName.getPrimitiveJavaObject(deferredObjects[2].get());
String table = tableName.getPrimitiveJavaObject(deferredObjects[3].get());
String col = colName.getPrimitiveJavaObject(deferredObjects[4].get());
return new Text(AES.decrypt(stringToDecrypt, database, schema, table, col));
}
#Override
public String getDisplayString(String[] strings) {
return null;
}
}
Try getPrimitiveJavaObject method instead of toString, more details.
Another thought on your problem, check out optimization flags:
vectorization: hive.vectorized.execution, hive.vectorized.execution.enabled, hive.vectorized.execution.reduce.groupby.enabled
Cost-Based Optimization: hive.cbo.enable
predicate push down: hive.optimize.ppd
Check if those flags are enabled/disabled by typing set <option>, e.g., set hive.optimize.ppd;, in hive shell, and try to switch the value.

generated aliases error in spring JPA in criteria query API

public Predicate get_data(String field, String method, String value) throws Exception
{
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<student> cq = cb.createQuery(student.class);
Root<student> s = cq.from(student.class);
Predicate selected_field = null;
number = new BigDecimal(value);
if(method.equals("greaterThan") || method.equals("greaterThanOrEqualTo") ||
method.equals("lessThan") || method.equals("lessThanOrEqualTo"))
{
Method cbMethod = cb.getClass().getMethod(method,Expression.class,Comparable.class);
selected_field = (Predicate) cbMethod.invoke(cb,s.get(field), number);
}
else if(method.equals("eq"))
{
method = "equal";
Method cbMethod = cb.getClass().getMethod(method,Expression.class,Object.class);
selected_field = (Predicate) cbMethod.invoke(cb,s.get(field),number);
}
return selected_field;
}
public List<student> get(String search) throws Exception
{
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<student> cq = cb.createQuery(student.class);
Root<student> s = cq.from(student.class);
List<Predicate> selected_field = new ArrayList<>();
System.out.println(search);
List<String> query = Arrays.asList(search.split("And",0));
System.out.println(query.size());
List<String> fields = new ArrayList<>();
List<String> values = new ArrayList<>();
List<String> method = new ArrayList<>();
for (String str : query)
{
List<String> s1 = null;
int index_lt = str.indexOf('<');
int index_gt = str.indexOf('>');
int index_eq = str.indexOf('=');
if(index_lt != -1)
{
s1 = Arrays.asList(str.split("<",0));
method.add("lessThan");
}
else if(index_gt != -1)
{
s1 = Arrays.asList(str.split(">",0));
method.add("greaterThan");
}
else if(index_eq != -1)
{
s1 = Arrays.asList(str.split("=",0));
method.add("equal");
}
System.out.println("S1"+s1);
fields.add("student_"+s1.get(0));
values.add(s1.get(1));
}
for(int i = 0 ; i < fields.size() ; i++)
{
selected_field.add(get_data(fields.get(i),method.get(i),values.get(i)));
}
cq.where(cb.and(selected_field.toArray(new Predicate[] {})));
cq.where(predicatesarr);
System.out.println("where ends");
TypedQuery<student> search_query = em.createQuery(cq);
return search_query.getResultList();
}
when I am sending this http://localhost:8080/?search=rollNo>13 then it is giving me this error.
org.hibernate.hql.internal.ast.QuerySyntaxException: Invalid path: 'generatedAlias1.student_rollNo' [select generatedAlias0 from io.poc_task1.poc_task1.student as generatedAlias0 where generatedAlias1.student_rollNo>13]
Can anyone help me with this? Thanks in advance.

Exception in HttpControllerDispatcher

In my WebApiConfig::Register(...) I replaced the HttpControllerSelector with my own controller selector. When I fire off a POST request the SelectController member is correctly called and I return a ControllerDescriptor with the correct type of my controller.
But then HttpControllerDispatcher is raising an exception saying "The given was not present in the dictionary." Anyone has an idea how to debug such error?
The complete exception is message is:
The given key was not present in the dictionary.","ExceptionType":"System.Collections.Generic.KeyNotFoundException","StackTrace":" at System.Collections.Generic.Dictionary`2.get_Item(TKey key)\r\n
at System.Web.Http.Controllers.ApiControllerActionSelector.ActionSelectorCacheItem.FindActionMatchRequiredRouteAndQueryParameters(IEnumerable`1 candidatesFound)\r\n
at System.Web.Http.Controllers.ApiControllerActionSelector.ActionSelectorCacheItem.FindMatchingActions(HttpControllerContext controllerContext, Boolean ignoreVerbs)\r\n
at System.Web.Http.Controllers.ApiControllerActionSelector.ActionSelectorCacheItem.SelectAction(HttpControllerContext controllerContext)\r\n
at System.Web.Http.Controllers.ApiControllerActionSelector.SelectAction(HttpControllerContext controllerContext)\r\n
at System.Web.Http.ApiController.ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken)\r\n
at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()"
And here is my Controller Selector:
public class Namespace_HTTP_Controller_Selector : IHttpControllerSelector
{
private readonly HttpConfiguration _configuration;
private readonly Lazy<Dictionary<string, HttpControllerDescriptor>> _controller;
public Namespace_HTTP_Controller_Selector(HttpConfiguration Config)
{
_configuration = Config;
_controller = new Lazy<Dictionary<string, HttpControllerDescriptor>>(Initialize_Controller_Dictionary);
}
public HttpControllerDescriptor SelectController(HttpRequestMessage Request)
{
var Route_Data = Request.GetRouteData();
if(Route_Data == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
var Controller_Name = Get_Controller_Name(Route_Data);
if(Controller_Name == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
var Name_Space = Get_Version(Route_Data);
if (Name_Space == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
var Controller_Key = String.Format(CultureInfo.InvariantCulture, "{0}.{1}", Name_Space, Controller_Name);
HttpControllerDescriptor Descriptor;
if(_controller.Value.TryGetValue(Controller_Key, out Descriptor))
{
return Descriptor;
}
throw new HttpResponseException(HttpStatusCode.NotFound);
}
public IDictionary<string, HttpControllerDescriptor> GetControllerMapping()
{
return _controller.Value;
}
private Dictionary<string, HttpControllerDescriptor> Initialize_Controller_Dictionary()
{
var Dictionary = new Dictionary<string, HttpControllerDescriptor>(StringComparer.OrdinalIgnoreCase);
var Assemblies_Resolver = _configuration.Services.GetAssembliesResolver();
var Controller_Resolver = _configuration.Services.GetHttpControllerTypeResolver();
var Controller_Types = Controller_Resolver.GetControllerTypes(Assemblies_Resolver);
foreach(var ct in Controller_Types)
{
var Segments = ct.Namespace.Split(Type.Delimiter);
var Controller_Name = ct.Name.Remove(ct.Name.Length - DefaultHttpControllerSelector.ControllerSuffix.Length);
var Controller_Key = string.Format(CultureInfo.InvariantCulture, "{0}.{1}", Segments[Segments.Length - 1], Controller_Name);
if(Dictionary.Keys.Contains(Controller_Key) == false)
{
Dictionary[Controller_Key] = new HttpControllerDescriptor(_configuration, ct.Name, ct);
}
}
return Dictionary;
}
private T Get_Route_Variable<T>(IHttpRouteData Route_Data, string Name)
{
object Result;
if(Route_Data.Values.TryGetValue(Name, out Result))
{
return (T)Result;
}
return default(T);
}
private string Get_Controller_Name(IHttpRouteData Route_Data)
{
var SubRoute = Route_Data.GetSubRoutes().FirstOrDefault();
if( SubRoute == null )
{
return null;
}
var Data_Token_Value = SubRoute.Route.DataTokens.First().Value;
if(Data_Token_Value == null)
{
return null;
}
var Controller_Name = ((HttpActionDescriptor[])Data_Token_Value).First().ControllerDescriptor.ControllerName.Replace("Controller", string.Empty);
return Controller_Name;
}
private string Get_Version(IHttpRouteData Route_Data)
{
var Sub_Route_Data = Route_Data.GetSubRoutes().FirstOrDefault();
if(Sub_Route_Data== null)
{
return null;
}
return Get_Route_Variable<string>(Sub_Route_Data, "apiVersion");
}
}
This is because you are not setting subroute data in request before returning descriptor.
HttpControllerDescriptor Descriptor;
if(_controller.Value.TryGetValue(Controller_Key, out Descriptor))
{
var subRoutes = Route_Data.GetSubRoutes();
IEnumerable<IHttpRouteData> filteredSubRoutes = subRoutes.Where(attrRouteData =>
{
HttpControllerDescriptor currentDescriptor = ((HttpActionDescriptor[])Route_Data.Route.DataTokens["actions"]).First().ControllerDescriptor;
return currentDescriptor != null && currentDescriptor.ControllerName.Equals(Descriptor.ControllerName, StringComparison.OrdinalIgnoreCase);
});
Route_Data.Values["MS_SubRoutes"] = filteredSubRoutes.ToArray();
return Descriptor;
}
Take a look at:
Versioning ASP.NET Web API 2 with Media Types
public class CustomSelectorController : DefaultHttpControllerSelector
{
HttpConfiguration _config;
public CustomSelectorController(HttpConfiguration config) : base(config)
{
_config = config;
}
public override HttpControllerDescriptor SelectController(HttpRequestMessage request)
{
IHttpRouteData routeData = request.GetRouteData();
IEnumerable<IHttpRouteData> attributeSubRoutes = routeData.GetSubRoutes();
var actions = attributeSubRoutes.LastOrDefault()?.Route?.DataTokens["actions"] as HttpActionDescriptor[];
var controllerName = "";
if (actions != null && actions.Length > 0)
{
controllerName = actions[0].ControllerDescriptor.ControllerName;
}
IEnumerable<string> headerValues = null;
//Custom Header Name to be check version
if (request.Headers.TryGetValues("Accept-Version", out headerValues))
{
var apiVersion = headerValues.First().ToUpper();
if (apiVersion == "V2")
{
controllerName = controllerName + apiVersion;
}
}
HttpControllerDescriptor controllerDescriptor = null;
IEnumerable<IHttpRouteData> filteredSubRoutes = attributeSubRoutes.Where(attrRouteData =>
{
HttpControllerDescriptor currentDescriptor = GetControllerDescriptor(attrRouteData);
bool match = currentDescriptor.ControllerName.Equals(controllerName);
if (match && (controllerDescriptor == null))
{
controllerDescriptor = currentDescriptor;
}
return match;
});
routeData.Values["MS_SubRoutes"] = filteredSubRoutes.ToArray();
return controllerDescriptor;
}
private HttpControllerDescriptor GetControllerDescriptor(IHttpRouteData routeData)
{
return ((HttpActionDescriptor[])routeData.Route.DataTokens["actions"]).First().ControllerDescriptor;
}
}

binaryexpression contains method

I created a helper class which is able to build lambda expression from string parameters an I can filter a query result using this.
But I have little problem that the LINQ.Expressions.Expression does not have a Contains method.
this is my code:
string member = d.Member;
object value = d.Value;
System.Linq.Expressions.Expression expression = System.Linq.Expressions.Expression.Parameter(typeof(T), "e");
foreach (var property in member.Split('.'))
{
expression = System.Linq.Expressions.Expression.PropertyOrField(expression, property);
}
ConstantExpression c = System.Linq.Expressions.Expression.Constant(value, typeof(string));
BinaryExpression b = null;
switch (d.Operator)
{
case FilterOperator.IsEqualTo:
b = System.Linq.Expressions.Expression.Equal(expression, c);
break;
case FilterOperator.Contains:
b = GetExpression<T>(expression.ToString(), value.ToString()).Body as BinaryExpression;
break;
case FilterOperator.IsGreaterThanOrEqualTo:
b = System.Linq.Expressions.Expression.GreaterThanOrEqual(expression, c);
break;
case FilterOperator.IsLessThanOrEqualTo:
b = System.Linq.Expressions.Expression.LessThanOrEqual(expression, c);
break;
}
CriteriaCollection.Add(b);
static Expression<Func<T, bool>> GetExpression<T>(string propertyName, string propertyValue)
{
var parameterExp = Expression.Parameter(typeof(T), "type");
var propertyExp = Expression.Property(parameterExp, propertyName);
MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) });
var someValue = Expression.Constant(propertyValue, typeof(string));
var containsMethodExp = Expression.Call(propertyExp, method, someValue);
return BinaryExpression.Lambda<Func<T, bool>>(containsMethodExp, parameterExp);
}
It should be work but the how I can convert Expression to BinaryExpression?
Anybody knows this or knows an other solution which is working?
i know it's been a long time since the question was asked but, well, i've think i've found an answer, which, basically, lies on MakeBinary.
First of all, i had to create a method alike Contains, but not a self referencing extension method, like this:
public static bool Containss(string text, string text2)
{
return text.Contains(text2, StringComparison.OrdinalIgnoreCase);
}
Then you use it like this:
MethodInfo method = typeof(StackOverflowAnswer).GetMethod("Containss", new[] { typeof(string), typeof(string) });
var constainsExp = Expression.MakeBinary(ExpressionType.Equal, Expression.Constant("FULL TEXT"), Expression.Constant("TEXT"), false, method);
Something that may also help, considering your propable objective, is to receive the member, parameter and value to compose your final expression. Here's an example:
class StackOverflowAnswer
{
static void Main()
{
ParameterExpression parameter = Expression.Parameter(typeof(Student), typeof(Student).Name);
var exp1 = GetBinaryExpression(parameter, "Name", "Foo");
var exp2 = GetBinaryExpression(parameter, "Name", "Bar");
BinaryExpression[] expressions = new BinaryExpression[] { exp1, exp2 };
var bin = CombineExpressions(expressions, parameter);
var func = Expression.Lambda<Func<Student, bool>>(bin, parameter);
var exp = func.Compile();
Student student = new Student { Name = "Foo Bar" };
var x = exp(student);
Console.WriteLine(x);
}
public static BinaryExpression GetBinaryExpression(ParameterExpression parameter, string property, object comparissonValue)
{
MemberExpression member = Expression.Property(parameter, property);
ConstantExpression constant = Expression.Constant(comparissonValue, comparissonValue.GetType());
MethodInfo method = typeof(StackOverflowAnswer).GetMethod("Containss", new[] { typeof(string), typeof(string) });
var containsExp = Expression.MakeBinary(ExpressionType.Equal, member, constant, false, method);
return containsExp ;
}
public static BinaryExpression CombineExpressions(BinaryExpression[] expressions, ParameterExpression parameter)
{
bool first = true;
BinaryExpression expFull = expressions[0];
foreach (BinaryExpression item in expressions)
{
if (first)
first = false;
else
{
expFull = Expression.AndAlso(expFull, item);
}
}
return expFull;
}
internal class Student
{
public string Name { get; set; }
}
}
public class FilterExpressionHelper<T> where T : class
{
public FilterExpressionHelper()
{
CriteriaCollection = new List<BinaryExpression>();
}
public List<BinaryExpression> CriteriaCollection { get; set; }
public Expression<Func<T, bool>> NoFilterExpression { get; set; }
public void RemoveFilterCriteriaFilterDescriptor(Telerik.Windows.Data.FilterDescriptor d)
{
string member = d.Member;
object value = d.Value;
System.Linq.Expressions.Expression expression = System.Linq.Expressions.Expression.Parameter(typeof(T), "e");
foreach (var property in member.Split('.'))
{
expression = System.Linq.Expressions.Expression.PropertyOrField(expression, property);
}
ConstantExpression c = System.Linq.Expressions.Expression.Constant(value, typeof(string));
BinaryExpression b = System.Linq.Expressions.Expression.Equal(expression, c);
BinaryExpression expr = CriteriaCollection.Where(cr => cr.Right.ToString() == b.Right.ToString()).FirstOrDefault();
CriteriaCollection.Remove(expr);
}
public void AddFilterCriteriaFilterDescriptor(Telerik.Windows.Data.FilterDescriptor d)
{
string member = d.Member;
object value = d.Value;
System.Linq.Expressions.Expression expression = System.Linq.Expressions.Expression.Parameter(typeof(T), "e");
foreach (var property in member.Split('.'))
{
expression = System.Linq.Expressions.Expression.PropertyOrField(expression, property);
}
ConstantExpression c = System.Linq.Expressions.Expression.Constant(value, value.GetType());
BinaryExpression b = null;
switch (d.Operator)
{
case FilterOperator.IsEqualTo:
b = System.Linq.Expressions.Expression.Equal(expression, c);
break;
case FilterOperator.Contains:
//b = GetExpression<T>(expression.ToString(), value.ToString()).Body as BinaryExpression;
break;
case FilterOperator.IsGreaterThanOrEqualTo:
b = System.Linq.Expressions.Expression.GreaterThanOrEqual(expression, c);
break;
case FilterOperator.IsLessThanOrEqualTo:
b = System.Linq.Expressions.Expression.LessThanOrEqual(expression, c);
break;
}
CriteriaCollection.Add(b);
}
public Expression<Func<T, bool>> GetLambdaExpression()
{
ParameterExpression e = System.Linq.Expressions.Expression.Parameter(typeof(T), "e");
var orderedList = CriteriaCollection.OrderBy(cr => cr.Left.ToString()).ToList();
var disctinctValues = CriteriaCollection.Distinct(new BinaryExpressionComparer()).ToList();
List<BinaryExpression> orElseExpressionList = new List<BinaryExpression>();
foreach (var value in disctinctValues)
{
System.Linq.Expressions.BinaryExpression expression = null;
foreach (var criteria in orderedList.Where(cr => cr.Left.ToString().Equals(value.Left.ToString())))
{
if (expression == null)
{
expression = criteria;
}
else
{
if (expression.Left.ToString() == criteria.Left.ToString())
expression = System.Linq.Expressions.BinaryExpression.OrElse(expression, criteria);
else
expression = System.Linq.Expressions.BinaryExpression.AndAlso(expression, criteria);
}
}
orElseExpressionList.Add(expression);
}
System.Linq.Expressions.BinaryExpression expressionAnd = null;
foreach (var ex in orElseExpressionList)
{
if (expressionAnd == null)
{
expressionAnd = ex;
}
else
{
expressionAnd = System.Linq.Expressions.BinaryExpression.AndAlso(expressionAnd, ex);
}
}
if (expressionAnd != null)
{
return System.Linq.Expressions.Expression.Lambda<Func<T, bool>>(expressionAnd, e);
}
else
{
return NoFilterExpression;
}
}
static Expression<Func<T, bool>> GetExpression<T>(string propertyName, string propertyValue)
{
var parameterExp = Expression.Parameter(typeof(T), "type");
var propertyExp = Expression.Property(parameterExp, propertyName);
MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) });
var someValue = Expression.Constant(propertyValue, typeof(string));
var containsMethodExp = Expression.Call(propertyExp, method, someValue);
return BinaryExpression.Lambda<Func<T, bool>>(containsMethodExp, parameterExp);
}
private static System.Linq.Expressions.BinaryExpression Like(Expression lhs, Expression rhs)
{
//typeof(string).GetMethod("Contains", new Type[] { typeof(string) }, null);
Expression expression = Expression.Call(
typeof(FileInfoHelper).GetMethod("Like",
BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public)
, lhs, rhs);
return expression as BinaryExpression;
}
class BinaryExpressionComparer : IEqualityComparer<BinaryExpression>
{
#region IEqualityComparer<Contact> Members
public bool Equals(BinaryExpression x, BinaryExpression y)
{
return x.Left.ToString().Equals(y.Left.ToString());
}
public int GetHashCode(BinaryExpression obj)
{
return obj.Left.ToString().GetHashCode();
}
#endregion
}
}

How do I pass int array to RouteValueDictionary

I need generate this url: http://localhost:3178/Reports/?GroupId=1211&GroupId=1237
I'm trying:
var routeData = new RouteValueDictionary();
routeData.Add("GroupId", "1, 2");
getting: GroupId=1,%202
or
routeData.Add("GroupId", "1");
routeData.Add("GroupId", "2");
getting: An item with the same key has already been added
and even
routeData.Add("GroupId[0]", "1");
routeData.Add("GroupId[1]", "2");
getting: ?GroupId%5B0%5D=1&GroupId%5B1%5D=2
it's possible to somehow fix my issue?
The RouteValueDictionary is meant to provide information to routes. As such, I don't think it has the capability you're asking for. I've been using a custom helper to populate query string data based on what I pass into it:
public static string BuildPath(RequestContext context, string routeName, RouteValueDictionary routeValues, object additionalParams)
{
var vpd = RouteTable.Routes[routeName].GetVirtualPath(context, routeValues);
if (vpd == null)
return string.Empty;
var virtualpath = vpd.VirtualPath;
var addparams = BuildAdditionalParams(additionalParams);
if (!virtualpath.Contains("?") && addparams.Length > 0)
virtualpath = virtualpath + "?" + addparams;
else if (virtualpath.Contains("?") && addparams.Length > 0)
virtualpath = virtualpath + "&" + addparams;
return "/" + virtualpath;
}
protected static string BuildAdditionalParams(object additionalParams)
{
if (additionalParams == null)
return string.Empty;
StringBuilder sb = new StringBuilder();
Type type = additionalParams.GetType();
PropertyInfo[] props = type.GetProperties();
Action<string, string> addProperty = (name, value) =>
{
if (sb.Length > 0)
sb.Append("&");
sb.Append(name);
sb.Append("=");
sb.Append(value);
};
foreach (PropertyInfo prop in props)
{
var simplevalue = prop.GetValue(additionalParams, null);
if (simplevalue != null)
{
Type propertyType = prop.PropertyType;
if (Nullable.GetUnderlyingType(propertyType) != null)
{
propertyType = Nullable.GetUnderlyingType(propertyType);
}
if (propertyType.IsEnum)
{
addProperty(prop.Name, ((int)simplevalue).ToString());
}
else if (propertyType.IsArray && propertyType != typeof(string))
{
foreach (var val in prop.GetValue(additionalParams, null) as IEnumerable)
addProperty(prop.Name, val.ToString());
}
else
{
if (!string.IsNullOrEmpty(simplevalue.ToString()))
addProperty(prop.Name, simplevalue.ToString());
}
}
}
return sb.ToString();
}
This function will build a full path to your route and append the values in the additionalParams object as query string data. This can handle arrays, enums, nullable values, and other types that by executing their ToString method.
Hope this helps!

Resources