2013-11-01 4 views
2

Я застрял на том, что, как я думал, будет очень простой проблемой. Я пытаюсь перенаправить пользователя на другой веб-сайт, если UserAgent не содержит ряд строк. Часть, которую я не могу понять, заключается в том, что оператор if отлично работает, если я использую приведенный ниже код. Я доволен результатами с этим, но что-то говорит мне, что это не хорошая практика, чтобы иметь только инструкцию else и ничего не выполнять, если утверждение доказывает истинность.Оператор C# if с string.Contains() не работает как ожидалось

 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()); 
      } 

Когда я пытаюсь выполнить следующий блок кода, сценарий перенаправляет пользователя независимо от того, что содержит строка UserAgent. Может кто-нибудь объяснить, почему это может произойти?

 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()); 
      } 
+0

Кстати, вместо того, чтобы этот гигантский 'contains' блок, почему бы вам не поставить все из строки в коллекцию и просто делать «Содержит»? Это резко упростило бы это. – Arran

+0

Вы перевернули его неправильно. Изменяя '==' на '! =' И 'Contains' на'! Contains', но оставляя '' '' 'as-is, вы только входите в блок, если все' Contains' являются true. Вы можете изменить все '' '' '' на '&&' или отменить отдельные отрицания и обернуть все это с помощью '!()'. – yoozer8

ответ

6

Обратить ваше заявление с помощью ! («нет»):

if(!(conditions)) { } 

Это позволит избежать необходимости использовать пустой блок кода, и вы можете просто отказаться от else.

Ваш второй кодовый блок будет перенаправляться, если вы не находитесь на мобильном устройстве, или когда ваш useragent содержит любую из следующих строк. Это зависит от вашего ввода и вашей среды.

Обратите внимание, что это намного проще создать коллекцию возможностей и проверить, если ваш UserAgent находится там:

if(new[] {"iphone", "somephone", "otherphone" }.Any(x => useragent.Contains(x))) {} 
+0

В зависимости от того, что легче читать, вы можете обернуть все это в '!' Или отменить каждый логический ('! =', '! StrUserAgent.Contains (...) ') и swap' || 'для' && '. –

+1

Содержащиеся вами композиции требуют точного соответствия, в то время как вопрос совпадает, если пользовательский агент содержит одно из укусов. –

+1

Это 'Array.Contains' назад. Вы можете сделать 'new [] {...}. Любой (x => useragent.Contains (x))'. –

0

Вы должны полностью изменить всю вещь. Помещение !A || !B - это не то же самое, что и !(A||B). В первом случае, если его A тогда это не B, то это True. Во втором - 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()); 
     } 
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()); 
     } 
3

Это всегда будет верно, что по крайней мере один из ваших условий не будет истинным. Например, если strUserAgent.Contains (iphone) будет false, если значение strUserAgent.Contains («blackberry») истинно.

Вам необходимо сменить оператора OR (||) логическому оператору AND (&&).

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()); 
     } 
6

Необходимо De Morgan's Law. Когда вы перевернули свое состояние, ваши ОР должны стать ИД

+0

+1, я думал точно так же, Это лучший ответ партии. Гораздо проще дать программный ответ – Satpal

+0

@Satpal AllenG также правилен, и он не слишком ленив, чтобы напечатать код. – cadrell0

+0

@ cadrell0 - обычно я. Сегодня утром я чувствую прилив настроения. – AllenG

1

Не ответ, просто предложение. Вы можете сделать свой код понятнее с помощью метода расширения:

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

А теперь написать

if (strUserAgent.ContainsAnyOf("iphone", "blackberry", "mobile", "windows ce", "opera mini", "palm", "android")) 
{ 
    // 
} 
Смежные вопросы