How do I initialize a webhook receiver in ASP.Net MVC - asp.net-mvc

I'm following this guide here for installing and using webhooks in ASP.Net MVC, but it looks like this guide is for a wep api type project. I'm using a MVC type project and there is no Register method, unlike a API project. In MVC we have a RegisterRoutes method. So how do I register my webhooks in MVC?
an API project that uses Register and config, my ASP.Net MVC site doesn't have this.
MVC uses RegisterRoutes
UPdate
Here I added a web api controller and the code I posted below is whats in the web api controller. I included the nuget packages for webhooks, the registration in global.asax.cs and in the register method. But I'm still having problems reaching the code 'ExecuteAsync' no breakpoints are being hit
public class StripeWebHookHandler : WebHookHandler
{
// ngrok http -host-header="localhost:[port]" [port]
// http(s)://<yourhost>/api/webhooks/incoming/stripe/ strip receiver
public StripeWebHookHandler()
{
this.Receiver = StripeWebHookReceiver.ReceiverName;
}
public override Task ExecuteAsync(string generator, WebHookHandlerContext context)
{
// For more information about Stripe WebHook payloads, please see
// 'https://stripe.com/docs/webhooks'
StripeEvent entry = context.GetDataOrDefault<StripeEvent>();
// We can trace to see what is going on.
Trace.WriteLine(entry.ToString());
// Switch over the event types if you want to
switch (entry.EventType)
{
default:
// Information can be returned in a plain text response
context.Response = context.Request.CreateResponse();
context.Response.Content = new StringContent(string.Format("Hello {0} event!", entry.EventType));
break;
}
return Task.FromResult(true);
}
}

You can mix web api controllers in your MVC project. When you add web api controllers, you will have a WebApiConfig.cs file in your App_Start where you will definie the routing for web api. That is where you can call the InitializeReceiveStripeWebHooks method after adding the necessary nuget packages to your project.
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
// Load receivers
config.InitializeReceiveStripeWebHooks();
}
}
When you create a new project, Visual studio present you with different project templates. You can select the WebApi one which includes MVC and Web Api support. But if your project is created using the MVC template, it will not have the web api support by default. In that case, you can manually add it by following these steps.
Step #1
Create a new class called WebApiConfig.cs in the App_Start folder. Have the below content in that class
using System.Web.Http;
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
Step #2
Now go to global.asax and update the Application_Start event to include a call to the Register method in our newly created WebApiConfig class.
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register); // This is the new line
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
Now you can right click on project and add new WebApiController classes and web api's should work now.

Related

Web API controller in subfolder not being found with attribute routing

I have a controller in this folder structure:
Site
-Controllers
--API
---EventsController.cs
The EventsController.cs contains this:
[RoutePrefix("api")]
public class EventsController : Controller
{
[Route("event")]
public ActionResult Index()
{
return View("~/Views/Home/Index.cshtml");
}
The WebApiConfig.cs contains this:
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
When I run the site from Visual Studio and try to access http://127.0.0.1:8080/api/event I see nothing but this error:
<Error>
<Message>
No HTTP resource was found that matches the request URI 'http://127.0.0.1:8080/api/event'.
</Message>
<MessageDetail>
No type was found that matches the controller named 'event'.
</MessageDetail>
</Error>
If I comment out the config.Routes.MapHttpRoute line to make WebApiConfig.cs as the following, the URL above works:
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
//config.Routes.MapHttpRoute(
// name: "DefaultApi",
// routeTemplate: "api/{controller}/{id}",
// defaults: new { id = RouteParameter.Optional }
//);
}
What am I doing wrong? What is it that causes the attribute routing to fail when the DefaultApi route is configured? I have tried placing it before/after the config.MapHttpAttributeRoutes(); and neither works.
As an aside, I have manually built up this project while reading the following article, which has the same structure of MVC/Web API project and which does work. I just can't figure out what I've done differently.
http://www.codemag.com/Article/1605081
Thanks to #phil-cooper the answer was to inherit the correct base class in the api controller.

MVC and Sitefinity api

