github can alert you and call your webservice when commits are pushed to a repository (Post-Receive Hooks). github sends the commit information as JSON but inside a form encoded parameter. That is, the content type is application/x-www-form-urlencoded and the http request is
当提交被推送到存储库(后接收挂钩)时,github可以提醒您并调用您的Web服务。 github将提交信息作为JSON发送,但在表单编码参数内。也就是说,内容类型是application / x-www-form-urlencoded并且http请求是
POST /my_uri HTTP/1.1
Content-Type: application/x-www-form-urlencoded
payload=%7B%22ref%22%3A%22refs%2Fheads...
I want to write the webservice that processes the new commits in ASP.NET MVC or WebAPI. I've defined some classes to deserialize the json, but I can't get the framework to initialize my objects directly. What I have now is
我想编写处理ASP.NET MVC或WebAPI中新提交的web服务。我已经定义了一些类来反序列化json,但我无法让框架直接初始化我的对象。我现在拥有的是什么
public string my_uri(string payload)
{
var s = new JavaScriptSerializer();
var p = s.Deserialize(payload, typeof(Payload)) as Payload;
...
}
but I would want
但我想要
public string my_uri(Payload payload)
{
...
}
I've read about ValueProviders but I didn't find a way to chain them. I need to compose FormValueProviderFactory and JsonValueProviderFactory. How can I get ASP to do the binding?
我读过有关ValueProviders但我找不到链接它们的方法。我需要编写FormValueProviderFactory和JsonValueProviderFactory。如何让ASP进行绑定?
1 个解决方案
#1
1
First, I am a bit confused as to why they would stuff Json data in form-encoded body data. If a service in the end can understand Json(since it has to deserialize it), why not post as "application/json" itself? Is it because of CORS that they are doing this way?
首先,我有点困惑为什么他们会在表单编码的正文数据中填充Json数据。如果一个服务最终可以理解Json(因为它必须反序列化它),为什么不发布为“application / json”本身呢?是因为CORS他们这样做吗?
That aside, you could create a custom parameter binding like below and see if it fits your needs:
除此之外,您可以创建一个自定义参数绑定,如下所示,看看它是否符合您的需求:
Action:
行动:
public Payload Post([PayloadParamBinding]Payload payload)
Custom Parameter Binding:
自定义参数绑定:
public class PayloadParamBindingAttribute : ParameterBindingAttribute
{
public override HttpParameterBinding GetBinding(HttpParameterDescriptor parameter)
{
return new PayloadParamBinding(parameter);
}
}
public class PayloadParamBinding : HttpParameterBinding
{
HttpParameterBinding _defaultFormatterBinding;
public PayloadParamBinding(HttpParameterDescriptor desc)
:base(desc)
{
_defaultFormatterBinding = new FromBodyAttribute().GetBinding(desc);
}
public override async Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken)
{
if (actionContext.Request.Content != null)
{
NameValueCollection nvc = await actionContext.Request.Content.ReadAsFormDataAsync();
StringContent sc = new StringContent(nvc["payload"]);
//set the header so that Json formatter comes into picture
sc.Headers.ContentType = new MediaTypeHeaderValue("application/json");
actionContext.Request.Content = sc;
//Doing like this here because we want to simulate the default behavior of when a request
//is posted as Json and the Json formatter would have been picked up and also the model validation is done.
//This way you are simulating the experience as of a normal "application/json" post request.
await _defaultFormatterBinding.ExecuteBindingAsync(metadataProvider, actionContext, cancellationToken);
}
}
public override bool WillReadBody
{
get
{
return true;
}
}
}
#1
1
First, I am a bit confused as to why they would stuff Json data in form-encoded body data. If a service in the end can understand Json(since it has to deserialize it), why not post as "application/json" itself? Is it because of CORS that they are doing this way?
首先,我有点困惑为什么他们会在表单编码的正文数据中填充Json数据。如果一个服务最终可以理解Json(因为它必须反序列化它),为什么不发布为“application / json”本身呢?是因为CORS他们这样做吗?
That aside, you could create a custom parameter binding like below and see if it fits your needs:
除此之外,您可以创建一个自定义参数绑定,如下所示,看看它是否符合您的需求:
Action:
行动:
public Payload Post([PayloadParamBinding]Payload payload)
Custom Parameter Binding:
自定义参数绑定:
public class PayloadParamBindingAttribute : ParameterBindingAttribute
{
public override HttpParameterBinding GetBinding(HttpParameterDescriptor parameter)
{
return new PayloadParamBinding(parameter);
}
}
public class PayloadParamBinding : HttpParameterBinding
{
HttpParameterBinding _defaultFormatterBinding;
public PayloadParamBinding(HttpParameterDescriptor desc)
:base(desc)
{
_defaultFormatterBinding = new FromBodyAttribute().GetBinding(desc);
}
public override async Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken)
{
if (actionContext.Request.Content != null)
{
NameValueCollection nvc = await actionContext.Request.Content.ReadAsFormDataAsync();
StringContent sc = new StringContent(nvc["payload"]);
//set the header so that Json formatter comes into picture
sc.Headers.ContentType = new MediaTypeHeaderValue("application/json");
actionContext.Request.Content = sc;
//Doing like this here because we want to simulate the default behavior of when a request
//is posted as Json and the Json formatter would have been picked up and also the model validation is done.
//This way you are simulating the experience as of a normal "application/json" post request.
await _defaultFormatterBinding.ExecuteBindingAsync(metadataProvider, actionContext, cancellationToken);
}
}
public override bool WillReadBody
{
get
{
return true;
}
}
}