I have seen many links on how to make a web-api using PHP, and all of the examples would put each "function" in a different file. I once helped my friend develop an asp.net C# web api where a single file would contain multiple functions.
Can this be done in PHP? i.e can a single PHP file contain multiple functions that a web-api can call? If so can you kindly give me an example of how it is done, or refer me to a link where this is explained?
Thank you for your time.
Use a framework to build your API, don't reinvent the wheel.
If you must, you need to find a "discriminator", or how you know what kind of request has to end up at which function.
You can do so using the HTTP verb, the URL, HTTP headers and whatnot. Frameworks do this for you, so you only have to write the code you're interested in.
Again, if you must, you can do something like this:
<?php
function DoPost()
{
// ...
}
function DoPut()
{
// ...
}
function DoGet()
{
// ...
}
function Main()
{
switch ($_SERVER['REQUEST_METHOD'])
{
case 'GET':
return DoGet();
case 'PUT':
return DoPut();
case 'POST':
return DoPost();
}
}
Main();
?>
Related
Is there any way to run the PHP code on the c# app
since I'm working on an application that requires to implement of this site's API
but there is no documentation except for PHP, so is there any way I can use this piece of code in a c# application or convert this code in C# if that is possible.
public $api_url = 'https://smm-bomb.com/api/v2'; // API URL
public $api_key = ''; // Your API key
public function order($data) { // add order
$post = array_merge(array('key' => $this->api_key, 'action' => 'add'), $data);
return json_decode($this->connect($post));
}
One option is to rewrite the call using C#, check docs if needed.
Another one is to made your custom php-api which wrap initial call.
Then from C# just use your php-api. Postman can be a useful tool to check your custom php-api and also for C# code generation
---custom php-api---
--update to fit https://smm-bomb.com/api--
<?php
class Api
{
public $api_url = 'https://smm-bomb.com/api/v2'; // API URL
public $api_key = '4a99333333333333333dummy'; // Your API key
...
//just copy-paste from example
}
//from-docs, create an instance an invoke any methods
//since it's a self contained class no imports required
//main
$api = new Api();
$services = $api->services(); # return all services
$out = [];
//mainly here will be the return of api-call
$out["mykey"]="myvalue";
//output as json whatever wanted
$out["listServices"]=$services;
echo json_encode($out);
?>
//sample output
//{"mykey":"myvalue"}
This piece of code should be accessible via link eg: https://yoursite/custom-api (for security purpose can use a token on query-string. /custom-api?key=123mykey ->trivial approach)
Use PostMan to check and see code-generation
I am new to ASP.NET and I want to ask which method is more preferred for insert new rows in SQL Server.
The biggest problem I want to avoid is double insert data into SQL Server. Maybe for some network delay I will take server error in my client's application, but server have received my data and insert them into SQL Server. When I will make a retry, it will re-insert them.
Does post or put method can avoid this? Or i need to create my own mechanism?
public void Post([FromBody]string value)
{
}
// PUT api/values/5
public void Put(int id, [FromBody]string value)
{
}
Also one last question, can I create two post methods inside same controller or I have to create a new one?
Sorry, if questions looks easy but as I said I am new in asp.net. Thank you
POST or PUT methods does not solve nothing by itself. If you want to avoid the behaviour you described you should solve that by adding your own logic to that methods. It is your implementation what have to make the control over if the data exists or not.
Ideally on REST API, POST will be for creating a resource and PUT is for updating an existing resource.
Having said that, you can implement your logic depending on who is calling that endpoint and in what instance of the application. For example, if someone send a POST with the same resource two times, you can check out if the resource exists and send an HTTP status that describe the situation.
EDIT:
I will add some code to show you. How it could work:
Let´s suppose you want to create and update users in your application. The endpoint for that could be something like: http://localhost:8080/api/users/ using POST method and sending the user as JSON on the request body.
You will have a UsersController something like this:
public HttpResponseMessage Post([FromBody]UserModel user)
{
SQL.InsertUser(user);
return Request.CreateResponse(HttpStatusCode.OK);
}
Then on the data layer you could make something like this:
public static void InsertUser(UserModel user)
{
try
{
using (_conn = new SqlConnection(_connectionString))
{
_conn.Execute(#"IF EXISTS(SELECT * FROM USER WHERE ID = #ID)
BEGIN
/*DO THE UPDATE*/
END
ELSE
BEGIN
/*DO THE INSERT*/
END", user);
}
}
catch (Exception ex)
{
throw ex;
}
}
This is not the optimal approach but what I´m trying to show here is that you can either insert the resource on POST or on PUT. The thing is that RESTful API´s are meant to be designed following the RESTful standard. If you insert data with a PUT method then you probably have and architecture issue and your API isn´t RESTful at all. Even if it uses the HTTP methods form communication and so.
It is very important on RESTful API´s to follow the standard. For you and the people that make use of the API.
Here you got a RESTful introductory bible. I usually send this to everyone that is looking to undestand RESTful world: https://blog.octo.com/en/design-a-rest-api/
Post() method that we decorated with a [HttpPost] attribute.
Put() is able to update something in a RESTful service
I am trying to create a WebHookHandler for Webhooks send from WordPress WooCommerce in ASP.NET C#.
I started with creating a ASP.NET C# Azure API App WebApplication Project and adding the relevant references (Microsoft.AspNet.WebHooks.Common, Microsoft.AspNet.WebHooks.Receivers, Microsoft.AspNet.WebHooks.Receivers.WordPress). Added the WebHookConfig, WordPressWebHookHandler and registered the WebHookConfig in the GlobalAsax.
I then published the application as an Azure App Service.
My WordPressWebHookHandler is still the default of the examples and looks like this:
public class WordPressWebHookHandler : WebHookHandler
{
public override Task ExecuteAsync(string receiver, WebHookHandlerContext context)
{
// make sure we're only processing the intended type of hook
if("WordPress".Equals(receiver, System.StringComparison.CurrentCultureIgnoreCase))
{
// todo: replace this placeholder functionality with your own code
string action = context.Actions.First();
JObject incoming = context.GetDataOrDefault<JObject>();
}
return Task.FromResult(true);
}
}
When testing a User Creation WebHook in WooCommerce I can see the request in the log as below.
But unfortunately it is never received while debugging and I see below error.
I am thinking maybe I need a custom WebHook instead of the WordPress specific one as this is a WooCommerce Webhook. Or possibly it is handled wrong in the routing and ends up in another controller.
Any help is much appreciated.
Your WebHookReceiver is wrong
There is a mismatch of expecting HTML Form Data, when in fact it should be expecting JSON.
WordPressWebHookHandler is still the default
This is what is causing your error. If you look at the WordPressWebHookReceiver, the ReceiveAsync() method implementation, calls out to ReadAsFormDataAsync() method, which is not what you want, as your Content-Type is json. So, you want to be doing ReadAsJsonAsync().
Solution: Don't use the WordPressWebHookReceiver and switch it to another one that will call ReadAsJsonAsync().
Looking at the code
I am thinking maybe I need a custom WebHook instead of the WordPress specific one as this is a WooCommerce Webhook.
You had the right idea, so I dug up some of the code to explain exactly why this was happening.
The code block below is the ReceiveAsync() method that is overridden in the WordPressWebHookReceiver. You can see that it is calling the ReadAsFormDataAsync() which is not what you want...
public override async Task<HttpResponseMessage> ReceiveAsync(
string id, HttpRequestContext context, HttpRequestMessage request)
{
...
if (request.Method == HttpMethod.Post)
{
// here is what you don't want to be called
// you want ReadAsJsonAsync(), In short, USE A DIFFERENT RECEIVER.
NameValueCollection data = await ReadAsFormDataAsync(request);
...
}
else
{
return CreateBadMethodResponse(request);
}
}
A quick search through the repository for classes that call the ReadAsJsonAsync() method, shows that the following recievers implement it:
DynamicsCrmWebHookReceiver
ZendeskWebHookReceiver
AzureAlertWebHookReceiver
KuduWebHookReceiver
MyGetWebHookReceiver
VstsWebHookReceiver
BitbucketWebHookReceiver
CustomWebHookReceiver
DropboxWebHookReceiver
GitHubWebHookReceiver
PaypalWebHookReceiver
StripeWebHookReceiver
PusherWebHookReceiver
I assumed that the CustomWebHookReceiver would fit your requirements, so can grab the NuGet here. Otherwise you can implement your own, or derive it from this class, etc.
Configuring a WebHook Recevier
(Copied from the Microsoft Documentation)
Microsoft.AspNet.WebHooks.Receivers.Custom provides support for
receiving WebHooks generated by ASP.NET WebHooks
Out of the box you can find support for Dropbox, GitHub, MailChimp,
PayPal, Pusher, Salesforce, Slack, Stripe, Trello, and WordPress but
it is possible to support any number of other providers
Initializing a WebHook Receiver
WebHook Receivers are initialized by registering them, typically in
the WebApiConfig static class, for example:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
...
// Load receivers
config.InitializeReceiveGitHubWebHooks();
}
}
There is a problem with the data format that you send in your request. You must use format of HTML Form as your error message said.
Proper POST data format is described here: How are parameters sent in an HTTP POST request?
Don't forget to set Content-Length header and correct Content-Type if your library doesn't do it. Usually the content type is application/x-www-form-urlencoded.
I would like to make some additions to Svek's answer as I now got my Proof-of-concept completed and understand a bit more about the receivers.
His answer pointed me in the right direction, but needs a little addition.
WordpressWebHookReceiver
Can take in Wordpress Webhooks of type HttpPost. This does not work with Woocommerce as Woocommerce sends Json Webhook messages and will fail the HttpPost validation which is build into the WordpressWebHookReceiver class.
CustomWebHookReceiver
Can take in custom ASP.NET Webhooks. The custom ASP.NET webhooks have a specific partner for validation which includes but is not limited to the 'ms-signature'. Even adding the header will not suffice as the signature is also used in a different way from out of the box Woocommerce to encrypt the message. Basically coming to a point that you can't integrate Woocommerce with the CustomWebHookReceiver without changing the Webhook classes of Woocommerce.
GenericWebHookReceiver
This is the receiver you want, which accepts basically a generic set of Json data and will be able to use the "code" query parameter to verify the secret which you can add in the web.config of your asp.net api application. I used this receiver to finish the Proof-of-concept and got both the signature validation as well as the deciphering of the message working right of the bat.
My basic class which I will start to build into a real solution can be viewed below and changes the JObject into a dynamic object in the methods I call from the class. As you can see I have two methods currently added, one for the customer create and one for the order create to call the respective methods which do an insert into Dynamics 365 (former CRM).
public class GenericJsonWebHookHandler : WebHookHandler
{
public GenericJsonWebHookHandler()
{
this.Receiver = "genericjson";
}
public override Task ExecuteAsync(string generator, WebHookHandlerContext context)
{
var result = false;
try
{
// Get JSON from WebHook
var data = context.GetDataOrDefault<JObject>();
if(context.Id != "crcu" && context.Id != "cror")
return Task.FromResult(true);
if (context.Id == "crcu")
{
result = WoocommerceCRMIntegrations.Entities.Contact.CreateContactInCRM(data);
}
else if (context.Id == "cror")
{
result = WoocommerceCRMIntegrations.Entities.Order.CreateOrderInCRM(data);
}
}
catch (Exception ex)
{
result = false;
}
return Task.FromResult(result);
}
}
I'm trying to develop a program that handles POST and GET requests.
I've spent countless hours searching around the web for a tutorial that doesn't depend on ASP.NET I do not want to use ASP.NET just standard C#.
How can I achieve this? The furthest I've gotten to is this:
if (HttpMethod.ContentType == "POST") {
// Code here
}
I've made a function HttpListen server on http://localhost:8080/ which sends a response.
What I'm looking for is you do http://localhost:8080/?method=val1&results=val2.
Thanks, Brown.
You're looking for an HTTP server library that is not ASP.NET?
Awkwardly bypassing the question "What's wrong with ASP.NET?"....
Nancy is an awesome lightweight open source library. You can find some samples on github, although the samples are a bit on the heavy side. If you're looking for an extremely basic setup you can get away with a couple dozen lines of code. A good example is the console-based self-hosted sample.
// add such a module class to your assembly, Nancy should find it automagically
public class ResourceModule : NancyModule
{
public ResourceModule() : base("/products")
{
// would capture routes to /products/list sent as a GET request
Get["/list"] = parameters => {
return "The list of products";
};
}
}
// then start the host
using (var host = new NancyHost(new Uri("http://localhost:1234")))
{
host.Start();
// do whatever other work needed here because once the host is disposed of the server is gone
Console.ReadLine();
}
I'm not sure of the best way to accomplish my goal. Looking for insight. I'm familiar with WebAPI services consumed through WPF and Silverlight but this is my first run at ASP and MVC.
I am building a site to verify contents of a shipment against an electronic manifest (EDI 856). I have a page that displays the shipping data and I need the users to scan each item barcode in the container. I would then like to pass that barcode to a service, verify the item belongs in that shipment and then update the page to show as much.
My plan was to have a single text box into which the user could scan/type the barcode and then submit that data to a WebAPI service which would verify the information and then probably use SignalR to send a message back to the page and update a grid with the item data.
If this is a decent way to go, I'm just not quite sure how to use ajax to call the WebAPI endpoint and provide the data I need.
I would advise against using SignalR in this situtation. What you need, judging from your description, is the most basic use case of submitting an ajax request and receiving a response.
You are not designing a system where you need the server to initiate communication with the browser or anything like that, where sockets (and SignalR as an abstraction over sockets with fallbacks to less suitable protocols) is a huge overkill.
Don't worry, your use case is rather simple.
It's a little out of scope to describe how to setup a WebApi project, how to configure routing, action names, etc. Simple google searches will surely provide ample quality tutorials on getting started.
I'll just try to explain what the general idea is, with some code samples, to get you thinking in the right direction.
You need to create an ApiController.
The simplest version of that Controller will probably look something like this:
public class ShipmentVerificationController : ApiController
{
//this is the response object you will be sending back to the client website
public class VerificationResult
{
public bool Valid;
}
public VerificationResult GetIsItemValid(string BarCode)
{
bool itemIsValid;
// Implement checks against the BarCode string here
itemIsValid = true;
return new VerificationResult { Valid = itemIsValid };
}
}
Note that the inner class represents the response you will be sending back. It should be properly filled out with additional info if needed and probably put into a separate .cs file in the "Models" folder or where ever you see fit.
I have declared it inside the controller for demonstration purposes only
Once you have a WebApi service deployed, it's really easy to send it data from your website and receive the feedback.
To simplify Ajax requests, jQuery is often used.
Once the user inputs the barcode into a textbox, you can hook up an event to check for return key being pressed (most barcode scanners send the return key command after they input the barcode data) and then write something along the lines of:
var barcode = $("#input-field").val();
$.getJSON( "<url_to_your_webapi_service>/api/ShipmentVerification/GetIsItemValid/" + barcode, function( data ) {
if (data.Valid) {
// great, highlight the item as valid
}
else {
//better indicate an error with the scanned item
}
});
Please note that for simplicity I have not included any error handling, url parameter encoding, and most importantly, zero authorization.
Authorization is very important if you deploy the web service to the open web but still do not want anyone to be able to call it.
You will have to research these topics yourself, but I hope I have presented you the core concepts and logic behind a simple service such as this, so you have a base to start with.
If you come up with specific problems and questions post a new question.
I actually found a more simple way to do this. I nixed the idea of using a WebAPI endpoint and just went with a normal controller. I used ajax to prevent the page from refreshing with the new view, since that view is actually just json data with my return values in it.