I am working on a project that needs to update data in a Sitefinity database. I added the Telerik.Sitefinity_All dll's to the project. I've added the connection string to the database that contains all the sitefinity data. I'm trying to use the API for sitefinity to connect to the database and pull the data but I'm having troubles. How do you configure the App.WorksWith() to use the connection for the sitefinity database, or is there any good documentation showing how to fully set this up? Thanks in advance for any help, I'm extremely new to Sitefinity. FYI, this is using Sitefinity v 9.2
Presuming the site builds and runs fine here is what you need to do in order to be able to create a custom Web Api service which will use the Sitefinity API and will allow the web api to be called from external applications:
Register a custom route - this is done in Global asax file. See example below:
protected void Application_Start(object sender, EventArgs e)
{
SystemManager.ApplicationStart += SystemManager_ApplicationStart;
}
private void SystemManager_ApplicationStart(object sender, EventArgs e)
{
RegisterRoutes(RouteTable.Routes);
}
private void RegisterRoutes(RouteCollection routes)
{
routes.Ignore("{resource}.axd/{*pathInfo}");
routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "ajax/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional });
}
Here I am using the /ajax/ route because /api/ is already taken by Sitefinity in 9.2.
Create your web api controller and use the Sitefinity API inside:
public class CourseController : ApiController
{
[HttpPost]
public HttpResponseMessage CreateOrUpdateCourse([FromBody] Course item)
{
// use Sitefinity API here
// if you need to make modifications to the data then you need to use the ElevatedModeRegion }}

Web API Attribute Routes in MVC 5 exception: The object has not yet been initialized. Ensure that HttpConfiguration.EnsureInitialized()

On an MVC 5 with Web API I have the following, using only Attribute Routes:
RouteTable.Routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
RouteTable.Routes.IgnoreRoute("{*favicon}", new { favicon = #"(.*/)?favicon.([iI][cC][oO]|[gG][iI][fF])(/.*)?" }); // TODO: Check for Apple Icons
RouteTable.Routes.MapMvcAttributeRoutes();
GlobalConfiguration.Configuration.MapHttpAttributeRoutes();
AreaRegistration.RegisterAllAreas();
In the RouteTable all the MVC routes were created ... But not the API ones ...
I checked the RouteTable.Routes and I see an exception:
The object has not yet been initialized. Ensure that HttpConfiguration.EnsureInitialized() is called in the application's startup code after all other initialization code.
at System.Web.Http.Routing.RouteCollectionRoute.get_SubRoutes() at
System.Web.Http.Routing.RouteCollectionRoute.GetEnumerator() at
System.Linq.SystemCore_EnumerableDebugView`1.get_Items()
For testing this I added only two Web Api actions to the project:
[RoutePrefix("api")]
public class StatApiController : ApiController {
[Route("stats/notescreateddaily"), HttpGet]
public IHttpActionResult NotesCreatedDaily() {
// Some code
}
[Route("stats/userscreateddaily"), HttpGet]
public IHttpActionResult UsersCreatedDaily() {
// Some code
}
}
Am I missing something?
Thank You,
Miguel
The solution is in fact replacing:
GlobalConfiguration.Configuration.MapHttpAttributeRoutes();
By:
GlobalConfiguration.Configure(x => x.MapHttpAttributeRoutes());
That was a change in Web API 2.
The solution is to call GlobalConfiguration.Configuration.EnsureInitialized(); after all your Web API related configuration is done, but I am curious as to why your registrations look like this...What kind of project template did you use to create the MVC5 project?...The predefined templates that come with Visual Studio has a structure which helps minimize route ordering problems and so would recommend using them, so wondering why your configuration structure looks like that...
I am having the same problem after I upgrade all my web services project using ASP.Net Web API 4.0 to 4.5 and using Web API 2.2 with Cors library. I managed to successfully solve the problem. What I did was eliminating or commenting out the following statement at the RouteConfig.cs file at App_Start folder:`
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
namespace myNameSpace.Configurations
{
public static class RouteConfig
{
public static void Register(HttpConfiguration config)
{
// Web API routes
//DON'T USE THIS. IT WILL GIVE PROBLEMS IN INSTANTIATION OF OBJECTS
//config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "LocationData",
routeTemplate: "dataservices/locations/{controller}/{action}/{id}",
defaults: new {action = "Index", id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "ProfileData",
routeTemplate: "dataservices/profiles/{controller}/{action}/{id}",
defaults: new { action = "Index", id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "DefaultRoute",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
}
On my Global.asax.cs file I am using the old routing registration
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System.Net.Http.Formatting;
using myNameSpace.IoC;
using myNameSpace.Configurations; // Here actually I change the protected void Application_Start() to protected void Configuration() and change the folder to configuration instead on App_Start
using myNameSpace.Controllers.ExceptionSchema;
using myNameSpace.Filters.HttpFilters;
namespace myNameSpace
{
public class WebApiApplication : System.Web.HttpApplication
{
public static void RegisterApis(HttpConfiguration config)
{
config.Filters.Add(new CustomHttpExceptionFilter());
}
protected void Application_Start()
{
//AreaRegistration.RegisterAllAreas();
RegisterApis(GlobalConfiguration.Configuration);
var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
GlobalConfiguration.Configuration.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.Register(GlobalConfiguration.Configuration);
}
}
}
Here is the reason:
Attribute Routing in Web API 2
Note: Migrating From Web API 1
Prior to Web API 2, the Web API project templates generated code like this:
protected void Application_Start()
{
// WARNING - Not compatible with attribute routing.
WebApiConfig.Register(GlobalConfiguration.Configuration);
}
If attribute routing is enabled, this code will throw an exception. If you upgrade an existing Web API project to use attribute routing, make sure to update this configuration code to the following:
protected void Application_Start()
{
// Pass a delegate to the Configure method.
GlobalConfiguration.Configure(WebApiConfig.Register);
}
I am using the old route and I decided not to use attribute routing. So take OUT THAT statement

How to add Web API to an existing ASP.NET MVC 4 Web Application project?

I wish to add an ASP.NET Web API to an ASP.NET MVC 4 Web Application project, developed in Visual Studio 2012. Which steps must I perform to add a functioning Web API to the project? I'm aware that I need a controller deriving from ApiController, but that's about all I know.
Let me know if I need to provide more details.
The steps I needed to perform were:
Add reference to System.Web.Http.WebHost.
Add App_Start\WebApiConfig.cs (see code snippet below).
Import namespace System.Web.Http in Global.asax.cs.
Call WebApiConfig.Register(GlobalConfiguration.Configuration) in MvcApplication.Application_Start() (in file Global.asax.cs), before registering the default Web Application route as that would otherwise take precedence.
Add a controller deriving from System.Web.Http.ApiController.
I could then learn enough from the tutorial (Your First ASP.NET Web API) to define my API controller.
App_Start\WebApiConfig.cs:
using System.Web.Http;
class WebApiConfig
{
public static void Register(HttpConfiguration configuration)
{
configuration.Routes.MapHttpRoute("API Default", "api/{controller}/{id}",
new { id = RouteParameter.Optional });
}
}
Global.asax.cs:
using System.Web.Http;
...
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
WebApiConfig.Register(GlobalConfiguration.Configuration);
RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
Update 10.16.2015:
Word has it, the NuGet package Microsoft.AspNet.WebApi must be installed for the above to work.
To add WebAPI in my MVC 5 project.
Open NuGet Package manager console and run
PM> Install-Package Microsoft.AspNet.WebApi
Add references to System.Web.Routing, System.Web.Net and System.Net.Http dlls if not there already
Right click controllers folder > add new item > web > Add Web API controller
Web.config will be modified accordingly by VS
Add Application_Start method if not there already
protected void Application_Start()
{
//this should be line #1 in this method
GlobalConfiguration.Configure(WebApiConfig.Register);
}
Add the following class (I added in global.asax.cs file)
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
Modify web api method accordingly
namespace <Your.NameSpace.Here>
{
public class VSController : ApiController
{
// GET api/<controller> : url to use => api/vs
public string Get()
{
return "Hi from web api controller";
}
// GET api/<controller>/5 : url to use => api/vs/5
public string Get(int id)
{
return (id + 1).ToString();
}
}
}
Rebuild and test
Build a simple html page
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script src="../<path_to_jquery>/jquery-1.9.1.min.js"></script>
<script type="text/javascript">
var uri = '/api/vs';
$(document).ready(function () {
$.getJSON(uri)
.done(function (data) {
alert('got: ' + data);
});
$.ajax({
url: '/api/vs/5',
async: true,
success: function (data) {
alert('seccess1');
var res = parseInt(data);
alert('got res=' + res);
}
});
});
</script>
</head>
<body>
....
</body>
</html>
UPDATE 11/22/2013 - this is the latest WebApi package:
Install-Package Microsoft.AspNet.WebApi
Original answer (this is an older WebApi package)
Install-Package AspNetWebApi
More details.
As soon as you add a "WebApi Controller" under controllers folder, Visual Studio takes care of dependencies automatically;
Visual Studio has added the full set of dependencies for ASP.NET Web
API 2 to project 'MyTestProject'.
The Global.asax.cs file in the project may require additional changes
to enable ASP.NET Web API.
Add the following namespace references:
using System.Web.Http;
using System.Web.Routing;
If the code does not already define an Application_Start method, add the following method:
protected void Application_Start()
{
}
Add the following lines to the beginning of the Application_Start method:
GlobalConfiguration.Configure(WebApiConfig.Register);
You can install from nuget as the the below image:
Or, run the below command line on Package Manager Console:
Install-Package Microsoft.AspNet.WebApi
Before you start merging MVC and Web API projects I would suggest to read about cons and pros to separate these as different projects. One very important thing (my own) is authentication systems, which is totally different.
IF you need to use authenticated requests on both MVC and Web API, you need to remember that Web API is RESTful (don't need to keep session, simple HTTP requests, etc.), but MVC is not.
To look on the differences of implementations simply create 2 different projects in Visual Studio 2013 from Templates: one for MVC and one for Web API (don't forget to turn On "Individual Authentication" during creation). You will see a lot of difference in AuthencationControllers.
So, be aware.
NOTE : this is just an abbreviation of this answer above
Open NuGet Package manager console and run
PM> Install-Package Microsoft.AspNet.WebApi
Add references to System.Web.Routing, System.Web.Net and System.Net.Http dlls if not there already
Add the following class
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
Add Application_Start method if not there already (in global.asax.cs file)
protected void Application_Start()
{
//this should be line #1 in this method
GlobalConfiguration.Configure(WebApiConfig.Register);
}
Right click controllers folder > add new item > web > Add Web API controller
namespace <Your.NameSpace.Here>
{
public class VSController : ApiController
{
// GET api/<controller> : url to use => api/vs
public string Get()
{
return "Hi from web api controller";
}
}
}
The above solution works perfectly. I prefer to choose Web API option while selecting the project template as shown in the picture below
Note: The solution works with Visual Studio 2013 or higher. The original question was asked in 2012 and it is 2016, therefore adding a solution Visual Studio 2013 or higher.
I had same problem, the solution was so easy
Right click on solotion
install Microsoft.ASP.NET.WebApi from "Manage Nuget Package for Sulotion"
boom that's it ;)

In ASP.NET MVC, why do I get 404 errors after Publishing my website?

I'm still new to ASP.NET MVC and I'm struggling a little with the routing.
Using the ASP.NET development server (running directly from Visual Studio), my application can find its views without any problems. The standard ASP.NET URL is used - http://localhost:1871/InterestingLink/Register
However, when I publish my site to IIS and access it via http://localhost/MyFancyApplication/InterestingLink/Register, I get a 404 error.
Any suggestions on what might be wrong?
More info...
This is what my global.asax file looks like (standard):
public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
}
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
}
}
My controller is also very simple:
public class InterestingLinkController : Controller
{
public ActionResult Register()
{
return View("Register");
}
}
I figured out what was wrong. The problem was actually that IIS5 (in Windows XP) does not fire up ASP.NET when the URL does not contain a .ASPX. The easiest way to get around this is to add a '.aspx' to your controller section in global.asax. For example:
routes.MapRoute(
"Default",
"{controller}.aspx/{action}/{id}",
new { controller = "Home", action = "Index", id = "" }
);
Not pretty, but it will do.
Lots of things could be wrong:
Is the IIS Virtual Directory & Application set correctly?
Is the ASP.NET application being called at all? (Add some logging/breakpoiont in Application_Start and Application_BeginRequest)
Just for a start. You are going to have to apply the usual debugging approaches.
(To avoid issues like this, I rarely use the development server and just use IIS the whole time: most difficult thing is remembering to run VS elevated every time.)

Resources