What is the simplest way to read a long json string (not via query string) from ASP.NET Core minimal Web API MapPost
and pass it to ADO.NET as parameters for a stored procedure?
CodePudding user response:
According to your description, I suggest you could try to create a model according to the json and then you could use sql client to call the SP.
More details, you could refer to below codes:
Model:
public class Todo
{
public string name { get; set; }
public int id { get; set; }
}
Minimal API
app.MapPost("/todoitems", async (Todo todo) =>
{
using (SqlConnection con = new SqlConnection("connection string"))
{
using (SqlCommand cmd = new SqlCommand("sp_Add_contact", con))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@FirstName", SqlDbType.VarChar).Value = todo.id;
cmd.Parameters.Add("@LastName", SqlDbType.VarChar).Value = todo.name;
con.Open();
cmd.ExecuteNonQuery();
return Results.Created($"/todoitems/{todo.id}", todo);
}
}
});
You could directly read the json from the httprequest.
More details, you could refer to below codes:
app.MapPost("/", async (HttpRequest request) =>
{
var person = await request.ReadFromJsonAsync<Person>();
// ...
});
CodePudding user response:
I tried it 4 different ways with the following results:
json1: success in Postman; error 415 from jQuery no responseText
json2: success in Postman and from jQuery. Works consistently
json3: success in Postman; error 400 from jQuery error Microsoft.AspNetCore.Http.BadHttpRequestException: Failed to read parameter "JsonRec jsonObj" from the request body as JSON.
json4: success in Postman; error 500 from jQuery error System.Text.Json.JsonException: 'j' is an invalid start of a value. Path: $ | LineNumber: 0 | BytePositionInLine: 0.
The code below should be enough to reproduce the errors. All MapPost snippets go in Program.cs of an asp.net core web app/api. The jQuery is called as usual from an html file. You could replace ops.spPostJson with a local stub function. Errors are produced on the client side, before this call.
app.MapPost("/json1", ([FromBody] string jsonStr) =>
{
return ops.spPostJson("dbo.sp_postJson", jsonStr);
});
app.MapPost("/json2", async (HttpRequest request) =>
{
string body = "";
using (StreamReader stream = new StreamReader(request.Body))
{
body = await stream.ReadToEndAsync();
}
return ops.spPostJson("dbo.sp_postJson", HttpUtility.UrlDecode(body));
});
for json3 and json4: record JsonRec(object json);
app.MapPost("/json3", async (JsonRec jsonObj) =>
{
return ops.spPostJson("dbo.sp_postJson", jsonObj.json.ToString());
});
app.MapPost("/json4", async (HttpRequest request) =>
{
var jsonObj = await request.ReadFromJsonAsync<JsonRec>();
return ops.spPostJson("dbo.sp_postJson", jsonObj.ToString().Substring(5));
});
The jQuery code (json1 and json2 had contentType: text/plain):
var jsonObj = { "a": 44, "b": 55 };
var jsonObjStr = JSON.stringify(jsonObj);
$.ajax({
url: '/json3',
type: "POST",
dataType: "json",
contentType: "application/json; charset=utf-8",
data: {
json: jsonObjStr
},
success: function (returnedData, textStatus, jqXhr) {
console.log('json3 success', returnedData)
},
error: function (response, textStatus, jqXhr) {
console.log('json3 error', response.responseText);
}
});
It is quite frustrating to go through all that trouble just to read the request body; worse off now than decades ago! Try a C!# equivalent of JSON.stringify or parse. Is that missing the obvious or what?