简体   繁体   中英

Making SqlDataAdapter/Datareader “Really Read-Only”

Updated Question: Is there a way to force dataadapter accept only commands which do not include any update/drop/create/delete/insert commands other than verifying the command.text before sending to dataadapter (otherwise throw exception). is there any such built-in functionality provided by dot net in datareader dataadapter or any other?

Note: DataReader returns results it also accepts update query and returns result. (I might be omitting some mistake but I am showing my update command just before executing reader and then show message after its success which is all going fine

Could you search the string for some keywords? Like CREATE,UPDATE, INSERT, DROP or if the query does not start with SELECT? Or is that too flimsy?

You might also want to create a login for this that the application uses that only has read capability. I don't know if the object has that property but you can make the server refuse the transaction.

All you need to do is ensure there are no INSERT, UPDATE, or DELETE statements prepared for the DataAdapter . Your code could look something like this:

var dataAdapter = new SqlDataAdapter("SELECT * FROM table", "connection string");

OR

var dataAdapter = new SqlDataAdapter("SELECT * FROM table", sqlConnectionObject);

And bam, you have a read-only data adapter.

If you just wanted a DataTable then the following method is short and reduces complexity:

public DataTable GetDataForSql(string sql, string connectionString)
{
    using(SqlConnection connection = new SqlConnection(connectionString))
    {
        using(SqlCommand command = new SqlCommand())
        {
            command.CommandType = CommandType.Text;
            command.Connection = connection;
            command.CommandText = sql;
            connection.Open();          
            using(SqlDataReader reader = command.ExecuteReader())
            {
                DataTable data = new DataTable();
                data.Load(reader);
                return data;
            }

        }

    }

}

usage:

try{
    DataTable results = GetDataForSql("SELECT * FROM Table;", ApplicationSettings["ConnectionString"]);
}
catch(Exception e)
{
    //Logging
    //Alert to user that command failed.
}

There isn't really a need to use the DataAdapter here - it's not really for what you want. Why even go to the bother of catching exceptions etc if the Update, Delete or Insert commands are used? It's not a great fit for what you want to do.

It's important to note that the SelectCommand property doesn't do anything special - when the SelectCommand is executed, it will still run whatever command is passed to it - it just expects a resultset to be returned and if no results are returned then it returns an empty dataset.

This means that (and you should do this anyway) you should explicitly grant only SELECT permissions to the tables you want people to be able to query.

EDIT

To answer your other question, SqlDataReader 's are ReadOnly because they work via a Read-Only firehose style cursor. What this effectively means is:

while(reader.Read()) //Reads a row at a time moving forward through the resultset (`cursor`)
{
   //Allowed
   string name = reader.GetString(reader.GetOrdinal("name"));
   //Not Allowed - the read only bit means you can't update the results as you move through them
   reader.GetString(reader.GetOrdina("name")) = name;
}

It's read only because it doesn't allow you to update the records as you move through them. There is no reason why the sql they execute to get the resultset can't update data though.

If you have a read-only requirement, have your TextBox use a connection string that uses an account with only db_datareader permissions on the SQL database.

Otherwise, what's stopping the developer who is consuming your control from just connecting to the database and wreaking havoc using SqlCommand all on their own?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM