2
\$\begingroup\$

I have set up a Dictionary that calls on a class to fill a DataGridView via SQL statements. The problem is in two (out of 5) instances the value passed HAS to be an integer, but the value comes from a textbox so it is being passed as string. Before I set these Dictionaries up I was just using a switch statement that can be seen here. In my switch statement I simply added:

int n;
bool isNumber = int.TryParse(textBox.Text, out n);

if (!isNumber)
{
  MessageBox.Show("Input must be an integer");
  break;
}

to the two cases that needed the value to be an integer type.

Any idea on how I can add error handling to this? Preferably a message box that just says "value needs to be an integer".

    private void findScriptsQueryButton_Click(object sender, EventArgs e)
    {
        SqlConnection connection = new SqlConnection();
        string value = this.valueTextBox.Text;
        connection.ConnectionString = GetSqlConnection[serverComboBox.SelectedItem.ToString()];
        findScriptsDataGrid.DataSource = GetDataSource[findByComboBox.SelectedItem.ToString()](connection, value).Tables[0];
    }
    private static TableAdapters.FindScript dataSource = new TableAdapters.FindScript();
    private static readonly Dictionary<String, Func<SqlConnection, String, DataSet>> GetDataSource = new Dictionary<String, Func<SqlConnection, String, DataSet>>()
    {
        {"Target VDN", dataSource.FillByTargetVDN},
        {"Skill Group", dataSource.FillBySkillGroup},
        {"Translation Route Pool", dataSource.FillByTranslationRoutePool},
        {"Name", dataSource.FillByName},
        {"Label", dataSource.FillByLabel}
    };

    private static readonly Dictionary<String, String> GetSqlConnection = new Dictionary<String, String>()
    {
        {"SERVER01", ConfigurationManager.ConnectionStrings["csS01"].ConnectionString},
        {"SERVER02", ConfigurationManager.ConnectionStrings["csS02"].ConnectionString}
    };
\$\endgroup\$
  • \$\begingroup\$ Clarification on the text box: Does it have to be a text box? Or can you make it a different type of input? \$\endgroup\$ – JohnP Jul 3 '14 at 15:06
  • \$\begingroup\$ In this case the text box will be the most efficient solution. It's used to pass a parameter to a query which can literally be hundreds of thousands of possible strings or integers. \$\endgroup\$ – aaronmallen Jul 3 '14 at 15:11
  • \$\begingroup\$ If it can be hundreds of thousands, then how are you restricting it in only 2 of 5 instances? \$\endgroup\$ – JohnP Jul 3 '14 at 15:17
  • \$\begingroup\$ "Target VDN" and "Skill Group" are the only two queries in the dictionary that REQUIRE an integer value. \$\endgroup\$ – aaronmallen Jul 3 '14 at 15:25
  • 1
    \$\begingroup\$ Take a look at the ErrorProvider class. And the StackOverflow errorprovider tag \$\endgroup\$ – radarbob Jul 15 '14 at 19:51
2
\$\begingroup\$

In your data structure include a validator (this should probably be a Predicate<String>); most of the predicates will just return true, but the two that require integers will have a nontrivial validator that checks for integer.

So I guess the type should be Dictionary<String, Tuple<Func<SqlConnection, String, DataSet>>,Predicate<String>>

\$\endgroup\$
2
\$\begingroup\$

I haven't tested, so cannot verify about errors but you could try something like this -

  1. Create validator functions for validating input -

    public bool DummyValidator(string input)
    {
    
        return true;
    }
    
    public bool ValidateIntegerInput(string input)
    {
        int n;
        bool isNumber = int.TryParse(input, out n);
    
        if (!isNumber)
        {
            MessageBox.Show("Input must be an integer");\
            return false;
        }
        return true;
    }
    
  2. Create dictionary to hold them -

    private static readonly Dictionary<String, Func<String, Boolean>> GetValidator = new Dictionary<String, Func<String, Boolean>>()
    {
        {"Target VDN", dataSource.ValidateIntegerInput},
        {"Skill Group", dataSource.ValidateIntegerInput},
        {"Translation Route Pool", dataSource.DummyValidator},
        {"Name", dataSource.DummyValidator},
        {"Label", dataSource.DummyValidator}
    };
    
  3. Then validate before calling methods -

    SqlConnection connection = GetSqlConnection();
    string value = this.ValueTextBox.Text;
    
    if (GetValidator[this.FindByComboBox.SelectedItem.ToString()](textBox.Text)){
    
        this.FindScriptsDataGrid.DataSource = switchReplacement[this.FindByComboBox.SelectedItem.ToString()](connection, value).Tables[0];
    
    }
    

You can map other validators accordingly.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.