How to get Chargify Webhook Response in .Net - webhooks

I have already configure webhook url in chargify. This url is for webapi.
So i'm handling all events in webapi. But I want to know that how can we get the request parameter from chargify. If anyone have an example, would you please give me.
Below is the request from the chargify webhook's one event
you can get the below link for the webhook sending request for the events.
https://docs.chargify.com/webhooks#signup-success-payload
Please help me on this.
Thanks in Advance.

I tried the solution from above but it didn't work for me (probably because it's a 2015 solution and Chargify has made a few changes in the time).
What worked for me was:
[HttpPost]
[Route("test")]
[Consumes("application/x-www-form-urlencoded")]
public ActionResult Test([FromForm] RequestObject request)
If we will use RequestObject with ModelBinding, we have to create the data structure of the objects and variables we want to use.
For instance, for the signup_success event, the data structure for the objects Product, Customer and Customer Reference will be:
public class RequestObject
{
public string id { get; set; }
public Payload payload { get; set; }
}
public class Payload
{
public Subscription subscription { get; set; }
}
public class Subscription
{
public long id { get; set; }
public Product product { get; set; }
public Customer customer { get; set; }
}
public class Product
{
public long id { get; set; }
}
public class Customer
{
public long id { get; set; }
public string reference { get; set; }
}

Since it's submitted to the webhook url as form-parameters, so in MVC your signature would look similar to the following:
public ActionResult ReceiveWebhook(FormCollection webhookPayload, string signature_hmac_sha_256)
The parameter signature_hmac_sha_256 is included in the query string, so it's passed here.
You could then run different logic by using the event:
var eventName = webhookPayload["event"];

Related

Can AutoQuery return a single item (not list)

When I add a type to AutoQuery, with:
[Route("/templates")]
public class SearchTemplates : QueryDb<Template>
{
public int? Id { get; set; }
public string Name { get; set; }
}
then I can query this object by Id or Name (or whatever other attributes I would add, that the POCO Template has). However it always returns list of items.
It's very useful to be able to GET a single item (not a search result).
This is how I do it:
[Route("/template/{Id}","GET")]
public class SingleTemplate : IReturn<Template>
{
public int Id { get; set; }
}
public Template Get(SingleTemplate request)
{
return Db.LoadSingleById<Template>(request.Id);
}
With all the new AutoQuery and AutoCRUD, it seems to me that the "return a single item by its URL" could also be automatic?
No, All AutoQuery QueryDb<T> services return the same fixed QueryResponse Response DTO as per its Service Contract, i.e:
public abstract class QueryDb<T>
: QueryBase, IQueryDb<T>, IReturn<QueryResponse<T>> { }
public abstract class QueryDb<From, Into>
: QueryBase, IQueryDb<From, Into>, IReturn<QueryResponse<Into>> { }
public class QueryResponse<T> : IQueryResponse
{
public virtual int Offset { get; set; }
public virtual int Total { get; set; }
public virtual List<T> Results { get; set; }
public virtual Dictionary<string, string> Meta { get; set; }
public virtual ResponseStatus ResponseStatus { get; set; }
}
A single result would still populate the Results property, so the JSON wire format would look like:
{ "results":[ {/*Template*/} ] }
You could create your own Custom AutoQuery Implementation that utilizes AutoQuery's IAutoQueryDb API to return your own custom populated DTO but then your Request DTO should NOT inherit from QueryDb<T> as not returning a QueryResponse<T> would break the explicit Service contract of the Request DTO (and all clients expecting it), i.e. you would instead just create a normal ServiceStack Service returning your own custom Response Type.

ServiceStack "Handler for request not found" when it is working for dozens of similar DTOs

