2012-04-19 4 views
0

У меня есть веб-служба, которая получает строку.Проверьте правильность аргументов, хранящихся в словаре.

Эта строка содержит несколько ключей => значения, которые объединены с символом '+'.

Я должен проверить каждое значение («обязательно», «не пусто») и назначить каждому переменную с тем же именем.

Вот как я построить словарь из строки:

string firstname; 
string lastname; 
string amount; 

string request = "firstname=foo+lastname=bar+amout=100.58"; 

Dictionary<string, string> arguments = new Dictionary<string, string>(); 

request.Split('+').ToList<string>().ForEach(p => 
{ 
    string[] tmp = p.Split('='); 

    if (tmp.Length == 2) 
     arguments.Add(tmp[0], tmp[1]); 
}); 

// Validate and assign : How I do with one value : (I must find a better way) 
bool isValid = true; 

// check "firstname" 
if(arguments.ContainsKey("firstname") && string.IsNullOrWhiteSpace(arguments["firstname"]) == false) 
{ 
    firstname = arguments["firstname"]; 
} 
else 
{ 
    isValid = false; 
    Logger.Write("Invalid argument : firstname"); 
} 

// Do this for about 20 arguments, it becomes huge... 

if(isValid) 
{ 
    Console.WriteLine(firstname); // Displays foo 
    Console.WriteLine(lastname); // Displays bar 
    Console.WriteLine(amout); // Displays 100.58 
} 

Спасибо, и извините за орфографические ошибки, я французский.

+2

гм .. что проблема на самом деле? – Tigran

+0

Что вы хотите изменить? –

+0

Например, я не могу понять, как проверить, существует ли в словаре первое имя, если оно не пустое, и как заполнить переменную «firstname» значением dictionnary. В действительности существует около 20 аргументов, и для каждого из них очень важно проверить их. –

ответ

0

Я думаю вы хотите что-то вроде этого, но так как вы не acutally задать вопрос, я просто угадать:

request.Split('+').ToList<string>().ForEach(p => 
{ 
    string[] tmp = p.Split('='); 

    if (tmp.Length == 2 && !string.IsNullOrWhiteSpace(tmp[1])) 
    { 
     // edit - if your string can have duplicates, use 
     // Dictionary<U,K>.ContainsKey(U) to check before adding 
     var key = tmp[0]; 
     var value = tmp[1]; 

     if(!arguments.ContainsKey(key)) 
     { 
      arguments.Add(key, value); 
     } 
     else 
     { 
      //overwrite with new value 
      //could also maybe throw on duplicate or some other behavior. 
      arguents[key]=value; 
     } 
    } 
    else 
     throw InvalidOperationException("Bad dictionary string value"); 
}); 

Кроме того, я бы вопрос использования ToList-> ForEach, если это было передо мной в обзоре кода. Вы хотите, чтобы избежать побочных эффектов в Linq, я написал бы его с традиционным Еогеаспом как:

var itemValues = request.Split('+'); 
foreach(var item in itemValues) 
{ 
    string[] tmp = item.Split('='); 

    if (tmp.Length == 2 && !string.IsNullOrWhiteSpace(tmp[1])) 
     arguments.Add(tmp[0], tmp[1]); 
    else 
     throw InvalidOperationException("Bad dictionary string value"); 
}); 



// Validate and assign 
//read values from the dictionary 
//use ContainsKey to check for exist first if needed 

Console.WriteLine(arguments["firstname"]); // Displays foo 
Console.WriteLine(arguments["lastname"]); // Displays foo 
Console.WriteLine(arguments["amout"]); // Displays 100.58 

Edit 2 - Вы должны инкапсулировать логику в методе:

private string TryGetValue(IDictionary<string,string> dict,string key) 
{ 
    string value = null; 
    if(dict.ContainsKey(key) && !string.IsNullOrWhiteSpace(dict[key])) 
    { 
     value = dict[key]; 
    } 
    else 
    { 
     Logger.Write("Invalid argument : " + key); 
    } 
    return value; 
} 

Теперь вы можете сказать:

string firstName = TryGetValue(arguments,"firstname"); 
string lastName= TryGetValue(arguments,"lastName"); 
string amount = TryGetValue(arguments,"amount"); 

bool isValid = firstName!=null && lastName != null && amount != null; 

if(isValid) 
{ 
    Console.WriteLine(firstName); // Displays foo 
    Console.WriteLine(lastName); // Displays bar 
    Console.WriteLine(amout); // Displays 100.58 
} 

TryGetValue бы превосходный метод расширения:

public static class Extensions 
{ 
    public static string TryGetValue(this IDictionary<string,string> dict, string key) 
    { 
     string value = null; 
     if(dict.ContainsKey(key) && !string.IsNullOrWhiteSpace(dict[key])) 
     { 
      value = dict[key]; 
     } 
     else 
     { 
      Logger.Write("Invalid argument : " + key); 
     } 
     return value; 
    } 

} 

Теперь вызывающий код будет выглядеть следующим образом:

string firstName = arguments.TryGetValue("firstname"); 
string lastName= arguments.TryGetValue("lastname"); 
string amount = arguments.TryGetValue("amount"); 

Последнее редактирование - записку о методах Удлинитель - Да, они опрятны, но это также легко случайно попасть в плохой ситуации перерасхода их. Прочитайте в msdn и блоги о них, следуйте рекомендациям. Избегайте расширений на общие типы, такие как object, string ect.

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

namespace Extensions.IDictionary { ... } 
namespace Extensions.string { ... } 
namespace Extensions.SomeType { ... } 
namespace Extensions.IList { ... } 

и потребляющих код не будет иметь using положения, чтобы соответствовать:

using Extensions.IDictionary; 

тянуть в только расширения ваш интересует, не больше.

+0

Большое спасибо, я новичок в C#, я не знал о методах расширений. Отличная функция! –

+0

@AsKaiser Нет проблем! В будущем, пожалуйста, постарайтесь выписать свои вопросы с максимально возможной информацией, чтобы избежать путаницы. Никто не любит догадываться! Я добавил короткую заметку о методах расширения для вас. – asawyer

0

Это всего лишь предположение, поскольку ваш вопрос непонятен.

// Validate and assign 

foreach(KeyValuePair<string,string> pair in arguments) 
{ 
    if(!String.IsNullOrEmpty(pair.Value)) 
    { 
     Console.WriteLine(pair.Value); 
    } 
} 
0

Если у вас есть больше, чем просто один firstnames и lastnames, и вы можете использовать список для значения словаря. Таким образом вы можете просто добавить другие значения для имени, имени и других.

Чтобы подтвердить, что вы можете сделать это между добавлением значений в словарь:

string request = "firstname=foo+lastname=bar+amout=100.58+firstname=+lastname=bar2+amout=100.59+firstname=foo3+lastname3=bar3+amout=100.60"; 

     Dictionary<string, List<string>> arguments = new Dictionary<string, List<string>>(); 
     request.Split('+').ToList<string>().ForEach(f => 
      { 
       string[] data = f.Split('='); 
       if (data.Length == 2) 
       { 
        if (!arguments.ContainsKey(data[0])) 
        { 
         if (data[1] != "") 
          arguments.Add(data[0], new List<string> { data[1] }); 
         else 
          arguments.Add(data[0], new List<string> { "no firstname" }); 
        } 
        else 
        { 
         if (data[1] != "") 
          arguments[data[0]].Add(data[1]); 
         else 
          arguments[data[0]].Add("no firstname"); 
        } 
       } 
      }); 

Надеется, что это помогает, свиданья

Смежные вопросы