On my C# asp.net webform I have a search page that has roughly 20 elements that ‘could’ be used as part of the search. There will be more added later.
What I have done is extend the textbox and dropdown listbox to include a few variables:
fieldname: Tablename.columnname dbtype: DbType.Int32 Joinparam: LEFT Join on otherTable ON x.y = a.b
These are all stored in the viewstate and loaded back in. The reason I do this is so that I can iterate through all the controls and pull out all the controls that are of my type. I can then validate them to make sure they have input and are of the right type. If so I can then pass them off to the database access layer and let the code dynamically generate the SQL statement.
I do not let anything but SELECT statements happen from this. The fields selected and returned can not be changed and I use the dbparameter to try and avoid sql injection.
My worry is that I put the table and field names that will be used in the search criteria and the JOINS required all in the viewstate. Is this a real bad idea?
I could obscurify this by just having some int index’s into tables that hold this info in the DB but this would still need to be put into the viewstate and just mean they would have an extra layer to figure out.
The reason I went for this approach was that I did not want to have to put tons of IF statements in the DB layer to build the statement there. It would be ugly as hell and a pain to maintain.
Thanks for any and all advice about this.
Jon
EDIT
Thanks all for the advice. Thankfully this app is an internal thing only so the damage would be limited. But I will never use this technique again and will work on the search template idea instead.
Cheers 🙂
I think it’s a real design mistake to encode parts of your data access layer in your view logic. Putting aside the security concerns, this is going to be really hard to maintain and understand for anyone coming after you. I think a factory class to produce your specific queries from the various selected inputs is probably going to be easier to work with in the long run. Or perhaps, you could populate a ‘search template’ from the inputs and have the search template function as the factory for producing the query, much like the way the UserPrincipal interacts with a PrincipalSearcher in the System.DirectoryServices.AccountManagement namespace.