ASP.NET Core 最小 Web API:如何从请求正文读取 json 字符串并将其传递给 SQL Server 存储过程?

W. *_*ema 5 sql-server asp.net-core

从 ASP.NET Core 最小 Web API 读取长 json 字符串(不是通过查询字符串)MapPost并将其作为存储过程的参数传递给 ADO.NET 的最简单方法是什么?

W. *_*ema 6

我尝试了 4 种不同的方法,结果如下:

json1: Postman 成功;jQuery 的错误 415 无响应文本


json2: Postman 和 jQuery 的成功。始终如一地工作


json3: Postman 成功;jQuery 错误 Microsoft.AspNetCore.Http.BadHttpRequestException 中的错误 400:无法从请求正文中以 JSON 形式读取参数“JsonRec jsonObj”。


json4: Postman 成功;来自 jQuery 错误 System.Text.Json.JsonException 的错误 500:“j”是值的无效开头。路径: $ | 行号: 0 | 内联字节位置:0。


下面的代码应该足以重现错误。所有MapPost片段都位于 asp.net core Web 应用程序/api 的 Program.cs 中。像往常一样从 html 文件调用 jQuery。您可以将ops.spPostJson替换为本地存根函数。在此调用之前,客户端会产生错误。

app.MapPost("/json1", ([FromBody] string jsonStr) =>
{
  return ops.spPostJson("dbo.sp_postJson", jsonStr);
});
Run Code Online (Sandbox Code Playgroud)
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));    
});
Run Code Online (Sandbox Code Playgroud)

对于 json3 和 json4:记录 JsonRec(object json);

app.MapPost("/json3", async (JsonRec jsonObj) =>
{
  return ops.spPostJson("dbo.sp_postJson", jsonObj.json.ToString());
});
Run Code Online (Sandbox Code Playgroud)
app.MapPost("/json4", async (HttpRequest request) =>
{
  var jsonObj = await request.ReadFromJsonAsync<JsonRec>();
  return ops.spPostJson("dbo.sp_postJson", jsonObj.ToString().Substring(5));
});
Run Code Online (Sandbox Code Playgroud)

jQuery 代码(json1 和 json2 的 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);
  }
});
Run Code Online (Sandbox Code Playgroud)

仅仅为了读取请求正文就经历这些麻烦是相当令人沮丧的;现在比几十年前还惨!尝试使用 C!# 相当于 JSON.stringify 或 parse 的方法。这是缺少明显的东西还是什么?


Bra*_*ang 3

根据你的描述,我建议你可以尝试根据json创建一个模型,然后使用sql客户端调用SP。

更多详细信息,您可以参考以下代码:

模型:

public class Todo
{
    public string name { get; set; }
    public int id { get; set; }

}
Run Code Online (Sandbox Code Playgroud)

最小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);
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

您可以直接从 httprequest 中读取 json。

更多详细信息,您可以参考以下代码:

app.MapPost("/", async (HttpRequest request) =>
{
    var person = await request.ReadFromJsonAsync<Person>();

    // ...
});
Run Code Online (Sandbox Code Playgroud)