I have been using ServiceStack for months now. It has been working great for awhile and I've used many advanced approaches and Redis integration. I have a license, so my issue is not regarding a license issue, but I wonder if it is related. It almost looks like I have hit a maximum of DTO or paths, but I do not get any such error, simply the "Handler for request not found". So here is my question: how can you debug and isolate this error? I have read all the posts I can find on proper formats for DTO and DTO filters and I have been doing this long enough that I can see nothing wrong in this regard. Identically styled DTO's and paths work, but new ones fail, or so it seems. Even if I find there is something I am doing wrong in my DTO setup, the question remains, is there a way to debug this? Of course, finding what I'm doing wrong, if that is the case, is the first question.
Here is my code, AppHost first:
.Add<UsersCredentials>("/userscredentials", "GET")
.Add<UserCredential>("/userscredentials", "DELETE")
.Add<UserCredential>("/userscredentials/{UserName}", "POST PUT DELETE")
.Add<UserCredential("/userscredentials/{UserName}/(Permissions}/{System}/{ParamSet}/{Instrument}/{Interval}", "POST PUT DELETE")
DTO:
[Route("/userscredentials", "GET")]
public class UsersCredentials : IReturn<UsersCredentials>
{
public string UserName { get; set; }
public string Permissions { get; set; }
public string System { get; set; }
public uint ParamSet { get; set; }
public string Instrument { get; set; }
public uint Interval { get; set; }
} //Request DTO
[Route("/userscredentials", "DELETE")]
[Route("/userscredentials/{UserName}", "POST PUT DELETE")]
[Route("/userscredentials/{UserName}/(Permissions}/{System}/{ParamSet}/{Instrument}/{Interval}", "POST PUT DELETE")]
public class UserCredential : IReturn<UserCredential>
{
public string UserName { get; set; }
public string Permissions { get; set; }
public string System { get; set; }
public uint ParamSet { get; set; }
public string Instrument { get; set; }
public uint Interval { get; set; }
} //Request DTO
And Service:
// UsersCredentials
public class UsersCredentialsResponse
{
public string Result { get; set; }
public ResponseStatus ResponseStatus { get; set; } //Where Exceptions get auto-serialized
}
public class UsersCredentialsService : Service
{
private bool init = false;
public object Get(UsersCredentials request)
{
return (request);
}
public object Post(UserCredential request)
{
return request;
}
public object Put(UserCredential request)
{
return request;
}
public void Delete(UserCredential request)
{
}
}
I use "POSTMAN" for debug and send this as a POST:
http://sun:1300/userscredentials/a?format=json
It works. Then I send as POST:
http://sun:1300/userscredentials/a/b/c/1/d/2?format=json
and get, "Handler for Request not found: Request.HttpMethod: POST Request.PathInfo: /userscredentials/a/b/c/1/d/2 Request.QueryString: format=json Request.RawUrl: /userscredentials/a/b/c/1/d/2?format=json"
Routing:
You shouldn't be defining the routes in the AppHost using the .Add<T> method as well as using [Route("/route", "METHOD")] on the DTO.
You only need to use one method. So this may cause conflict, and certainly extra maintenance. I recommend using just the latter, of the Route attribute. So remove the Add rules from your AppHost as they are covered by the DTO routes.
You should also read the routing documentation here, and this post about routing also.
Typo:
You have a typo in your route code. You have an incorrect bracket ( instead of {:
(Permissions}
Should be:
{Permissions}
Metadata
An excellent place to check the service is defined properly is by checking the applications Metadata feature. This is enabled by default, so you can do this by adding /metadata to your server url. i.e.
http://localhost:{port}/metadata
You can see an example metadata page here
Hope that helps.

What's the best way to convey required/optional DTO properties in ServiceStack?

I'm having an issue with my ServiceStack w/ Swagger implementation regarding documenting required/optional properties. Developers implementing clients that consume my services love the Swagger documentation, however they don't know which properties are required vs. optional--aside from getting a 400 response on each attempt to get a valid request through.
Take the following example:
public class UserProfile
{
public string FirstName { get; set; }
public string LastName { get; set; }
public UserAddress Address { get; set; }
}
public class UserAddress
{
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zip { get; set; }
public string Country { get; set; }
public string PhoneNumber { get; set; }
}
Swagger will cleanly show both of these types if they are part of my DTO, however I can't convey that FirstName, LastName, or any of the Address properties are required or not. Is there a way to accomplish this without having to roll a separate spec document?
You can use an [ApiMember(IsRequired = false)] attribute on the properties in the DTO to add extra information for swagger ui.
There is list of the attributes that swagger ui will recognise on the servicestack wiki

DDD/CQRS, Entity has access to Query, Command?

public class PageRoleService
{
public void SetRoles(Page page, User activeUser)
{
var rb = page.Project.ProjectType.GetRoleFor(activeUser.UserType);
page.RolesForPage.Add(activeUser, rb);
var managers = GetAllManagersOf(activeUser);
foreach (var m in managers)
{
page.RolesForPage.Add(m, rb);
}
}
}
public class Project : Entity
{
public ProjectType ProjectType { get; set; }
public IList<Page> Pages { get; set; }
}
public class Page : Entity
{
public string Name { get; set; }
public Project Project { get; set; }
public IDictionary<User, RoleBehaviour> RolesForPage { get; set; }
}
public class ProjectType : Entity
{
public IQueryProcessor QueryProcessor { get; set; }
public IList<RoleBehaviour> RoleBehaviours { get; set; }
public RoleBehaviour GetRoleFor(USerType userType)
{
var behaviour = return QueryProcessor.Execute(new GetRolesByUserAndProjectTypeQuery() {
ProjectType = this,
UserType = userType
});
// Filter behaviour attributes for project type properties, business rules, etc...
// FilterBehaviour(behaviour);
return behaviour;
}
}
public class GetRolesByUserAndProjectTypeQuery
{
public UserType UserType { get; set; }
public ProjectType ProjectType { get; set; }
}
public class GetRolesByUserAndProjectTypeQueryHandler
{
public Db Db { get; set; }
public RoleBehaviour Execute(GetRolesByUserAndProjectTypeQuery query)
{
return Db.FirstOrDefault(r => r.UserType == query.UserType && r.ProjectType == query.projectType);
}
}
public class RoleBehaviour : Entity
{
public Role ROleForArea1 { get; set; }
public Role ROleForArea2 { get; set; }
public UserType UserType { get; set; }
public ProjectType ProjectType { get; set; }
public IDictionary<string, string> Attributes { get; set; }
}
public enum UserType
{
A,
B,
C,
D
}
public class Role : Entity
{
public IList<string> Permissions { get; set; }
}
I don't use repository, no need data abstraction, I use CQRS for crud operations. (CreateProjectCommand, GetRolesByUserAndProjectTypeQuery, etc..)
Users related a lot of project and page. Users have more than role for each Page Entity and is dynamically created when user (client) request to fetch All projects page or single page item.
My Page Role Service determinates page roles for active user and its managers. My MVC Controller use PageRoleService.
PageRoleService is Application Service or Domain Service or .....?
QueryProcessor in Entity (ProjectType) is invalid approach? How can handle this/their problems without lazy or eager loading?
RoleBehaviour is Entity or Value Object?
PageRoleService is a service or business logic in domain?
I know that I'm some years later, but:
I would put away the base class Entity, because it looks that this are just Dtos returned by the queryhandler (infact GetRolesByUserAndProjectTypeQueryHandler.Execute returns a RoleBehaviour).
Given this, I think that:
PageRoleService is a simple service that completes a Dto, hence it looks a kind of factory
Given that ProjectType here has two different roles (a Dto and Entity, and this is against CQRS), if:
it's a Dto, then use a service/factory/ORM to load extra data on it
it's an Entity, try to load all the data that's needed by it. This because there're great changes that you'll need it on the way to execute your command (great explanation about DDD and entities).
The object has it's own identity? Has it an Id that, even if things will change, remains the same? Looking at it, it looks just a Dto, with nothing really interesting (at business level).
see 1.

ServiceStack not receiving values on OnDelete

On OnDelete of ServiceStack, it is called but the values are empty.
I tried to check the value, e.g.
ProductRequestResponse rx = Client.Send<ProductRequestResponse>(
"DELETE", "http://localhost:2012/api/product_request",
new ProductRequest { Id = 7 });
On the ServiceStack side, I only receive an Id of 0. Here's my StackService OnDelete method.
public override object OnDelete(ProductRequest request)
{
throw new Exception("Id: " + request.Id.ToString());
}
Here's my objects use for communication
public class ProductRequest
{
public int Id { get; set; }
public ProductDto ProductDto { get; set; }
}
public class ProductRequestResponse
{
public ProductDto ProductDto { get; set; }
public IEnumerable<ProductDto> ProductDtos { get; set; }
public ServiceStack.ServiceInterface.ServiceModel.ResponseStatus ResponseStatus { get; set; } //Where Exceptions get auto-serialized
}
What am I missing, why StackService is not receiving any value from OnDelete method?
Firstly, you should be using the Delete method as the Send only does POST's:
So it looks something like:
restClient.Delete<TransactionLogResponse>("/transactionlog");
The reason why Delete doesn't expect a Request DTO is because the DELETE Http verb does not accept a request body.
If you want to add paramaters you should add this on the route path or query string, e.g:
restClient.Delete<TransactionLogResponse>("/transactionlog/1?Arg1=a&Arg2=b");

Resources