So I'm brand new to developing an API, I have an existing MVC website which is published on Azure, and I would like to create my API using the ASP.NET Web Api template in a new project.
My question is in deployment. How can I deploy this API so that the target address is like:
www.MyMVCWebsite.com/api/etc...
I don't want to modify my existing MVC site to contain the api as I've seen some posts mention that it is less secure, and all tutorials I've seen are for the web api template and I'm learning this from scratch.
Within the publish to azure settings in visual studio it gives the option to publish to an existing site...would this achieve what I want or is there more to it?
JK
You just need to configure the routes to what you want it to be.
routes.MapHttpRoute(
name: "API Default",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
See Here
Related
I am doing an MVC5 Web API Application. I am doing an simple example.
Create an Web Asp.Net web Application.
Select Empty and API.
Then I add a Api2 Controller called Home, and add a Simple Method called Get()
Method Get() looks like this.
public string Get()
{
return "Hello World";
}
I run the application and complete the URL.
http://localhost:56464/Home/Get
Got an error
Error HTTP 404.0 - Not Found
I test changing WebApiConfig adding
{action}
but I get the same error.
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
When I start the Application http://localhost:56464/, I got this error
Error HTTP 403.14 - Forbidden
I always run the Application from Visual Studio 2013. I did not publish it it IIS
What is missing?
There are a few issues.
First the web api route template is
api/{controller}/{action}/{id}
Note the api prefix.
So that would mean that you have to browse to
http://localhost:56464/api/Home/Get
http://localhost:56464/ wont work because the route has the api prefix. So the forbidden error is default for what ever is hosting at that address.
To be able to use the URL you want in the question you would need to change the route template to match your desired template.
I have a web api service placed on https sub domain. I used castle Windsor to create all classes (per web request), from controller to domain objects.
I tested all actions on local machine and also using fiddler. everything works fine. And no memory leak was happened. and also we have a mobile programmer which worked with all actions and again every thing was fine.
but after hosting on https, by each request to web api urls, application pool stops.
but the request to authorization works fine. What is wrong with my application? here is my code to Config file:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config, IAppBuilder app)
{
// Web API configuration and services
var container =Bootstrapper.WireUp();
ConfigCors(container, config);
RegisterControllers(container);
UserManagement.Config.Bootstrapper.WireUp(container);
config.Services.Replace(typeof(IHttpControllerActivator), new WindsorControllerActivator(container));
container.Register(Component.For<IDataProtectionProvider>().ImplementedBy<DpapiDataProtectionProvider>()
.UsingFactoryMethod(x => app.GetDataProtectionProvider()));
// Web API routes
config.MapHttpAttributeRoutes();
config.AddFiveLevelsOfMediaType();
config.Routes.MapHttpRoute(
name: "DefaultApiWithAction",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
//config.Routes.MapHttpRoute("DefaultApiWithId", "Api/{controller}/{id}", new { id = RouteParameter.Optional }, new { id = #"\d+" });
}
private static void ConfigCors(IWindsorContainer container, HttpConfiguration config)
{
var cors = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(cors);
}
There is no specific reason that application pool is stopping. It could be a windows registry error, system error or assembly permission error. The best way to find out why is to go and check event viewer.
From Administrative Tools select Event Viewer
Alternatively, press Windows Key and type Event Viewer. Once there look into the into Windows Logs and then Application logs. Search for any error (red icon) or warning (yellow icon) that is related to IIS / ASP.Net or .Net framework. I have attached a sample image from my system -
Another Instance -
** EDIT **: There is one other possibility since it stopped after enabling https. Check the SSL certificate. The most common reason is using same certificate in multiple sites. Only wild card certificates can be used in multiple site. If the certificate is self signed, delete it and create a new one with * , being the prefix for the certificate name. Then use that one.
With the help of several online tutorials, like this one, I am still struggling to add a Web API service to an existing Asp site, that is not MVC.
I added to the project a new item of type Web API Controller Class(v2.1), named it something like AbcController.cs, and VS2015 asked me to put it in the App_Code directory. The default code has handlers for Get, Put etc. Sounded to me like I am on the right track.
I added a default route in Global.asax.cs like in the tutorial:
RouteTable.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
This got built after adding a reference to System.Web.Http.Webhost which was not mentioned in the tutorial. Sounded like I was still on the right track.
However, it doesn't work. I run the site in debug and this gives me a 404 Not Found:
http://localhost:54905/api/abc
I tried to run this on the production server with IIS7, of course as a second test web site to not interfere with the version that is in production. However, I ran into the error that the Microsoft.Web.Infrastructure dll could not be found. To fix this, I should install MVC packages, which I don't like for just an experiment.
My questions are:
do I get it right that the URL is in lower case, i.e., not .../api/Abc ?
does this kind of routing work in the debugger?
am I essentially turning the web site into an MVC web site?
is this really the simplest way to add a "REST" service to an existing web site? I only need to implement the POST, read and return some JSON data, and do not need arguments in the URL
I want to display a default status page for my web api project (where instead some IIS message is displayed when I start the project). However it seems like I cannot create views in web api (there is no support for ActionResult).
In addition to a status page I will also use this information to create an api documentation page.
How can I achieve displaying html pages in this situation ?
If your default status page is static html, you don't have to use MVC. Just tell WebApi in your Startup.cs that you want to support static resources:
app.UseFileServer();
For creating an API documentation, maybe you could write that file on startup dynamically?
You can create regular controllers and views in a webAPI project the same as any MVC project. Just create a normal controller that does not inherit from ApiController. In your startup.cs make sure to configure at least a default route.
configuration.Routes.MapHttpRoute(
name: "someName",
routeTemplate: "{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
Right click and select Add, then you should see controller at the top. Select one of the mvc controllers.
I want to run tests against WebAPI project using a popular in-memory hosting strategy.
My tests reside in a separate project.
Here's the start of my test
[TestMethod]
public void TestMethod1()
{
HttpConfiguration config = new HttpConfiguration();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new {id = RouteParameter.Optional});
HttpServer server = new HttpServer(config);
HttpMessageInvoker client = new HttpMessageInvoker(server)
}
The client is initialized with the HttpServer, establishing the direct client-server connection.
Other than providing route config info, how does HttpServer know which WebAPI project to host?
How to host multiple WebAPI projects at the same time?
Seems HttpServer does some magic to locate WebAPI projects?
Thanks
Web API depends on a service called IAssembliesResolver to get all the assemblies and scans them to find controllers which implement the IHttpController interface.
Now sometimes Web API might be unable to find your controller depending on whether the assembly has been loaded into the current app domain or not. In that scenario you would need to make sure that your assembly is loaded.
Looking at your sample test code, it appears that you are not referring to any type from your Web API project in which case i assume the Web API project's assembly would not be loaded.
Also you seem to be registering the routes again in your test. I would suggest to use the WebApiConfig.Register(HttpConfiguration) of your Web API project to do all the registration stuff. This way you would be testing with the same settings that your Web API project has.
Notes:
When running tests using in-memory server, your requests/responses wouldn't go through the formatters' serialization/deserialization process which is dangerous as you could be having real issues during them. So you would need to make sure to take care about this. Long time back i wrote a blog post regarding this. You can check it out here.
Fiddler tool is very useful in looking at the raw requests/responses to diagnose any issues. You would be loosing this ability if you are doing in-memory testing though.
Web Api should find all your controllers that inherit from ApiController. As long as all your controllers are in the same solution it should work just fine. I have a very similar setup that runs tests using the in-memory httpserver against controllers in another project. This gives me the ability to do very fast "integration" tests in my unit test project.
Just make sure that you are invoking any controller from the web api project into your separate project to ensure that web api project is loaded in in-memory.Example:
[TestMethod]
public void TestMethod1()
{
//// So that the web api project is loaded in-memory
{webapi Project name}.Controller.{controllerName} = new {controller name}() ;
HttpConfiguration config = new HttpConfiguration();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new {id = RouteParameter.Optional});
HttpServer server = new HttpServer(config);
HttpMessageInvoker client = new HttpMessageInvoker(server)
}