我想让我的.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'."
}
当我的帖子功能签名如下所示时会发生这种情况:
public string Post([FromUri]string payload)
{
var hookEvent = JsonConvert.DeserializeObject<HookEvent>(payload);
....
或 public string Post(字符串有效负载) { var hookEvent = JsonConvert.DeserializeObject(payload); ....
当我这样做时:
public string Post([FromUri]HookEvent 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)"
我知道我的&#39; HookEvent&#39;正确反序列化,因为如果更改PostMan以将有效负载作为请求主体发送,则对象将被正确反序列化,并设置所有字段。不幸的是,BB并没有以这种方式发送有效载荷,而是作为后置参数发送。
我的控制器签名是:
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);
如何让我的控制器接受邮件有效负载?
答案 0 :(得分:0)
我能够提交的最佳解决方案是使用容器模型。
public class HookEventContainer
{
public string payload { get; set; }
public HookEvent HookEvent {
get
{
if (string.IsNullOrEmpty(payload))
{
return null;
}
return JsonConvert.DeserializeObject<HookEvent>(payload);
}
}
}
然后将此用于我的帖子签名:
// POST api/<controller>
//
public string Post(HookEventContainer eventData)
{
var hookEvent = eventData.HookEvent;
丑陋但它有效。
我还向Bitbucket发送了一个请求,以找出他们选择将有效负载作为参数而不是请求体发送的原因。由于Atlassian买了它们,但它们并不是那么敏感......