Error SqlException when passing parameters from client-side (React) but not when passing them at server-side

daowdos 261 Reputation points
2022-10-05T03:32:09.573+00:00

I have an ASP.NET Core app project, SQL Server in the backend and React as the frontend.

When I pass the parameters (must be 1 or 0) to SetGameResults method through Swagger UI (browser) the database accepts the parameters and the table is filled.

But when I pass the parameters through the React client-side to ASP.NET, I get this error:

Inner Exception: Procedure or function 'Set_Game_Result' expects parameter '@user1_res', which was not supplied.

Controller.cs:

[HttpPost]   
[Route("SetGameResults")]   
public string SetGameResults(byte? us1, byte? us2)   
{   
    if (!(us1 >= 1 && us2 >= 1))  // it passes this condition -    
    {   
        DataTable table = new DataTable();   
        string sqlDataSource = _configuration.GetConnectionString("tictaktoedb1");   
        SqlDataReader myReader;   

        try   
        {   
            using (SqlConnection myCon = new SqlConnection(sqlDataSource))   
            {   
                myCon.Open();   

                using (SqlCommand myCommand = new SqlCommand("Set_Game_Result", myCon))   
                {   
                    myCommand.CommandType = CommandType.StoredProcedure;   
                    myCommand.Parameters.AddWithValue("@user1_res", us1);   
                    myCommand.Parameters.AddWithValue("@user2_res", us2);   

                    myReader = myCommand.ExecuteReader();   

                    table.Load(myReader);   
                    myReader.Close();   

                    if (table.Rows.Count > 0)   
                    {   
                        var JsonResoltString = JsonConvert.SerializeObject(table);   

                        return JsonResoltString;   
                    }   

                    return "No data sent and table returned empty";   
                }   
            }   
        }   
        catch (SqlException ex)   
        {   
            return "Inner Exception: " + ex.Message;   
        }   
        catch (Exception ex)   
        {   
            return $"Outer Exception: " + ex.Message;   
        }   
    }   

    return "No data sent";   
}   

React Native

  let data= {   
    us1: gameResult.us1Win,   
    us2: gameResult.us2Win,   
  };   
 const fetchResponse = await fetch(URL, {   
  body: JSON.stringify(data),   
  method: 'POST',   
  headers: {   
    Accept: 'application/json',   
    'Content-type': 'application/json; charset=UTF-8',   
  },   
});   
const data = await fetchResponse.json();   

Be glad for some explanations about that, thanks.

ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,164 questions
SQL Server
SQL Server
A family of Microsoft relational database management and analysis systems for e-commerce, line-of-business, and data warehousing solutions.
12,711 questions
ASP.NET API
ASP.NET API
ASP.NET: A set of technologies in the .NET Framework for building web applications and XML web services.API: A software intermediary that allows two applications to interact with each other.
294 questions
{count} votes

1 answer

Sort by: Most helpful
  1. AgaveJoe 26,201 Reputation points
    2022-10-05T11:31:43.667+00:00

    The SetGameResults action is designed to accept querystring parameters but your React code sends the parameters in the message body (HTTP POST).

    The standard is passing an object to a Web API Post action not querystring parameters. I recommend learning model binding and Web API fundamentals rather than guessing how Web API works.

    Model Binding in ASP.NET Core

    Example action:

    [HttpPost]  
    [Route("SetGameResults")]  
    public string SetGameResults(DtoData data)  
    {  
        if (!(data.us1 >= 1 && data.us2 >= 1))    
        {  
            return $"IF -- us1:{data.us1} us2:{data.us2}";  
        }  
        return $"us1:{data.us1} us2:{data.us2}";  
    }  
    

    Example object:

        public class DtoData  
        {  
            public byte? us1 { get; set; }  
            public byte? us2 { get; set; }  
        }  
    

    Lastly, I question the nullable parameter design and general logic since there's no null checks. The code checks for both values NOT being greater than or equal to one but not null. If null is passed then the same missing parameter exception will fire. It seems to me that you need to rethink the approach. At least simplify the logic.

    I would do this check in the React application. Only send the HTTP request if us1 and us2 are zero which is ultimately how the logic is designed. Correct?

    Nullable value types (C# reference)

    2 people found this answer helpful.