gpt4 book ai didi

c# - WebAPI 发布 JSON 字符串并将其映射到模型

转载 作者:行者123 更新时间:2023-11-30 16:01:40 25 4
gpt4 key购买 nike

我必须创建将使用 JSON 消息的 webhook 端点。
消息以 x-www-form-urlencoded 格式发送:

key = json
value = {"user_Id": "728409840", "call_id": "1114330","answered_time": "2015-04-16 15:37:47"}

如PostMan所示:

enter image description here

请求看起来像这样:

json=%7B%22user_Id%22%3A+%22728409840%22%2C+%22call_id%22%3A+%221114330%22%2C%22answered_time%22%3A+%222015-04-16+15%3A37%3A47%22%7D

要从请求中获取值作为我的类(模型),我必须创建包含单个字符串属性的临时对象:

public class Tmp
{
public string json { get; set; }
}

以及我的 Controller 中使用该请求的方法:

[AllowAnonymous]
[Route("save_data")]
[HttpPost]
public IHttpActionResult SaveData(Tmp tmp)
{
JObject json2 = JObject.Parse(tmp.json);
var details = json2.ToObject<CallDetails>();
Debug.WriteLine(details);
//data processing
return Content(HttpStatusCode.OK, "OK", new TextMediaTypeFormatter(), "text/plain");
}

如您所见,Tmp 类是无用的。

有没有办法像这个类一样获取请求数据:

public class CallDetails
{
public string UserId { get; set; }
public string CallId { get; set; }
public string AnsweredTime { get; set; }
}

我知道 IModelBinder 类,但在开始之前我想知道是否有更简单的方法。

我无法更改网络请求格式,格式我的意思是始终是包含单个键的 POST - JSON yhat 具有 json 字符串作为值。

最佳答案

您可以使用 JsonProperty 属性将 json 对象属性映射到 c# 对象属性:

public class CallDetails
{
[JsonProperty("user_id")]
public string UserId { get; set; }
[JsonProperty("call_id")]
public string CallId { get; set; }
[JsonProperty("answered_time")]
public string AnsweredTime { get; set; }
}

然后它可以在没有临时类的情况下使用:

[AllowAnonymous]
[Route("save_data")]
[HttpPost]
public IHttpActionResult SaveData(CallDetails callDetails)

更新。因为数据是作为 x-www-form-urlencoded 发送的 - 我认为您处理它的方式是最直接的,而且还不错。如果您想检查其他选项,这里有一些:

选项 1 - 自定义模型 Binder 。像这样:

public class CustomModelBinder : IModelBinder
{
public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
{
var body = actionContext.Request.Content.ReadAsStringAsync().Result;
body = body.Replace("json=", "");
var json = HttpUtility.UrlDecode(body);

bindingContext.Model = JsonConvert.DeserializeObject<CallDetails>(json);

return true;
}
}

和用法:SaveData([ModelBinder(typeof(CustomModelBinder))]CallDetails callDetails)。缺点 - 您将失去验证以及可能在 web api 管道中定义的其他内容。

选项 2 - DelegatingHandler

public class NormalizeHandler : DelegatingHandler
{
public NormalizeHandler(HttpConfiguration httpConfiguration)
{
InnerHandler = new HttpControllerDispatcher(httpConfiguration);
}

protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var source = await request.Content.ReadAsStringAsync();
source = source.Replace("json=", "");
source = HttpUtility.UrlDecode(source);

request.Content = new StringContent(source, Encoding.UTF8, "application/json");

return await base.SendAsync(request, cancellationToken);
}
}

用法:

[AllowAnonymous]
[HttpPost]
public IHttpActionResult SaveData(CallDetails callDetails)

缺点 - 您需要为其定义自定义路由:

config.Routes.MapHttpRoute(
name: "save_data",
routeTemplate: "save_data",
defaults: new { controller = "YourController", action = "SaveData" },
constraints: null,
handler: new NormalizeHandler(config)
);

关于c# - WebAPI 发布 JSON 字符串并将其映射到模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38439194/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com