ASP.NET MVC 5 - JSON -(动态?)模型绑定 - REST 服务 - Webhooks - Chargebee
ASP.NET MVC 5 - JSON - (Dynamic?) Model Binding - REST services - Webhooks - Chargebee
这应该很容易,但我卡住了。我已经使用服务 (ChargeBee) 设置了一个 webhook,该服务成功发布了我的网站 JSON。这是我要绑定的模型:
public class ChargeBeeWebhookModel
{
public string id { get; set; }
public string occurred_at { get; set; }
public string source { get; set; }
public string @object { get; set; }
public string content { get; set; }
public string event_type { get; set; }
public string webhook_status { get; set; }
}
除了 "content" 之外的所有内容都具有约束力,它是空的。问题是 "content" 会根据触发的事件类型而改变。例如,对于 "customer created" 事件,它可能是这样的:
"customer": {
"id": "8avVGOkx8U1MX",
"first_name": "Benjamin",
"last_name": "Ross",
"email": "Benjamin@test.com",
"auto_collection": "on",
"created_at": 1317407411,
"object": "customer",
"card_status": "valid",
"payment_method": {
"object": "payment_method",
"type": "card",
"gateway": "chargebee",
"reference_id": "tok_KyVr8xPHl5BSx1",
"status": "valid"
},
"account_credits": 0
},
"card": {
"customer_id": "8avVGOkx8U1MX",
"status": "valid",
"gateway": "chargebee",
"iin": "411111",
"last4": "1111",
"card_type": "visa",
"expiry_month": 1,
"expiry_year": 2016,
"object": "card",
"masked_number": "************1111"
}
我只需要将这些复杂对象绑定到某种类型。字符串不工作。绑定后,我可以使用 event_type 属性 轻松检查它是否是我要处理的事件,并将其反序列化为适当的自定义类型。
我该怎么做?我觉得我错过了一些非常简单的东西。据我所知,Chargebee 不会让我为每种类型的事件设置不同的 URL,这是我认为最有意义的。这是一个 URL,我必须绑定许多可能的响应。
我需要自定义模型活页夹吗?有没有更简单的方法?
也许有人可以制作一个 ChargeBee 标签?
谢谢大家
编辑:
根据要求,示例请求如下所示:
Headers
POST HTTP/1.1
Host:********.ngrok.io //(obviously I commented this out)
Authorization: Basic cGF0cmlvdGN5YmVybmV0aWNzZHJvbmVtYXN0ZXI6c3VuZGV2aWxjb2NvYXJhZ2luZ2J1bGw=
Content-Type: application/json; charset=utf-8
User-Agent: ChargeBee
Body
{
"id": "ev_3Nl8ERLPElBCRU6",
"occurred_at": 1341167306,
"source": "admin_console",
"object": "event",
"content": {
"subscription": {
"id": "3Nl8ERLPElBCGl1",
"plan_id": "basic",
"plan_quantity": 1,
"status": "future",
"start_date": 1341772105,
"trial_start": 1341772105,
"trial_end": 1344450505,
"created_at": 1341167305,
"has_scheduled_changes": false,
"object": "subscription",
"addons": [{
"id": "data_usage",
"quantity": 1,
"object": "addon"
}],
"due_invoices_count": 0
},
"customer": {
"id": "3Nl8ERLPElBCGl1",
"first_name": "Benjamin",
"last_name": "Ross",
"email": "Benjamin@test.com",
"auto_collection": "on",
"created_at": 1341167305,
"object": "customer",
"card_status": "valid",
"payment_method": {
"object": "payment_method",
"type": "card",
"reference_id": "3Nl8ERLPElBCGl1",
"status": "valid"
}
}
},
"event_type": "subscription_created",
"webhook_status": "not_configured"
}
除非我弄错了,否则我认为模型绑定器无法处理这种情况。据我所知,它需要预定义的类型并且不能处理可变性或动态的东西。如果我错了,请纠正我。不管怎样,我稍后会用完整的代码示例来回答这个问题,但现在我已经放弃了纯模型绑定方法,正在阅读 Request.InputStream 来获取我需要的 JSON 数据。然后,根据模型绑定器没有问题的 event_type,我将反序列化为我的预定义类型。只是我以前从来没有真正需要手动从请求中挑选一些东西;我一直用模型活页夹。
好的,下面应该可以工作。不要为内容传递 Javascript 对象,而是对您的对象使用 JSON.stringify 并将其结果设置为内容。这样,在您的控制器中,内容的值将是一个字符串。
这就是我想要实现的目标。 Request.InputStream 是必经之路;我开始尝试手动执行此操作,但幸运的是 ChargeBee 有一个官方 .NET 库(与 Mandrill 不同)可以为我完成所有操作:
[HttpPost]
[BasicAuthentication(username: "x", password: "y", BasicRealm = "z")]
public HttpStatusCodeResult ChargeBeeWebhook()
{
if (ModelState.IsValid)
{
Event chargeBeeEvent = new Event(Request.InputStream);
EventTypeEnum? eventType = chargeBeeEvent.EventType;
Event.EventContent eventContent = chargeBeeEvent.Content;
if (eventType == EventTypeEnum.SubscriptionCreated)
{
Subscription subscription = eventContent.Subscription;
Customer customer = eventContent.Customer;
// more stuff
}
return new HttpStatusCodeResult(200);
}
else
{
return new HttpStatusCodeResult(400); // bad request
}
}
这应该很容易,但我卡住了。我已经使用服务 (ChargeBee) 设置了一个 webhook,该服务成功发布了我的网站 JSON。这是我要绑定的模型:
public class ChargeBeeWebhookModel
{
public string id { get; set; }
public string occurred_at { get; set; }
public string source { get; set; }
public string @object { get; set; }
public string content { get; set; }
public string event_type { get; set; }
public string webhook_status { get; set; }
}
除了 "content" 之外的所有内容都具有约束力,它是空的。问题是 "content" 会根据触发的事件类型而改变。例如,对于 "customer created" 事件,它可能是这样的:
"customer": {
"id": "8avVGOkx8U1MX",
"first_name": "Benjamin",
"last_name": "Ross",
"email": "Benjamin@test.com",
"auto_collection": "on",
"created_at": 1317407411,
"object": "customer",
"card_status": "valid",
"payment_method": {
"object": "payment_method",
"type": "card",
"gateway": "chargebee",
"reference_id": "tok_KyVr8xPHl5BSx1",
"status": "valid"
},
"account_credits": 0
},
"card": {
"customer_id": "8avVGOkx8U1MX",
"status": "valid",
"gateway": "chargebee",
"iin": "411111",
"last4": "1111",
"card_type": "visa",
"expiry_month": 1,
"expiry_year": 2016,
"object": "card",
"masked_number": "************1111"
}
我只需要将这些复杂对象绑定到某种类型。字符串不工作。绑定后,我可以使用 event_type 属性 轻松检查它是否是我要处理的事件,并将其反序列化为适当的自定义类型。
我该怎么做?我觉得我错过了一些非常简单的东西。据我所知,Chargebee 不会让我为每种类型的事件设置不同的 URL,这是我认为最有意义的。这是一个 URL,我必须绑定许多可能的响应。
我需要自定义模型活页夹吗?有没有更简单的方法?
也许有人可以制作一个 ChargeBee 标签?
谢谢大家
编辑:
根据要求,示例请求如下所示:
Headers
POST HTTP/1.1
Host:********.ngrok.io //(obviously I commented this out)
Authorization: Basic cGF0cmlvdGN5YmVybmV0aWNzZHJvbmVtYXN0ZXI6c3VuZGV2aWxjb2NvYXJhZ2luZ2J1bGw=
Content-Type: application/json; charset=utf-8
User-Agent: ChargeBee
Body
{
"id": "ev_3Nl8ERLPElBCRU6",
"occurred_at": 1341167306,
"source": "admin_console",
"object": "event",
"content": {
"subscription": {
"id": "3Nl8ERLPElBCGl1",
"plan_id": "basic",
"plan_quantity": 1,
"status": "future",
"start_date": 1341772105,
"trial_start": 1341772105,
"trial_end": 1344450505,
"created_at": 1341167305,
"has_scheduled_changes": false,
"object": "subscription",
"addons": [{
"id": "data_usage",
"quantity": 1,
"object": "addon"
}],
"due_invoices_count": 0
},
"customer": {
"id": "3Nl8ERLPElBCGl1",
"first_name": "Benjamin",
"last_name": "Ross",
"email": "Benjamin@test.com",
"auto_collection": "on",
"created_at": 1341167305,
"object": "customer",
"card_status": "valid",
"payment_method": {
"object": "payment_method",
"type": "card",
"reference_id": "3Nl8ERLPElBCGl1",
"status": "valid"
}
}
},
"event_type": "subscription_created",
"webhook_status": "not_configured"
}
除非我弄错了,否则我认为模型绑定器无法处理这种情况。据我所知,它需要预定义的类型并且不能处理可变性或动态的东西。如果我错了,请纠正我。不管怎样,我稍后会用完整的代码示例来回答这个问题,但现在我已经放弃了纯模型绑定方法,正在阅读 Request.InputStream 来获取我需要的 JSON 数据。然后,根据模型绑定器没有问题的 event_type,我将反序列化为我的预定义类型。只是我以前从来没有真正需要手动从请求中挑选一些东西;我一直用模型活页夹。
好的,下面应该可以工作。不要为内容传递 Javascript 对象,而是对您的对象使用 JSON.stringify 并将其结果设置为内容。这样,在您的控制器中,内容的值将是一个字符串。
这就是我想要实现的目标。 Request.InputStream 是必经之路;我开始尝试手动执行此操作,但幸运的是 ChargeBee 有一个官方 .NET 库(与 Mandrill 不同)可以为我完成所有操作:
[HttpPost]
[BasicAuthentication(username: "x", password: "y", BasicRealm = "z")]
public HttpStatusCodeResult ChargeBeeWebhook()
{
if (ModelState.IsValid)
{
Event chargeBeeEvent = new Event(Request.InputStream);
EventTypeEnum? eventType = chargeBeeEvent.EventType;
Event.EventContent eventContent = chargeBeeEvent.Content;
if (eventType == EventTypeEnum.SubscriptionCreated)
{
Subscription subscription = eventContent.Subscription;
Customer customer = eventContent.Customer;
// more stuff
}
return new HttpStatusCodeResult(200);
}
else
{
return new HttpStatusCodeResult(400); // bad request
}
}