What's the ASP.NET equivalent of this PHP code?
$db = new mysqli(/*some data*/);
$db->query('INSERT INTO `log` (`msg`) VALUES ("'.$db->real_escape_string($_POST['mesg']).'");');
Im only interested in mysqli_real_escape_string, but the only examples I can find on Google for ASP.NET and SQL are all injectable.
So my question is: How do I pass user data to SQL in ASP.NET using ADO.NET?
If you use replace of regex, please base your example on this code.
When using this approach, you'll want to look into using parameterized SQL in your code.
using (SqlConnection connection = new SqlConnection(connectionString))
{
DataSet userDataset = new DataSet();
SqlDataAdapter myDataAdapter = new SqlDataAdapter("SELECT * FROM Log WHERE Message = #Message", connection);
myCommand.SelectCommand.Parameters.Add("#Message", SqlDbType.VarChar, 11);
myCommand.SelectCommand.Parameters["#Message"].Value = messageString;
myDataAdapter.Fill(userDataset);
}
First of all, you should use properties if possible. Then you don't need to escape the strings yourself.
If you can't do that, you need to escape both backslashes and apostrophes:
public static string EscapeForMySQL(string str) {
return str.Replace("\\", "\\\\").Replace("'", "\\'")
}
If possible please refactor to avoid dynamic sql or use parameterized queries.
Use Parameterized queries for ODBC (I believe in oledbcommand will work here as well)
http://weblogs.asp.net/cumpsd/archive/2004/04/05/107456.aspx
See my talk on it - its the first subject:
http://channel9.msdn.com/Events/TechEd/NorthAmerica/2011/DEV333
Related
"Select item from table1 where Spare parts='"+ textbox1.text+"'".
I have tried to replace item with Textbox2.text.
I used :
"Select'"& textbox2.text& "' from table1 where Spare parts='"+ textbox1.text+"'"
I got error.
I used "+ textbox2.text+" I got error too
What you have here is one of the fastest ways out there to get your app hacked. It is NOT how you include user input in an SQL statement.
To explain the right way, I also need to include the connection and command objects for context, so I may also have a different pattern for how I handle these than you're use to. I'm also assuming the mysql tag in the question is accurate (though I have my doubts), such that the correct code looks more like this:
string SQL = "Select item from table1 where `Spare parts`= #SpareParts";
using cn = new MySqlConnection("connection string here")
using cmd = new MySqlCommand(SQL, cn)
{
cmd.Parameters.AddWithValue("#SpareParts", TextBox1.Text);
cn.Open();
using (var rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
// ...
}
}
}
Note the backticks around Spare Parts, so it will be correctly treated as a single object name by MySql.
I am trying to move data from a SPARQL endpoint to a JSONObject. Using RDF4J.
RDF4J documentation does not address this directly (some info about using endpoints, less about converting to JSON, and nothing where these two cases meet up).
Sofar I have:
SPARQLRepository repo = new SPARQLRepository(<My Endpoint>);
Map<String, String> headers = new HashMap<String, String>();
headers.put("Accept", "SPARQL/JSON");
repo.setAdditionalHttpHeaders(headers);
try (RepositoryConnection conn = repo.getConnection())
{
String queryString = "SELECT * WHERE {GRAPH <urn:x-evn-master:mwadata> {?s ?p ?o}}";
GraphQuery query = conn.prepareGraphQuery(queryString);
debug("Mark 2");
try (GraphQueryResult result = query.evaluate())
this fails because "Server responded with an unsupported file format: application/sparql-results+json"
I figured a SPARQLGraphQuery should take the place of GraphQuery, but RepositoryConnection does not have a relevant prepare statement.
If I exchange
try (RepositoryConnection conn = repo.getConnection())
with
try (SPARQLConnection conn = (SPARQLConnection)repo.getConnection())
I run into the problem that SPARQLConnection does not generate a SPARQLGraphQuery. The closest I can get is:
SPARQLGraphQuery query = (SPARQLGraphQuery)conn.prepareQuery(QueryLanguage.SPARQL, queryString);
which gives a runtime error as these types cannot be cast to eachother.
I do not know how to proceed from here. Any help or advise much appreciated. Thank you
this fails because "Server responded with an unsupported file format: application/sparql-results+json"
In RDF4J, SPARQL SELECT queries are tuple queries, so named because each result is a set of bindings, which are tuples of the form (name, value). In contrast, CONSTRUCT (and DESCRIBE) queries are graph queries, so called because their result is a graph, that is, a collection of RDF statements.
Furthermore, setting additional headers for the response format as you have done here is not necessary (except in rare circumstances), the RDF4J client handles this for you automatically, based on the registered set of parsers.
So, in short, simplify your code as follows:
SPARQLRepository repo = new SPARQLRepository(<My Endpoint>);
try (RepositoryConnection conn = repo.getConnection()) {
String queryString = "SELECT * WHERE {GRAPH <urn:x-evn-master:mwadata> {?s ?p ?o}}";
TupleQuery query = conn.prepareTupleQuery(queryString);
debug("Mark 2");
try (TupleQueryResult result = query.evaluate()) {
...
}
}
If you want to write the result of the query in JSON format, you could use a TupleQueryResultHandler, for example the SPARQLResultsJSONWriter, as follows:
SPARQLRepository repo = new SPARQLRepository(<My Endpoint>);
try (RepositoryConnection conn = repo.getConnection()) {
String queryString = "SELECT * WHERE {GRAPH <urn:x-evn-master:mwadata> {?s ?p ?o}}";
TupleQuery query = conn.prepareTupleQuery(queryString);
query.evaluate(new SPARQLResultsJSONWriter(System.out));
}
This will write the result of the query (in this example to standard output) using the SPARQL Query Results JSON format. If you have a non-standard format in mind, you could of course also create your own TupleQueryResultHandler implementation.
For more details on the various ways in which you can process the result (including iterating, streaming, adding to a List, or just directly sending to a result handler), see the documentation on querying a repository. As an aside, the javadoc on the RDF4J APIs is pretty extensive too, so if your Java editing environment has support for displaying that, I'd advise you to make use of it.
Similar to the question answered here https://stackoverflow.com/a/42932812/1321510 we need to execute a raw sql query. For the query we don't have any db context model (so any .FromSql answers won't work for us). However we need to execute it within an existing transaction (created with context.Database.BeginTransaction()). All solutions found on SO do not work with existing transactions.
Example:
var connection = context.Database.GetDbConnection();
using (var command = connection.CreateCommand())
{
command.CommandText = sql;
command.Transaction = context.Database.CurrentTransaction.GetDbTransaction();
var executeReader = command.ExecuteReader();
var values = new object[executeReader.FieldCount];
if (!executeReader.Read())
{
return values;
}
executeReader.GetValues(values);
return values;
}
}
Commiting the transaction then throws System.InvalidOperationException: 'This MySqlConnection is already in use. See https://fl.vu/mysql-conn-reuse'.
The provided link in the exception doesn't seem helpful at all, since we're neither using async nor using the connection whilst reading from it.
We're using Pomelo.EntityFrameworkCore.MySql as the database connector.
Why can you not use parameters in an SQL statement as the column name? I found that out after two hours of thinking what the problem could be. The only way it seemed possible was by doing it in a way it could be vulnerable to SQL injections (which for me wasn't a problem because the parameters are generated serverside).
This works:
string cmdgetValues = "SELECT " + column + " FROM user WHERE " + filterColumn + " = #filter";
MySqlCommand getValues = new MySqlCommand(cmdgetValues, connectionDB);
getValues.Parameters.AddWithValue("#filter", filterValue);
This doesn't work:
string cmdgetValues = "SELECT #column FROM user WHERE #filterColumn = #filter";
MySqlCommand getValues = new MySqlCommand(cmdgetValues, connectionDB);
getValues.Parameters.AddWithValue("#column", column);
getValues.Parameters.AddWithValue("#filterColumn", filterColumn);
getValues.Parameters.AddWithValue("#filter", filterValue);
Why is this? And is it intended?
Because select columns are fundamental query
You can't parameterise the fundamental query, so you have to build the query at the code.
If you want to decide the query columns runtime maybe you can try to use Prepared SQL Statement Syntax in Mysql.
I have been trying to get MySQL stored procedures running with the linq templates in Subsonic3. I added some functions to the MySQL.ttinclude file that seems to have generated the stored procedure reference classes. However when I run the code and call the stored procedures I seem to always get NULL results:
public DataSet SPTotalCallsByHour(int period)
{
rt.rtDB ee = new rt.rtDB();
StoredProcedure sp = ee.Totals_By_Hour(period.ToString());
sp.Execute();
return (DataSet)sp.Output;
}
Has anyone got MySQL stored procedures working with Subsonic3? If so can you please explain how you got them to work?
Did you use the ttinclude files straight out of the subsonic 3 release?
These are the two functions I added to the MySQL.ttinclude file:
List<SPParam> GetSPParams(string spName){
var result=new List<SPParam>();
MySqlCommand cmd = new MySqlCommand();
using(conn=new MySqlConnection(ConnectionString))
{
conn.Open();
cmd.Connection = conn;
cmd.CommandText = spName;
cmd.CommandType = CommandType.StoredProcedure;
try
{
MySqlCommandBuilder.DeriveParameters(cmd);
}
catch
{
}
if(cmd.Parameters.Count > 0)
{
foreach(MySqlParameter param in cmd.Parameters)
{
SPParam p = new SPParam();
p.SysType = GetSysType(param.MySqlDbType.ToString());
p.DbType = param.DbType.ToString();
p.Name = param.ParameterName;
p.CleanName=CleanUp(p.Name);
result.Add(p);
}
}
conn.Close();
}
return result;
}
List<SP> GetSPs(){
var result=new List<SP>();
string[] spNames = GetSPList();
foreach(string spName in spNames){
var sp=new SP();
sp.Name=spName;
sp.CleanName=CleanUp(sp.Name);
sp.Parameters=GetSPParams(sp.Name);
result.Add(sp);
}
return result;
}
i have never got stored procedures to work for mysql and subsonic, but i havent tried so hard either. my reasoning behind that you have something better than inline sql.
i think i speak for the masses that stored procedures was used to get around having database code (loads of sql) inside the application, dotted here n there
so programmers would use stored procedures to seperate the 2 concerns and make it easier to update/change/repair.
now if you use subsonic or any other kind of DAL and entities then you have no need to write sql statements as such, you just write code.... subsonic, linq etc know what to do with that and translate it for you.
so you dont really need stored procedures, if your database has a problem, you just run your TT files again.
the rest is code, your program. so maybe it is not the answer you would like, but sack the stored procedures and make use of how much fun it is to use something like subsonic and well forget all about your database and just think about the code.
I had a problem executing a SP with no parameter and trying to read back ouput. Seems you have to do this work around;
SubSonic.StoredProcedure sp = SPs.UspNoParamProc();
//Stored Procedure command Is Null... ensure command is created
string dummy = sp.Command.CommandSql;
rptList.DataSource = sp.GetReader();
rptList.DataBind();
Not sure if this problem continues to exist in 3.0 or not. Might try it out.