Error uploading a document to SQL Server in .Net Core 3.1 Web API

0

I have a SQL Server stored procedure that is used for uploading a document and returns an ID upon success.

I am storing the parameter file_data into a byte[] type in the Customer_Document_ADD class.

public byte[] file_data { get; set; }

The following is my repository code.

public async Task<int> InsertCustomer_Document_ADDResult(Customer_Document_ADD customer_Document_ADDED)
        {
            await using(SqlConnection connection = new SqlConnection(_connectionString))
            {
                connection.Open();

                // define SqlParameters for the other two params to be passed
                var company_idParam = new SqlParameter("@company_id", customer_Document_ADDED.company_id);
                var customer_idParam = new SqlParameter("@customer_id", customer_Document_ADDED.customer_id);
                var customer_site_idParam = new SqlParameter("@customer_site_id", customer_Document_ADDED.customer_site_id);
                var customer_system_idParam = new SqlParameter("@customer_system_id", customer_Document_ADDED.customer_system_id);
                var job_idParam = new SqlParameter("@job_id", customer_Document_ADDED.job_id);
                var security_levelParam = new SqlParameter("@security_level", customer_Document_ADDED.security_level);
                var file_nameParam = new SqlParameter("@file_name", customer_Document_ADDED.file_name);
                var file_sizeParam = new SqlParameter("@file_size", customer_Document_ADDED.file_size);
                var upload_dateParam = new SqlParameter("@upload_date", customer_Document_ADDED.upload_date);
                var document_extParam = new SqlParameter("@document_ext", customer_Document_ADDED.document_ext);
                var user_codeParam = new SqlParameter("@user_code", customer_Document_ADDED.user_code);
                var user_descriptionParam = new SqlParameter("@user_description", customer_Document_ADDED.user_description);
                var reference1Param = new SqlParameter("@reference1", customer_Document_ADDED.reference1);
                var reference2Param = new SqlParameter("@reference2", customer_Document_ADDED.reference2);
                var reference3Param = new SqlParameter("@reference3", customer_Document_ADDED.reference3);
                var reference4Param = new SqlParameter("@reference4", customer_Document_ADDED.reference4);
                var file_dataParam = new SqlParameter("@file_data", customer_Document_ADDED.file_data);
                //if (file_dataParam.Value == null)
                //{
                //    file_dataParam.Value = "";
                //}
                file_dataParam.SqlDbType = SqlDbType.Image;

                // define the output parameter that needs to be retained
                // for the Id created when the Stored Procedure executes 
                // the INSERT command
                var document_idParam = new SqlParameter("@document_id", SqlDbType.Int);

                // the direction defines what kind of parameter we're passing
                // it can be one of:
                // Input
                // Output
                // InputOutput -- which does pass a value to Stored Procedure and retains a new state
                document_idParam.Direction = ParameterDirection.Output;

                // we can also use context.Database.ExecuteSqlCommand() or awaitable ExecuteSqlCommandAsync()
                // which also produces the same result - but the method is now marked obselete
                // so we use ExecuteSqlRawAsync() instead

                // we're using the awaitable version since GetOrCreateUserAsync() method is marked async
                await context.Database.ExecuteSqlRawAsync(
                    "EXECUTE [dbo].[Customer_Document_ADD_incentive] @company_id, @customer_id, @customer_site_id, @customer_system_id, @job_id, @security_level, @file_name, @file_size, @upload_date, @document_ext, @user_code, @user_description, @reference1, @reference2, @reference3, @reference4, @file_data, @document_id out",
                    company_idParam,
                    customer_idParam,
                    customer_site_idParam,
                    customer_system_idParam,
                    job_idParam,
                    security_levelParam,
                    file_nameParam,
                    file_sizeParam,
                    upload_dateParam,
                    document_extParam,
                    user_codeParam,
                    user_descriptionParam,
                    reference1Param,
                    reference2Param,
                    reference3Param,
                    reference4Param,
                    file_dataParam,
                    document_idParam);

                // the userIdParam which represents the Output param
                // now holds the Id of the new user and is an Object type
                // so we convert it to an Integer and send
                return Convert.ToInt32(document_idParam.Value);
            }
        }

I'm getting the following error in Postman.

Microsoft.Data.SqlClient.SqlException (0x80131904): The parameterized query '(@company_id int,@customer_id int,@customer_site_id int,@custome' expects the parameter '@file_data', which was not supplied.
   at Microsoft.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at Microsoft.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at Microsoft.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
   at Microsoft.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
   at Microsoft.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString, Boolean isInternal, Boolean forDescribeParameterEncryption, Boolean shouldCacheForAlwaysEncrypted)
   at Microsoft.Data.SqlClient.SqlCommand.CompleteAsyncExecuteReader(Boolean isInternal, Boolean forDescribeParameterEncryption)
   at Microsoft.Data.SqlClient.SqlCommand.InternalEndExecuteNonQuery(IAsyncResult asyncResult, Boolean isInternal, String endMethod)
   at Microsoft.Data.SqlClient.SqlCommand.EndExecuteNonQueryInternal(IAsyncResult asyncResult)
   at Microsoft.Data.SqlClient.SqlCommand.EndExecuteNonQueryAsync(IAsyncResult asyncResult)
   at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteNonQueryAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteNonQueryAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteNonQueryAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.RelationalDatabaseFacadeExtensions.ExecuteSqlRawAsync(DatabaseFacade databaseFacade, String sql, IEnumerable`1 parameters, CancellationToken cancellationToken)
   at WebAPI.Repository.Customer_Document_ADDRepository.InsertCustomer_Document_ADDResult(Customer_Document_ADD customer_Document_ADDED) in C:\Users\CStith\source\code\project\WebAPI\WebAPI\Repository\Customer_Document_ADDRepository.cs:line 73
   at WebAPI.Repository.Customer_Document_ADDRepository.InsertCustomer_Document_ADDResult(Customer_Document_ADD customer_Document_ADDED) in C:\Users\CStith\source\code\project\WebAPI\WebAPI\Repository\Customer_Document_ADDRepository.cs:line 97
   at WebAPI.Controllers.Customer_Document_ADDController.InsertCustomer_Document_ADDResult(Customer_Document_ADD customer_Document_ADDED) in C:\Users\CStith\source\code\project\WebAPI\WebAPI\Controllers\Customer_Document_ADDController.cs:line 38
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
ClientConnectionId:e8f735f0-1ab5-4d53-9ead-01df3ee63c2e
Error Number:8178,State:1,Class:16

enter image description here

All other values are captured except the file. I am getting a null value in the debugger. Why am I unable to upload a file into the database? Thanks in advance.

sql
.net-core
entity-framework-core
asp.net-core-webapi
asp.net-core-3.1
asked on Stack Overflow Apr 28, 2021 by carltonstith • edited Apr 28, 2021 by carltonstith

1 Answer

0

Firstly,default model binding system cannot bind file to byte[] properties.If you want to bind file to btye[],you can use ByteArrayModelBinder,here is an official link.

Also,if you don't mind to change the type of file_data,you can use

public IFormFile file_data { get; set; }

and then you can convert it to byte[] type with MemoryStream.Here is an official link about upload files in .net core.

answered on Stack Overflow Apr 29, 2021 by Yiyi You • edited Apr 29, 2021 by Yiyi You

User contributions licensed under CC BY-SA 3.0