【发布时间】:2023-03-18 04:03:02
【问题描述】:
我正在尝试让我的 .Net WebApi 2.2 接受来自 bitbucket 的帖子。但是 BB 不会将其数据作为正文发布,而是作为发布参数发布。
我在这里使用 PostMan 模拟了 bitbucket 发送的内容: http://www.posttestserver.com/data/2014/11/05/shea/22.05.091712543622
您可以在此处导入 PostMan 集合:https://www.getpostman.com/collections/ec562c5141d85fe7b850
当我尝试发布到我的 ApiController 时,我得到了
{
"Message": "The requested resource does not support http method 'POST'."
}
当我的 post 函数签名如下所示时会发生这种情况:
public string Post([FromUri]string payload)
{
var hookEvent = JsonConvert.DeserializeObject<HookEvent>(payload);
....
或 公共字符串帖子(字符串有效负载) { var hookEvent = JsonConvert.DeserializeObject(payload); ....
当我这样做时:
public string Post([FromUri]HookEvent payload)
{
....
payload 不为空,但其中的所有字段均为空。
public string Post(HookEvent payload)
{
给出这个错误:
"Message": "The request contains an entity body but no Content-Type header. The inferred media type 'application/octet-stream' is not supported for this resource.",
"ExceptionMessage": "No MediaTypeFormatter is available to read an object of type 'HookEvent' from content with media type 'application/octet-stream'.",
"ExceptionType": "System.Net.Http.UnsupportedMediaTypeException",
"StackTrace": " at System.Net.Http.HttpContentExtensions.ReadAsAsync[T](HttpContent content, Type type, IEnumerable`1 formatters, IFormatterLogger formatterLogger, CancellationToken cancellationToken)\r\n at System.Net.Http.HttpContentExtensions.ReadAsAsync(HttpContent content, Type type, IEnumerable`1 formatters, IFormatterLogger formatterLogger, CancellationToken cancellationToken)\r\n at System.Web.Http.ModelBinding.FormatterParameterBinding.ReadContentAsync(HttpRequestMessage request, Type type, IEnumerable`1 formatters, IFormatterLogger formatterLogger, CancellationToken cancellationToken)"
我知道我的“HookEvent”正在正确反序列化,因为如果更改 PostMan 以将有效负载作为请求正文发送,则对象会正确反序列化,并设置所有字段。不幸的是,BB 不会以这种方式发送有效负载,而是作为 post 参数发送。
我的控制器签名是:
public class BitbucketHookController : ApiController
{
....
其他路由位:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
}
}
和 Global.asax.cs 中的 Application_Start()
DiConfig.Register();
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
我必须做什么才能让我的控制器接受 post 有效负载?
【问题讨论】:
-
思考1,在第一个没有返回方法帖子的方法上,你能不能用
[HttpPost]属性来装饰它——看看我们能不能强迫它捡起帖子。 -
思想 2,在您的模型具有空值的方法中 - 您可以检查原始请求以查看正在传递的内容以及传递方式。您可以使用
var req = Request.Content.ReadAsByteArrayAsync()之类的方式访问原始请求 -
重新思考1:添加装饰并没有改变结果,我仍然得到一个请求的资源不支持http方法'POST'。
-
重新思考 2:我使用了 Request.Content.ReadAsStringAsync();保存之后将数据转换为字符串。此调用返回的 Result 字段包含字符串“payload=%7B+++++%22canon_url%22%3A+%22https%3........”,这是 urlendcoded json 有效负载。如果我将该值放在 urldecoder 中,它将变为:“payload={“canon_url”:“https:.......”。我的意思是我想我可以手动剥离 payload=,然后手动反序列化 JSON ,但为什么 ApiController 没有发挥它的魔力。
-
并且注册了 JSON 序列化器?
configuration.Formatters.Add(new JsonMediaTypeFormatter());?
标签: .net asp.net-web-api-routing asp.net-apicontroller