There is an attribute (LinqToQueryable) in the webapi package for LinqToQuerystring, but I wasn't able to find a good explanation how it works.
Does it modify the returning results?
Does it enable LinqToQuerystring? (but how do I get the querystring then?)
Other?
As it turns out, the attribute [LinqToQueryable] filters/orders/... the Queryable result when returning.
To get the querystring in webapi2 I created an extension method:
public static class RequestExtensions
{
public static string GetQueryString(this HttpRequestMessage request)
{
return request.GetQueryNameValuePairs().Select(x => x.Key + "=" + x.Value).Aggregate((i, j) => i + "&" + j);
}
}
But I suspect this could also be done with ODataRequestOptions as parameter for the (webapi)method instead of using the querystring. The only problem is I don't know how to convert this to a string.
The advantage for this ODataRequestOption is that you can easily couple validators.
Related
I like to store simple functions which can be expressed as one line lambda in private and final instance variables when they are used several times by other methods in the class.
Also I do that sometimes with functions which are not used several times to make a big method shorter and to have a stronger expression of the functionality used in the method.
public class SomeClass {
private final UnaryOperator<Something> someMethod = s -> doSomething;
public void someMethod2(Something s) {
//some code which goes over several lines and uses someMethod variable
}
public void someMethod3(Something s) {
//some code which goes over several lines and uses someMethod variable
}
}
Another example in which the input is preapred for diffrent services in a helper class. The two same characters have to be replaced in the String for both services. The function for this is not stored a normal static method, it is stored in a static field which implements the UnaryOperator.
public class PrepareServicesInputHelper {
private static final UnaryOperator<String> replaceSignsForAllServices = s -> s.replace('+', '-')
.replace('/', '*');
public static String transformStringForServiceOne(String s) {
return "Additional transformation information for service one" + removeUnwantedSigns.apply(s);
}
public static String transformStringForServiceTwo(String s) {
return "Additional transformation information for service two:" + removeUnwantedSigns.apply(s);
}
}
It looks better and is clearer this way for me.
Is this a good idea or are there some disadvantages which are practical or hurt some paradigms of clean code with this approach and the functionality should be stored traditional in instance methods?
In your example I cannot see any added value of your solution compared with just plain call of a method. Your solution is an overkill.
Abraham Maslow (https://en.wikipedia.org/wiki/Law_of_the_instrument):
I suppose it is tempting, if the only tool you have is a hammer, to treat everything as if it were a nail.
The proper use case for lambdas is where you need to pass a function, or to select a function from multiple possible ones. Here your use case is just a plain re-use of a method, obfuscated by a lambda.
Study the behavioural design patterns here or here, such as Command, Observer/Listener, Strategy, Visitor. Here you need to pass a behaviour and that's what lambdas are designed for in Java.
Another quick "rule of thumb" may be this:
Do you need to call a method right now? So call a method.
Do you need to pass a method to be called from inside another method, later, maybe called not once but multiple times, maybe even not at all (if the method in control decides to)? So pass a lambda.
For your use case the common way is this. It looks even better and is even clearer this way :)
public class PrepareServicesInputHelper {
private static String replaceSignsForAllServices(final String s) {
return s.replace('+', '-').replace('/', '*');
}
public static String transformStringForServiceOne(final String s) {
return "Additional transformation information for service one" + removeUnwantedSigns(s);
}
public static String transformStringForServiceTwo(final String s) {
return "Additional transformation information for service two:" + removeUnwantedSigns(s);
}
}
A good example, similar to the yours but not the same, is this. You have a logger which writes to a file, but only if you turn on the logging. Evaluating the log text might be costly and we want to calculate it only lazily, only when needed.
public class Logger {
private boolean logIsOn;
// constructor, setters, getters etc.
public log(final String message) {
if (logIsOn) {
printToFile(message);
}
}
public lazyLog(final Supplier<String> message) {
if (logIsOn) {
printToFile(message.get());
}
}
}
// Here the expensive calculation occurs always, even if the logging is off
logger.log("Operation x performed on " +
person.getFirstName() + " " +
person.getLastName() +
" with the result " + result.calculate());
// Here the expensive calculation occurs only when the logging is on
logger.lazyLog(() -> "Operation x performed on " +
person.getFirstName() + " " +
person.getLastName() +
" with the result " + result.calculate());
public String searchUserById(#RequestParam(value = "fileType", required = true) String fileType) {
System.out.println(fileType);
return "downloadexcel";
}
public String searchUserByName(#RequestParam(value = "fileType", required = true) String fileType, #RequestParam(value = "batchNo", required = true) String batchNo) {
System.out.println(fileType + " ----------- " + batchNo);
return "downloadexcel";
}
This kind of URL Patterns i need I found some relevant Questions but i am getting 400 bad request when hitting the url
1.http://localhost:8080/apna-shopee/download.htm?fileType=mani
2.http://localhost:8080/apna-shopee/download.htm?fileType=mani&batchNo=1001
Didn't find the correct solution.
visit following link this may help you to solve your issue
create two method for same url pattern with different arguments
You can also do this based on condition. just make simple method with two parameters and based on second parameter value you can perform appropriate action. i.e if second parameter value is null that means request done using only single parameter
I want to use the Redirect to Action result on this code which gives a null but i have several if statements and the code is becoming more complex to build need a solution on how i could use the Redirect to Action which outputs null, help please?
public ActionResult Convert(double temperature, string convertTo)
{
ViewBag.Temperature = temperature;
ViewBag.ConvertTo = convertTo;
if (convertTo.Equals("Celsius"))
{ ViewBag.ConvertedTemperature = this.FahrenheitToCelsius(temperature); }
else
{ ViewBag.ConvertedTemperature = this.CelsiusToFahrenheit(temperature); }
return View("Convert");
}
The error message would really help. But it seems like you'd need to make your temperature parameter nullable, like so:
public ActionResult Convert(double? temperature, string convertTo)
Then you could check for null and return RedirectToAction:
if (temperature == null)
return RedirectToAction("ActionName", "ControllerName");
You'll also need to do the following to get the temperature value in your conversion methods:
temperature.Value
Hope this helps.
I have the following method:
private static object[] GenerateParameters(MethodBase executingMethod)
{
var parameterInfoList = MethodBase.GetCurrentMethod().GetParameters();
var parameterObjectList = new List<object>();
for (var i = 0; i < parameterInfoList.Count(); i++)
{
parameterObjectList.Add(parameterInfoList.GetValue(i));
}
return parameterObjectList.ToArray();
}
It just seems to me that is is bloated and over complicated. Is there a way to turn this method into one or two lines of code that will do the same thing? Possibly using Lambda or LINQ.
The reason why I think it is so bloated is because you can only get the value of the parameters from a parameterInfo array and not each parameterInfo (parameterInfo has no GetValue). There has to be a better way to do this.
EDIT
There was A LOT of great answers, and each of them worked, so thank you to everyone.
Check this
return MethodBase.GetCurrentMethod().GetParameters().ToArray <object>();
return Enumerable.Repeat<object>(parameterInfoList.GetValue(0), parameterInfoList.Count).ToArray();
Assuming parameterInfoList.GetValue(0) must actually be parameterInfoList.GetValue(i)?
var parameterInfoList = MethodBase.GetCurrentMethod().GetParameters();
return Enumerable.Range(0, parameterInfoList.Count()).Select(x => parameterInfoList(x)).ToArray();
I assume that you want to return the parameter-list of the method which was passed as argument to this method but you're always returning the parameter of GenerateParameters itself. So instead of parameterInfoList you should use executingMethod.
You are only adding the first element to the parameter array, GetValue(0) instead of GetValue(i).
But since you only want to return the ParameterInfo[] isn't it as easy as this?
private static ParameterInfo[] GenerateParameters(MethodBase executingMethod)
{
return executingMethod.GetParameters().ToArray();
}
Maybe i've misunderstood your requirement since this is a unnecessary method.
I know there is a way to use Expressions and Lambdas to accomplish this but I having a hard time piecing it all together. All I need is a method that will dynamically query an Entity Framework DBSet object to find the row where the propery with the given name matches the value.
My context:
public class MyContext : DbContext
{
public IDbSet<Account> Accoounts{ get { return Set<Account>(); } }
}
The method that I'm looking to write:
public T Get<T>(string property, object value) : where T is Account
{...}
I would rather not have to use Dynamic SQL to accomplish this so no need to suggest it because I already know it's possible. What I'm really looking for is some help to accomplish this using Expressions and Lambdas
Thanks in advance, I know it's brief but it should be pretty self-explanatory. Comment if more info is needed
I'm trying to avoid dynamic linq as much as possible because the main point of linq is strongly typed access. Using dynamic linq is a solution but it is exactly the oppose of the linq purpose and it is quite close to using ESQL and building the query from sting concatenation. Anyway dynamic linq is sometimes real time saver (especially when it comes to complex dynamic ordering) and I successfully use it in a large project with Linq-to-Sql.
What I usually do is defining some SearchCriteria class like:
public class SearchCriteria
{
public string Property1 { get; set; }
public int? Property2 { get; set; }
}
And helper query extension method like:
public static IQueryable<SomeClass> Filter(this IQueryable<SomeClass> query, SearchCriteria filter)
{
if (filter.Property1 != null) query = query.Where(s => s.Property1 == filter.Property1);
if (filter.Property2 != null) query = query.Where(s => s.Property2 == filter.Property2);
return query;
}
It is not generic solution. Again generic solution is for some strongly typed processing of classes sharing some behavior.
The more complex solution would be using predicate builder and build expression tree yourselves but again building expression tree is only more complex way to build ESQL query by concatenating strings.
Here's my implementation:
public T Get<T>(string property, object value) : where T is Account
{
//p
var p = Expression.Parameter(typeof(T));
//p.Property
var propertyExpression = Expression.Property(p, property);
//p.Property == value
var equalsExpression = Expression.Equal(propertyExpression, Expression.Constant(value));
//p => p.Property == value
var lambda = Expression.Lambda<Func<T,bool>>(equalsExpression, p);
return context.Set<T>().SingleOrDefault(lambda);
}
It uses EF 5's Set<T>() method. If you are using a lower version, you'll need to implement a way of getting the DbSet based on the <T> type.
Hope it helps.
Dynamic Linq may be an option. Specify your criteria as a string and it will get built as an expression and ran against your data;
An example from something I have done;
var context = new DataContext(ConfigurationManager.ConnectionStrings["c"].ConnectionString);
var statusConditions = "Status = 1";
var results = (IQueryable)context.Contacts.Where(statusConditions);
http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx