I'm playing with the "Microsoft.AspNet.WebApi.SelfHost" NuGet package in version "5.0.0-rc1" (tried also the current stable) but unfortunately I can't get my application setup to resolve the configured route to my implementation of the ApiController.
The application is quite simple and can be found nearly in all examples. It contains a .NET console application where in the main class the self host service lives.
using System.Web.Http.SelfHost;
using System.Web.Http;
using System;
namespace EP.Server
{
class Program
{
static void Main(string[] args)
{
var config = new HttpSelfHostConfiguration("http://localhost:60064");
config.Routes.MapHttpRoute(
name: "Default Route",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
using (var server = new HttpSelfHostServer(config))
{
server.OpenAsync().Wait();
Console.WriteLine("Server ist running on "+config.BaseAddress + " hit ENTER to stop.");
Console.ReadLine();
server.CloseAsync().Wait();
}
}
}
}
and then there is a separate controller class which lives in the same project and inherits from the ApiController class.
using System.Web.Http;
namespace EP.Server
{
class UsersController : ApiController
{
[HttpGet]
public string Get()
{
return "Hello I'm a user...";
}
}
}
The error message sounds like this when I call the service from any browser.
<Error>
<Message>No HTTP resource was found that matches the request URI 'http://localhost:60064/api/Users'.</Message>
<MessageDetail>No type was found that matches the controller named 'Users'.</MessageDetail>
</Error>
Does somebody have an idea what's wrong there? Unfortunately I couldn't find any similar issues / questions on the web.
Thank you so far!
Web API controllers need to be public.
Related
I am New in Asp.Net and tried to develop a small Web API in learning process.
WebApiConfig.cs
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/v1/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
TopicsController.cs
namespace MessageBoard.Controllers
{
public class TopicsController : ApiController
{
private IMessageBoardRepository _repo;
public TopicsController(IMessageBoardRepository repo)
{
_repo = repo;
}
public IEnumerable<Topic> Get()
{
var topics = _repo.GetTopics()
.OrderByDescending(t => t.Created)
.Take(25)
.ToList();
return topics;
}
}
}
Actually i am watching PluralSight tutorials.
http://localhost:50031/api/v1/topics
this Url is not working in Browser not in Fiddler 4.
all references are added. i have also done Build Solution but its not working and their is no error showing in the code.
One last step to enable Web Api which looks like you're missing is enabling Web API in the Global.asax file by adding the following line of code to the Application_Start() method:
WebApiConfig.Register(GlobalConfiguration.Configuration);
Also, please don't use the port number from the PluralSight tutorial.You need to run the web application project from your instance of Visual Studio and when it opens up in the browser you will see which port is assigned to YOUR api service.So if you see that it assigned port 12345 for example you would call the following URL to access the service action:
http://localhost:12345/api/v1/topics
Add attribute routing to controller
[Route("api/v1/topics")]
public IEnumerable<Topic> Get()
{
var topics = _repo.GetTopics()
.OrderByDescending(t => t.Created)
.Take(25)
.ToList();
return topics;
}
Maybe this is answered before but I couldn't find it. If this is the case a good link will be great.
I'm developing an angular application in top of an ASP.NET app. I communicate them through a restful service. The problem is when I run from visual studio my app (using IIS) it goes to url
http://localhost:51061/
As I can't get into this page i get an error 403 forbidden. I want that when I push run inside visual studio my app start in.
http.//localhost:51061/AngularApp/
Global.asax.cs
namespace WebApi {
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register);
}
}
}
WebApiConfig.cs
namespace WebApiPrC
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "backend/api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
}
Thank you
Have you looked at ""Project > Properties > Web > Start Action" section?
You can specify however you want the app to start, e.g. "Current Page", "Specfic page" and "Start URL" etc. I guess you want to enter the url to "Start URL" box.
Webapi is a framework for resource transmission between server and client (data only) and for views routing you have set up Angular routing .
In this case,angularApp application angular routing is useful like :
AngularApp.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/', {
templateUrl: 'xxx.html',
controller: 'xxxcontrollername'
}).
otherwise({
redirectTo: '/login.html'
});
}]);
Hope So its help you.
I have found out how to version my WebAPI based on namespaces using this class.
I am using Swashbuckle to add Swagger doc to my API, using the Swashbuckle Nuget package.
If I keep everything intact, when I navigate to /swagger/, I get an empty page.
In my App_Start:
public class SwaggerConfig
{
public static void Register()
{
Bootstrapper.Init(GlobalConfiguration.Configuration);
SwaggerSpecConfig.Customize(c =>
{
c.IncludeXmlComments(GetXmlCommentsPath());
});
}
private static string GetXmlCommentsPath()
{
return string.Format(#"{0}\App_Data\XmlDocumentation.xml", AppDomain.CurrentDomain.BaseDirectory);
}
}
And my web API routes:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{namespace}/{controller}/{id}",
defaults: new
{
id = RouteParameter.Optional
});
}
}
If I remove the {namespace} it works (the API commands are displayed), but I want to keep this namespace information in my route.
How do I customize Swagger/Swashbuckle to make this work?
From the Swashbuckle Github repo:
There is a flaw in the above implementation of "namespace routing" as it breaks the WebApi metadata layer - ApiExplorer and hence Swashbuckle.
A workaround, although doesn't directly solve your problem, is to use attribute versioning instead, which works fine with Swashbuckle:
I.e.:
[RoutePrefix("api/v1/Features")]
public class FeaturesV1Controller : ApiController
{
[Route("Products/{product}")]
public IList<Metadata.FeatureListItemModel> Get(long product){}
Please see the two Github issues below for more info.
https://github.com/domaindrivendev/Swashbuckle/issues/317
https://github.com/domaindrivendev/Swashbuckle/issues/303
I believe that with attribute routing, your controller must have a different name for each version. I.e. the class should be named FeaturesV1Controller and FeaturesV2Controller for v2, but for the routes you can still use /api/v1/Features and /api/v2/Features
I am creating a WebApi2 service, and one of the methods I want to implement represents an HTTP GET from an object within an internal tree structure - so the request would be along the lines of:
GET /values/path/path/to/object/in/tree
So I would want my method to receive "path/to/object/in/tree".
However, I just get a 404 when I run this, and it's interesting that I get a 404 that is different looking to the standard IIS 404. It's titled 'Server Error in '/' Application.', whereas the one for a completely invalid resource is titled 'HTTP Error 404.0 - Not Found'.
I am playing around with the default template to try and see if I can get this to work, hence the similarity.
I have this for my RouteConfig
public static void RegisterRoutes(RouteCollection routes)
{
var route = routes.MapRoute(
name: "CatchAllRoute",
url: "values/path/{*pathValue}",
defaults: new { controller = "Values", action = "GetPath" });
}
And this is my ValuesController:
[System.Web.Mvc.AuthorizeAttribute]
[RoutePrefix("values")]
public class ValuesController : ApiController
{
[Route("test/{value}")]
[HttpGet]
public string Test(string value)
{
return value;
}
[HttpGet]
public string GetPath(string pathValue)
{
return pathValue;
}
}
Interestingly, if I derive from Controller rather than ApiController it works OK, but then the normal attribute routing doesn't work.
I tried following the methodology in this post (http://www.tugberkugurlu.com/archive/asp-net-web-api-catch-all-route-parameter-binding) but I couldn't get it to work.
I'm sure I'm missing something stupidly easy, but having spent a few hours on it I thought it prudent to ask what I'm doing wrong.
Thanks
M
Web api routing is not the same as routing MVC. instead of
route.MapRoute
try
public static void Register(HttpConfiguration config) {
config.MapHttpAttributeRoutes
config.Routes.MapHttpRoute(
name: "CatchAll", routeTemplate: "values/path/{*pathvalue}",
defaults: new {id = RouteParameter.Optional });
}
The reason it works from controller is that MapRoute is the correct format for routing an MVC controller, while MapHttpRoute is designed for API controllers.
I am using the John Papa Single Page Application source code to create my own App and I am running into some problems when using the Breeze Web API. I have my own breeze controller and as soon as I add a second HttpGET method I get the error "Multiple actions were found that match the request".
It is Weird because in his code he adds multiple GETs and his code works but I think I am missing something.
Breeze Controller
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using Breeze.WebApi;
using AgencyUpdate.Models;
namespace AgencyUpdate.Controllers
{
[BreezeController]
public class BreezeController : ApiController
{
readonly EFContextProvider<AgencyDbContext> _ContextProvider =
new EFContextProvider<AgencyDbContext>();
public string MetaData()
{
return _ContextProvider.Metadata();
}
[HttpGet]
public IQueryable<api_Agency> GetAgency()
{
return _ContextProvider.Context.api_Agency;
}
[HttpGet]
public IQueryable<api_AgencyOffice> GetOffice()
{
return _ContextProvider.Context.api_AgencyOffice;
}
}
}
I use this URL to request data:
**http://localhost:13762/api/breeze/GetAgency**
Also I have found this .CS file for routing but I don't know if I have to make changes to it.
BreezeWebApiConfig
using System.Web.Http;
[assembly: WebActivator.PreApplicationStartMethod(
typeof(AgencyUpdate.App_Start.BreezeWebApiConfig), "RegisterBreezePreStart")]
namespace AgencyUpdate.App_Start {
///<summary>
/// Inserts the Breeze Web API controller route at the front of all Web API routes
///</summary>
///<remarks>
/// This class is discovered and run during startup; see
/// http://blogs.msdn.com/b/davidebb/archive/2010/10/11/light-up-your-nupacks-with-startup-code-and-webactivator.aspx
///</remarks>
public static class BreezeWebApiConfig {
public static void RegisterBreezePreStart() {
GlobalConfiguration.Configuration.Routes.MapHttpRoute(
name: "BreezeApi",
routeTemplate: "breeze/{controller}/{action}"
);
}
}
}
Does anyone know what the problem is?
I feel a bit stupid the URL I need to use is breeze/breeze/MethodName.
John's code doesn't use breeze twice in the URL hence the confusion
Papa's course has the single-page-apps-jumpstart.zip file with project source code by chapters. The right version the BreezeWebApiConfig.cs content is as such:
public static class BreezeWebApiConfig {
public static void RegisterBreezePreStart() {
GlobalConfiguration.Configuration.Routes.MapHttpRoute(
name: "BreezeApi",
routeTemplate: "api/{controller}/{action}"
);
}
}
}
Notice the string routeTemplate: "api/{controller}/{action}"