I've seen a couple examples of how to check if a query string exists in a url with C#:
www.site.com/index?query=yes
if(Request.QueryString["query"]=="yes")
But how would I check a string without a parameter? I just need to see if it exists.
www.site.com/index?query
if(Request.QueryString["query"] != null) //why is this always null?
I know there's probably a simple answer and I'll feel dumb, but I haven't been able to find it yet. Thanks!
If you do not specify a value, the key will be automatically set to null, so you cannot check its existence.
In order to check if the value actually exists, you can check in the collection of Values equalling null if it contains your Key:
Request.QueryString.GetValues(null).Contains("query")
this is the fastest way to check it thanks to Ludovic's answer
if(Request.QueryString.GetValues(null)?.Contains("query")??false)
It returns null because in that query string it has no value for that key. I think the check you're looking for is this:
if(Request.QueryString.Keys.OfType<string>().Any(k => k == "query"))
or even:
if(Request.QueryString.AllKeys.Any(k => k == "query"))
The latter is probably more appropriate because that array is already cached.
If query was included as a parameter, but no value was specified, then the value of query will be null but it will still exist in Request.QueryString.AllKeys.
If query was not included, it won't exist in Request.QueryString.AllKeys at all.
Ludovic has the right answer. But I would like to offer a more robust version.
var valueEntries = Request.QueryString.GetValues((string)null) ?? new string[] {};
if (valueEntries.Contains("query", StringComparer.OrdinalIgnoreCase))
{
// value is specify in querystring
}
else
{
// value is NOT specify in querystring
}
This is verbose and it works. Here is a .NET Fiddle.
#using System.Linq;
#{
var empties = Request.Url.Query
.Split('&')
.Where(s => !s.Contains("=") || s.Last() == '=');
var keyExistsAndIsEmpty = empties.Any(x => x.Contains("target-key")
}
It turns out that if the value is null, then the key is also null in the QueryString collection. Your best bet is simply to assign a value to the query. There might be a way for you to rename the parameter so that this makes more semantic sense. For example instead of www.site.com/index?getdocument=yes you could do www.site.com/index?action=getdocument
However if you still want the url www.site.com/index?query to work, there is a way: don't use the QueryString at all and parse the URL manually:
string query = Request.RawUrl.Split('?')[1];
if (query == "query")
{
// send the data
}
You cannot use a null check to determine if a key exists when the "=" is not supplied since null means that the key wasn't in the query string.
The problem is that "query" is being treated as a value with a null key and not as a key with a null value.
In this case the key is also null inside Request.QueryString.AllKeys.
I used this generic method to "fix" the null key problem in the query string before using it. This doesn't involve manually parsing the string.
Usage example:
var fixedQueryString = GetFixedQueryString(Request.QueryString);
if (fixedQueryString.AllKeys.Contains("query"))
{
}
The method:
public static NameValueCollection GetFixedQueryString(NameValueCollection originalQueryString)
{
var fixedQueryString = new NameValueCollection();
for (var i = 0; i < originalQueryString.AllKeys.Length; i++)
{
var keyName = originalQueryString.AllKeys[i];
if (keyName != null)
{
fixedQueryString.Add(keyName, originalQueryString[keyName]);
}
else
{
foreach (var keyWithoutValue in originalQueryString[i].Split(','))
{
fixedQueryString.Add(keyWithoutValue, null);
}
}
}
return fixedQueryString;
}
I Prefer to use:
If(Request.QueryString.AllKeys.Contains("query")
{
//
}
Related
I'm currently trying to find invocations of .ExecuteSqlCommand and examine the first value being passed to the sql param.
Here is an example of the differences I've found in our code base.
ExecuteSqlCommand("[sql statement here]");
vs.
var sql = "sql statement";
ExecuteSqlCommand(sql);
So far, I have this:
var invocations = root.DescendantNodes()
.OfType<InvocationExpressionSyntax>()
.Select(ie => ModelExtensions.GetSymbolInfo(model, ie).Symbol)
.Where(symbol => symbol != null && symbol.Name == "ExecuteSqlCommand");
foreach (var invocation in invocations)
{
var method = (IMethodSymbol)invocation;
foreach (var param in method.Parameters)
{
//I can't quite seem to get information from IParameterSymbol about whether the param is a string literal, or a reference to a string via a variable.
}
}
If the param is not a string, and instead, a var, then I'll need to get the value of the var (as much as it's defined at runtime).
I'm not too sure if this is a job for the SemanticModel or the SyntaxTree, but my GUESS is that the SemanticModel should have the richer information I need to let me discover what I'm looking for.
My overall goal is to interrogate the sql being passed to the ExecuteSqlCommand method.
Thanks!
SemanticModel.GetConstantValue is the API we have for handling this situation.
It can accept both a syntax node and an expression. You will still need to track the state of variables back to their declaration sites and determine if they were given a constant expression.
I would use SemanticModel.GetSymbolInfo.Symbol?.DeclaringSyntaxReferences.First() to find the declaration site of a variable and then check to see if its a constant expression.
The Syntax API could be used to extract the sql statement value but depends on whether the variable declaration (i.e. var sql = "sql statement";) is included as part of code submitted to the syntax tree.
For example, if it's part of the same method implementation as where ExcuteSqlCommand() is called then you can first get the name of variable (i.e. sql) passed to it and use that to find the matching variable declaration statement within that same method. Finally, the sql statement value (i.e. "sql statement") can be extracted from that.
The following code first checks if the sql value is passed as a string literal otherwise looks for the variable declaration. The assumption it's all within the same method:
// whatever c# *method* code contains the sql.
// otherwise the root of the tree would need to be changed to filter to a specific single `MethodDeclarationSyntax`.
string submittedCode = "public void SomeMethodContainingSql(){ ...//rest of code...";
var tree = CSharpSyntaxTree.ParseText(submittedCode);
var root = (CompilationUnitSyntax) tree.GetRoot();
var arguments = root
.DescendantNodes()
.OfType<InvocationExpressionSyntax>()
.First(node => node.DescendantNodes().OfType<IdentifierNameSyntax>()
.First()
.Identifier.Text == "ExecuteSqlCommand")
.ArgumentList.DescendantNodes().ToList();
string sqlStatementValue = "";
var literalExpression = arguments.OfType<LiteralExpressionSyntax>().FirstOrDefault();
if (literalExpression != null)
{
sqlStatementValue = literalExpression.GetText().ToString();
}
else
{
var variableName = arguments
.First()
.ToFullString();
var variableDeclaration = root
.DescendantNodes()
.OfType<VariableDeclarationSyntax>()
.Single(node => node.DescendantNodes().OfType<VariableDeclaratorSyntax>()
.First()
.Identifier.Text == variableName);
sqlStatementValue = variableDeclaration.DescendantNodes()
.OfType<LiteralExpressionSyntax>()
.First()
.DescendantTokens()
.First()
.Text;
}
Otherwise, may need to look for the variable declaration in other parts of the submitted code (ex. class fields, properties, other methods, etc.) which is a bit more cumbersome.
Unfortunately Roslyn cannot provide a variable's value in a common cases when values is defined at runtime, because Roslyn actually doesn't know all possible values which may pass from outside the program, it doesn't calculate them and so on so forth. But if you can limit the needed cases to a inlining strings or variables which was declared and initialized at strings, Roslyn may help you with this:
You need to keep InvocationExpressionSyntax (or directly their first arguments)
var invocations = root.DescendantNodes()
.OfType<InvocationExpressionSyntax>()
.Select(ie => (ModelExtensions.GetSymbolInfo(model, ie).Symbol, ie))
// Would be better to compare not method's name but it FQN
.Where((symbol, node)) => symbol != null && symbol.Name == "ExecuteSqlCommand" &&
symbol.Parameters.Length == 1 &&
symbol.Parameters[0].Type.SpecialType == SpecialType.System_String &&
node.ArgumentList.Arguments.Count == 1)
.Select((symbol, node) => node);
You need to check not method parameter, but method argument which was passed to it
foreach (var invocation in invocations)
{
var argument = invocation .ArgumentList.Arguments[0];
if (argument is LiteralExpressionSyntax literal && literal.IsKind(SyntaxKind.StringLiteralExpression))
{
// You find invocation of kind `ExecuteSqlCommand("sql")`
}
else
{
var argSymbol = ModelExtensions.GetSymbolInfo(model, argument).Symbol;
if (!(argSymbol is null) && (argSymbol.Kind == SymbolKind.Field || argSymbol.Kind == SymbolKind.Property || argSymbol.Kind == SymbolKind.Local))
{
if (argSymbol.DeclaringSyntaxReferences.Length == 1)
{
var declarationNode = argSymbol.DeclaringSyntaxReferences[0].GetSyntax();
// I'm actually don't remember what exactlly `GetSyntax` returns for fields or locals:
// VariableDeclaratorSyntax or one of it parent LocalDeclarationStatementSyntax and FieldDeclarationSyntax, but if it returns declarations you also can
// get from them VariableDeclaratorSyntax that you need, it's just be a more deep pattern matching
if (declarationNode is VariableDeclaratorSyntax declaratorSyntax &&
declaratorSyntax.EqualsValueClauseSyntax?.Value is LiteralExpressionSyntax literal2 && literal2.IsKind(SyntaxKind.StringLiteralExpression) )
{
// You find invocation of kind `ExecuteSqlCommand(variable)` where variable is local variable or field
}
else if (declarationNode is PropertyDeclarationSyntax property)
{
// You can do the same things for properties initializer or expression body that you was do for fields and locals to check your case,
// but it doesn't work for property with get/set accessors in a common cases
}
}
}
}
}
I have one ASP.Net MVC - 5 application and I want to check if the session value is null before accessing it. But I am not able to do so.
//Set
System.Web.HttpContext.Current.Session["TenantSessionId"] = user.SessionID;
// Access
int TenantSessionId = (int)System.Web.HttpContext.Current.Session["TenantSessionId"];
I tried many solutions from SO
Attempt
if (!string.IsNullOrEmpty(Session["TenantSessionId"] as string))
{
//The code
}
Kindly guide me.
Error: NULL Reference
if(Session["TenantSessionId"] != null)
{
// cast it and use it
// The code
}
The NullReferenceException comes from trying to cast a null value. In general, you're usually better off using as instead of a direct cast:
var tenantSessionId = Session["TenantSessionId"] as int?;
That will never raise an exception. The value of tenantSessionId will simply be null if the session variable is not set. If you have a default value, you can use the null coalesce operator to ensure there's always some value:
var tenantSessionId = Session["TenantSessionId"] as int? ?? defaultValue;
Then, it will either be the value from the session or the default value, i.e. never null.
You can also just check if the session variable is null directly:
if (Session["TenantSessionId"] != null)
{
// do something with session variable
}
However, you would need to confine all your work with the session variable to be inside this conditional.
[] acts as an indexer (like a method on the class) and in this case, session is null and you cannot perform indexing on it.
Try this..
if(Session != null && Session["TenantSessionId"] != null)
{
// code
}
Check if the session is empty/Null or not in C# MVC Version Lower than 5.
if (!string.IsNullOrEmpty(Session["TenantSessionId"] as string))
{
//cast it and use it
//business logic
}
Check if the session is empty/Null or not in C# MVC Version Above 5.
if(Session["TenantSessionId"] != null)
{
//cast it and use it
//business logic
}
There is a case when you want to check only for existence of the key itself but not the content. Above method fails when you Session key value is null also.
Eg:
Session["myKey"] = null;
if(Session["myKey"]!=null){}
In above code, I want to check if only the key (not value) exists, I will get false. But the key does exists.
So the only way I could separate this existence check, is by basically checking each key.
static bool check_for_session_key(string SessionKey)
{
foreach (var key in HttpContext.Current.Session.Keys)
{
if (key.ToString() == SessionKey) return true;
}
return false;
}
if(check_for_session_key("myKey")){} //checks for the key only
Let me know if you know better way.
Check if the session is empty/Null or not
if (!string.IsNullOrEmpty(Session["TenantSessionId"] as string))
{
//here write code for logic
}
Im new to Dictionaries, so i have this basic question.
I have a dictionary like this:
Dictionary<string, string> usersLastStamp = checking.checkLastStamp();
How can i do a if statement that checks if a value of a specific key is something?
Like this:
if(usersLastStamp.the_value_of_key("theKey") == "someValue")
{
//Do something
}
I've taken a look at TryGetValue, but im not quite sure how to use it directly like the above in a if statement.
usersLastStamp["theKey"] will throw an exception if the key is not present in the dictionary (as specified here). You can use TryGetValue instead and combine it with short circuit evaluation:
string value = null;
if (usersLastStamp.TryGetValue("theKey", out value) && (value == "someValue"))
{
}
Folks have already answered the TryGetValue approach, but as an alternative: if it is an option, you could also consider using StringDictionary instead of Dictionary<string,string> - this returns null in the case that there is no value at that key, so you can just use:
if(usersLastStamp["theKey"] == "someValue")
without any risk of it erroring.
You could try
if(usersLastStamp["theKey"] != null && usersLastStamp["theKey"] == "SomeValue")
{
// Your cdoe writes here
}
You can use either
string someVal = "";
if (myDict.ContainsKey(someKey))
someVal = myDict[someKey];
or
string someVal = "";
if (myDict.TryGetValue(somekey, out someVal))
and then your if:
if (someVal == "someValue")
TryGetValue takes an out parameter, returns a bool, retruns true and updates the parameter if the key exists in the dictionary, if key doesn't exist in the dictionary returns false. Or you have to check if the key exists in the dictionary and only if it exists then take the value from it.
I'm attempting to dump variable property information to a simple string but when it gets to my nullable bools, the as string always returns null --even if the actual value is true | false!
StringBuilder propertyDump = new StringBuilder();
foreach(PropertyInfo property in typeof(MyClass).GetProperties())
{
propertyDump.Append(property.Name)
.Append(":")
.Append(property.GetValue(myClassInstance, null) as string);
}
return propertyDump.ToString();
No exceptions are thrown; quick and the output is exactly what I want except any properties that are bool? are always false. If I quick watch and do .ToString() it works! But I can't guarantee other properties are not, in fact, null.
Can anyone explain why this is? and even better, a workaround?
A bool is not a string, so the as operator returns null when you pass it a boxed boolean.
In your case, you could use something like:
object value = property.GetValue(myClassInstance, null);
propertyDump.Append(property.Name)
.Append(":")
.Append(value == null ? "null" : value.ToString());
If you want to have null values just not append any text, you can just use Append(Object) directly:
propertyDump.Append(property.Name)
.Append(":")
.Append(property.GetValue(myClassInstance, null));
This will work, but leave null properties in your "propertyDump" output as missing entries.
The as operator returns a casted value if the instance is of that exact type, or null otherwise.
Instead, you just should .Append(property.GetValue(...)); Append() will automatically handle nulls and conversions.
The nicest solution would be, in my opinion:
.Append(property.GetValue(myClassInstance, null) ?? "null");
If the value is null, it will append "null", and if not - it will call the value's ToString and append that.
Combining that with Linq instead of a foreach loop, you can have a nice little something:
var propertyDump =
string.Join(Environment.NewLine,
typeof(myClass).GetProperties().Select(
pi => string.Format("{0}: {1}",
pi.Name,
pi.GetValue(myClassInstance, null) ?? "null")));
(Looks nicer in the wide screen of VS).
If you compare speeds, by the way, it turns out the string.Join is faster than Appending to a StringBuilder, so I thought you might want to see this solution.
That's because the type of the property is not string. Change it to:
Convert.ToString(property.GetValue(myClassInstance, null))
If it's null, it will retrieve null and that's ok. For non-null values it will return the string representation of the value of the property.
You cannot cast a bool to a string. You must use ToString()
Use the null coalesing operator to handle the Null situations:
void Main()
{
TestIt tbTrue = new TestIt() { BValue = true }; // Comment out assignment to see null
var result =
tbTrue.GetType()
.GetProperties()
.FirstOrDefault( prp => prp.Name == "BValue" )
.GetValue( tb, null ) ?? false.ToString();
Console.WriteLine ( result ); // True
}
public class TestIt
{
public bool? BValue { get; set; }
}
I need to check if there is a param on the uri request.
So I need to check if that param is set. Is there a function on .NET/C#?
An unset value will be null or empty:
value = Request["param"];
if (String.IsNullOrEmpty(value))
{
// param is not set
}
If the param name is in the query string but the value is not, it will be empty. If the name is not in the query string, the value will be null. For example.
¶m1=¶m2=value
// Request["param1"] is String.Empty
// Request["param3"] is null
Yes, you can use HttpUtility.ParseQueryString() utility method which returns NameValueCollection and then cust call Get():
bool contains = HttpUtility.ParseQueryString(uri.Query)
.Get("ParameterName") != null;
Get() method
Returns A String that contains a comma-separated list of the values associated
with the specified key from the NameValueCollection, if found;
otherwise, null
EDIT:
If you have an instance of the HttpRequest then just use built in indexer like below:
bool contains = Request["ParamName"] != null;
In c# not implemented object is NULL. But if you try to acces to this object you will get the exception. You cat try to catch it or just add # before your variable.
So C# isset looks like this (for array of strings)
// Isset
internal static bool isset(String[] m, int index)
{
return (#m[index] == null) ? false : true;
}
Use it like this: if (App.isset(parts, 1)) cat = parts[1];
Or just "in plase" solution
if (#parts[1] != null) cat = parts[1];
I hope this ansver will help you.
You could use try and catch to wrap your uri request?
catch for NullReferenceException or just exception?