4

I am stuck on what I thought would be a really easy problem. I am trying to redirect a user to a different website if the UserAgent does not contain a series of strings. The part I can not figure out is that the if statement works fine if I use the code below. I am happy with the results with this but something tells me that it is not good practice to only have an else statement and perform nothing if the statement proves to be true.

        string strUserAgent = Request.UserAgent.ToString().ToLower();

        if (strUserAgent != null)
        {
            if (Request.Browser.IsMobileDevice == true || 
                strUserAgent.Contains("iphone") ||
                strUserAgent.Contains("blackberry") || 
                strUserAgent.Contains("mobile") ||
                strUserAgent.Contains("windows ce") || 
                strUserAgent.Contains("opera mini") ||
                strUserAgent.Contains("palm") ||
                strUserAgent.Contains("android"))
            {
                // Is this normal practice to only have an else block?
            }else
            {
                Response.Redirect(AppState["redirectBack"].ToString());
            }

When I try the next block of code the script redirects the user no matter what the UserAgent string contains. Can someone explain why this might be happening?

        string strUserAgent = Request.UserAgent.ToString().ToLower();

        if (strUserAgent != null)
        {
            if (Request.Browser.IsMobileDevice != true || 
                !strUserAgent.Contains("iphone") ||
                !strUserAgent.Contains("blackberry") || 
                !strUserAgent.Contains("mobile") ||
                !strUserAgent.Contains("windows ce") || 
                !strUserAgent.Contains("opera mini") ||
                !strUserAgent.Contains("palm") ||
                !strUserAgent.Contains("android"))
            {
                 Response.Redirect(AppState["redirectBack"].ToString());
            }
2
  • By the way, instead of having this mammoth contains block, why don't you put all of the strings into a collection, and just do a Contains on that? It would drastically simplify it. Commented Nov 1, 2013 at 16:20
  • You've inverted it incorrectly. By changing == to != and Contains to !Contains but leaving the ||s as-is, you're only entering the block if all of the Contains are true. You can change all of the ||s to &&s, or undo the individual negations and wrap the whole thing with !(). Commented Nov 1, 2013 at 16:26

6 Answers 6

8

Invert your statement using ! ("not"):

if(!(conditions)) { }

This will avoid the need to use an empty code block and you can just drop the else.

Your second codeblock will redirect when you're not on a mobile device or when your useragent contains any of the following strings. It depends on your input and your environment.

Do note that it's a lot easier to create a collection of the possibilities and check if your useragent is in there:

if(new[] {"iphone", "somephone", "otherphone" }.Any(x => useragent.Contains(x))) {}
Sign up to request clarification or add additional context in comments.

4 Comments

Depending on which is easier to read, you could wrap the whole thing in a ! or reverse each boolean (!=, !strUserAgent.Contains(...)) and swap || for &&.
The contains you're showing requires an exact match, while the question matches if the user agent contains one of the stings.
That Array.Contains is backwards. You could do new[] { ... }.Any(x => useragent.Contains(x)).
Overlooked that part, good point. I've edited it, thanks for the elegant solution.
8

You need De Morgan's Law. When you inverted your condition, your ORs need to become ANDs

3 Comments

+1, I was thinking exactly same, This is best answer of the lot. It is much easier to giver programmatic answer
@Satpal AllenG is correct as well, and he is not too lazy to type out the code.
@cadrell0 - normally I am. I'm just in a giving mood this morning.
4

It will always be true that at least one of your conditions will not be true. For instance, if strUserAgent.Contains(iphone) will be false if strUserAgent.Contains("blackberry") is true.

You need to change your OR (||) operator to a logical AND (&&) operator.

    if (strUserAgent != null)
    {
        if (Request.Browser.IsMobileDevice != true && 
            !strUserAgent.Contains("iphone") &&
            !strUserAgent.Contains("blackberry") && 
            !strUserAgent.Contains("mobile") &&
            !strUserAgent.Contains("windows ce") && 
            !strUserAgent.Contains("opera mini") &&
            !strUserAgent.Contains("palm") &&
            !strUserAgent.Contains("android"))
        {
             Response.Redirect(AppState["redirectBack"].ToString());
        }

Comments

3

Not an answer, just a suggestion. You can make your code cleaner with an extension method:

public static bool ContainsAnyOf(this string source, params string[] strings)
{
    return strings.Any(x => source.Contains(x));
}

And now write

if (strUserAgent.ContainsAnyOf("iphone", "blackberry", "mobile", "windows ce", "opera mini", "palm", "android"))
{
     //
}

Comments

0

You need to reverse the entire thing. Putting !A || !B is not the same as !(A||B). In the first one if its A then it's Not B so it's True. In the second one it's False.

   if (!(Request.Browser.IsMobileDevice == true || 
            strUserAgent.Contains("iphone") ||
            strUserAgent.Contains("blackberry") || 
            strUserAgent.Contains("mobile") ||
            strUserAgent.Contains("windows ce") || 
            strUserAgent.Contains("opera mini") ||
            strUserAgent.Contains("palm") ||
            strUserAgent.Contains("android")
      ) )
        {
            Response.Redirect(AppState["redirectBack"].ToString());
        }

Comments

0
 string strUserAgent = Request.UserAgent.ToString().ToLower();

    if (strUserAgent != null)
    {
        if (!(Request.Browser.IsMobileDevice == true || 
            strUserAgent.Contains("iphone") ||
            strUserAgent.Contains("blackberry") || 
            strUserAgent.Contains("mobile") ||
            strUserAgent.Contains("windows ce") || 
            strUserAgent.Contains("opera mini") ||
            strUserAgent.Contains("palm") ||
            strUserAgent.Contains("android")))            
        {
            Response.Redirect(AppState["redirectBack"].ToString());
        }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.