Click here to Skip to main content
15,881,687 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
Is there a way to insert a file without using parameters?
I am building a string that updates and insert data in several tables at same time, if something fails all changes is rejected.
This is my code:
if (Ordre.Attatchments.Where(x => x.SaveState == false).Count() > 0)
           {
               SqlSaveString.Append("INSERT INTO dbo.SaleAttatchments ([RefUid], [FilePath], [FileName], [FileType], [FileSize],[File], [AttatchInvoice]) VALUES");
               foreach (AttatchmentModel doc in Ordre.Attatchments.Where(x => x.SaveState == false).ToList())
               {
                   if (LineCount > 0) SqlSaveString.Append(",");
                   SqlSaveString.Append($"('{Ordre.SaleUid}', '{doc.FilePath}', '{doc.FileName}', '{doc.FileType}', {doc.FileSize}, {doc.File}, {doc.AttatchInvoice.BoolToTinyInt()})");
               }
               SqlSaveString.Append(";");
           }


What I have tried:

This code works but not what i am looking for.
public void SaveFile(AttatchmentModel parameters, string connectionStringName)
        {
            string connectionString = GetConnectionString(connectionStringName);
            using (IDbConnection connection = new System.Data.SqlClient.SqlConnection(connectionString))
            {
                var sql = "UPDATE dbo.SaleAttatchments SET[File] = @FileData WHERE RefUid = @Id And FileName = @FileName;";
                var dParams = new DynamicParameters();
                dParams.Add("@Id", parameters.RefUID, DbType.String);
                dParams.Add("@FileData", parameters.File, DbType.Binary);
                dParams.Add("@FileName", parameters.FileName, DbType.String);
                connection.Execute(sql, dParams);
            }
        }
Posted
Updated 21-Feb-20 6:14am
v2
Comments
Richard Deeming 21-Feb-20 12:03pm    
"without using parameters"

Why? Do you enjoy having your database completely destroyed by every random script-kiddie on the planet?!

NEVER use string concatenation / string.Format / interpolated strings to build a SQL query. ALWAYS use a parameterized query.

Everything you wanted to know about SQL injection (but were afraid to ask) | Troy Hunt[^]
How can I explain SQL injection without technical jargon? | Information Security Stack Exchange[^]
Query Parameterization Cheat Sheet | OWASP[^]

1 solution

Try:
C#
if (Ordre.Attatchments.Any(x => x.SaveState == false))
{
    string connectionString = GetConnectionString(connectionStringName);
    using (var connection = new System.Data.SqlClient.SqlConnection(connectionString))
    {
        const string sql = "UPDATE dbo.SaleAttatchments SET[File] = @FileData WHERE RefUid = @Id And FileName = @FileName;";
        
        var parameters = new List<DynamicParameters>();
        
        foreach (AttatchmentModel doc in Ordre.Attatchments.Where(x => x.SaveState == false))
        {
            var dParams = new DynamicParameters();
            dParams.Add("@Id", parameters.RefUID, DbType.String);
            dParams.Add("@FileData", parameters.File, DbType.Binary);
            dParams.Add("@FileName", parameters.FileName, DbType.String);
            parameters.Add(dParams);
        }
        
        connection.Execute(sql, parameters);
    }
}
Execute a Command multiple times - Dapper[^]

Alternatively, use a transaction:
C#
if (Ordre.Attatchments.Any(x => x.SaveState == false))
{
    string connectionString = GetConnectionString(connectionStringName);
    using (var connection = new System.Data.SqlClient.SqlConnection(connectionString))
    {
        const string sql = "UPDATE dbo.SaleAttatchments SET[File] = @FileData WHERE RefUid = @Id And FileName = @FileName;";
        
        connection.Open();
        
        using (var transaction = connection.BeginTransaction())
        {
            foreach (AttatchmentModel doc in Ordre.Attatchments.Where(x => x.SaveState == false))
            {
                var dParams = new DynamicParameters();
                dParams.Add("@Id", parameters.RefUID, DbType.String);
                dParams.Add("@FileData", parameters.File, DbType.Binary);
                dParams.Add("@FileName", parameters.FileName, DbType.String);
                connection.Execute(sql, parameters, transaction);
            }
            
            transaction.Commit();
        }
    }
}
Either way, NEVER try to embed your parameter values directly into the SQL query.
 
Share this answer
 
Comments
Member 12983358 22-Feb-20 5:47am    
Thanks Richard, I was playing around with that solution you proposed but since I am doing so many different updates/inserts I tried something else. Why should I NEVER embed my parameters into the sql?
Sofar it is only this I have done it in, the rest is procedures. But why not?

By the way, this is a local application with a local database, not intended for WWW
Richard Deeming 24-Feb-20 3:12am    
Because you'll render your code vulnerable to SQL Injection[^].

It doesn't matter whether it's a local application or a web application. Local application users can still accidentally cause problems by typing in "wrong" characters. And they can still be malicious - it doesn't take much searching to find stories of employees causing deliberate damage to their employer's network just before they leave.

Also, if you use parameters, you'll never have to worry about how to format the values into a suitable string representation.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900