I have created a C# Web API and I am able to access it on local host but post server deployment I am receiving 404 not found error.
Postman shows error - 'The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.'.
I have published the code using visual studio and then uploaded the files using file-zilla to the server.
The folder on the server is marked as an application.
I am able to access a sample html file present in the folder but not the api itself.
The Global.asax.cs has below code -
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
GlobalConfiguration.Configuration.Formatters.XmlFormatter.UseXmlSerializer = true;
}
}
RouteConfig.cs
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
WebApiConfig.cs
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 }
);
config.Filters.Add(new BasicAuthenticationAttribute());
}
I am trying to invoke the normal get method
[BasicAuthentication]
[HttpGet]
[Route("api/getmethodapi")]
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
The URI i am accessing is something like -
https://mysampleapp.com/sampleFolder/api/getmethodapi
I am able to get the values using Postman as well as with C# console application on local host.
Any help/suggestions would be appreciated.
Related
Good day, I am in a bit of a problem with my hosted ASP.NET WebAPI and MVC app hosted on IIS on a web server (MS Windows Server 2016). This is a basic website and includes an API in the same project. The web app has Areas and I suspect this is the problem. Periodically the website (Areas and API) goes down, the weird thing is that the views not under areas work fine, and the ones under areas and API stop working. There is no customization from the boiler template code for creating areas and so forth. I have also profiled requests coming in, but these are all basic calls with not a lot of data. I cannot see anything in the Event Viewer or IIS Logs, please does anyone have a suggestions?
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);//WEB API Registration
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
DiConfig.Register();
//Enable Claims Anti Forgery
AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.MetadataPropertyHandling = MetadataPropertyHandling.Ignore;
}
Routing Config:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.RouteExistingFiles = true;
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Exports", action = "Index", id = UrlParameter.Optional },
namespaces:new[] {""}
);
}
}
WebAPIConfig:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Configure Web API to use only bearer token authentication.
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
//config.MessageHandlers.Add(new TokenValidationHandler());
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/v1/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
//Configure to use XmlSerializer so you don't have to configure namespace in xml request
config.Formatters.XmlFormatter.UseXmlSerializer = true;
config.Formatters.XmlFormatter.SetSerializer<CertificateRequest>(new XmlSerializer(typeof(CertificateRequest)));
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/octet-stream"));
//Ignore Self Looping References
config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
//WEB API Throttling
config.MessageHandlers.Add(new ThrottlingHandler()
{
Policy = ThrottlePolicy.FromStore(new PolicyConfigurationProvider()),
Repository = new CacheRepository()
});
//
config.Services.Add(typeof(IExceptionLogger), new ElmahExceptionLogger());
}
}
My Web API on an Asp.Net MVC web app is returning 404 error when receiving requests that don't specify any controller.
The calls that are returning 404 error are:
https://myWebApp/api/
The goal would be to handle these type of requests without returning error and return something like "true" or "new EmptyResult()".
Current routing for the Web API includes the following in WebApiConfig.cs
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Filters.Add(new IdentityBasicAuthenticationAttribute());
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
While I have routes explicitly defined for each API controller:
[IdentityBasicAuthentication]
[Authorize]
public class myApi1Controller : ApiController
{
[HttpGet]
[Route("api/myApi1")]
public string Get(string id) { ... }
}
I have tried to route these calls to a default API or MVC controller without success.
My current RouteConfig for the MVC app is:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces: new[] { "myWebApp.Controllers" }
);
}
}
The order in which these are called is:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
Create a controller to handle that route so it does not fail with not found
Like
[RoutePrefix("api")]
public class MyEmptyController : ApiController {
//GET api
[HttpGet]
[Route("")]
public IHttpActionResult Get() {
return StatusCode(HttpStatusCode.NoContent); //204
}
}
Using attribute routing as it is already enabled via config.MapHttpAttributeRoutes(); in WebApiConfig
Your route config is different from your WebApi config and I don't know the order that you are calling them.
in your RouteConfig:
url: "{controller}/{action}/{id}",
which means: http://localhost:PORTNUMBER/myApi1/ACTION
in your WebApiConfig
routeTemplate: "api/{controller}/{id}",
(method and id are optionals)
which means: http://localhost:PORTNUMBER/api/myApi1/?id=value
change your WebApiConfig, and you even will be able to avoid using the Route tag in your controller :
[IdentityBasicAuthentication]
[Authorize]
public class myApi1Controller : ApiController
{
[HttpGet]
public string Get(string id) {
return "works!";
}
}
Edit:
Keep every thing the same, Invoke your default GET method from:
http://localhost:PORTNUMBER/api/myApi1
I'm new to API designing with VS2017 and I'm trying to make my simple API work with few SQL objects in a DB.
I have a fairly simple project which looks like this :
WebApiConfig.cs :
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 }
);
}
Which I believe is stock so should get me where I want to.
I have some controllers based on the same principles, here's one for example :
public class UsersController : Controller
{
private APIContext db = new APIContext();
// GET: Users
public ActionResult Index()
{
return View(db.Users.ToList());
}
// GET: Users/Details/5
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Users users = db.Users.Find(id);
if (users == null)
{
return HttpNotFound();
}
return View(users);
}
}
There are more of them, but everything has been autogenerated so I don't think I have to show them.
The problem is that when I get to localhost/api/users, I get the 404 error page :
No HTTP resource was found that matches the request URI 'http://localhost:myport/api/users'.
Same thing when I'm trying to access a specific id with /api/users/1
Can anyone point me where I should try and change things ?
I'm lost in the jungle of the config files and routes !
Thanks !
EDIT :
After some good answers, here's some more information:
I'm wondering if the issue is not somewhere else. When I'm on the localhost/api, I get a "beautiful" error page but when I try to access the /api/users/index I get an XML response with a 404 message in it. Is that a sign of another problem ?
Something to note is that the Swagger UI shows absolutely nothing.
Your Routing configuration mentions only a Controller in the template without a default Action associated with.
Multiple choices are available to you, however, I would suggest to go for a simple one as in:
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 { action = "index", id = RouteParameter.Optional }
);
}
Now the Action is part of the template, with a default value of index, you will have the following:
http://localhost:myport/api/users redirecting to UsersController.Index
http://localhost:myport/api/users/index redirecting to UsersController.Index
http://localhost:myport/api/users/details redirecting to UsersController.Details
http://localhost:myport/api/users/details/123 redirecting to UsersController.Details
Edit After a second investigation, it appears that you are using an MVC Controller rather than a WebApi Controller. While they both have the same name, they belong to different namespaces and need their own config.
In order to configure your MVC controller route, ensure to have a class as follow in your App_Start folder:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { action = "Index", id = UrlParameter.Optional }
);
}
}
Then, from the Global.asax, in Application_Start method, ensure to have the following call:
RouteConfig.RegisterRoutes(RouteTable.Routes);
as in:
protected void Application_Start()
{
RouteConfig.RegisterRoutes(RouteTable.Routes);
GlobalConfiguration.Configure(WebApiConfig.Register);
}
From this point, you can now access your controller via http://localhost:myport/users.
On the other end, if you want to do an API returning data rather than views, you would need your controller to inherit from ApiController.
Use http://localhost:yourport/users/index" instead.
The URL format is always Controller/Action/Parameters.
Add a new route with {action}
config.Routes.MapHttpRoute(
name: "MyNewRoute",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { type = RouteParameter.Optional }
URL: http://localhost:myport/api/users/details/123456
For supportability reasons I'm porting an application from .Net Core with ReactJs to .Net MVC.
This also uses Redux for state handling.
This seemed to be going ok but for some reason the WebAPI calls all fail with 404 errors.
I'm pretty sure the routing is correct as per the failing calls but clearly something is getting lost somewhere.
The default MVC controller that was added as an entry point works fine, it's just the ported WebAPI controllers that seem to fail.
I'm not allowed to post the entire code for commercial reasons but this is what the controller and one of the actions in question looks like:
namespace Api.Controllers
{
/// <summary>
/// Account management.
/// </summary>
[Authorize]
[System.Web.Http.RoutePrefix("api/account")]
public class AccountController : ApiController
{
// <snip>
/// <summary>
/// Current logged in account.
/// </summary>
// GET api/Account/UserInfo
[HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
[System.Web.Http.Route("userinfo")]
public async Task<UserInfoViewModel> GetUserInfo()
{
ExternalLoginData externalLogin = ExternalLoginData.FromIdentity(User.Identity as ClaimsIdentity);
var userName = User.Identity.GetUserName();
var account = new AccountRepresentation(await _context
.Accounts
.SingleOrDefaultAsync(acc => acc.Email == userName));
return new UserInfoViewModel
{
Account = account,
UserName = User.Identity.GetUserName(),
Email = User.Identity.GetUserName(),
HasRegistered = externalLogin == null,
LoginProvider = externalLogin != null ? externalLogin.LoginProvider : null,
Roles = await UserManager.GetRolesAsync(User.Identity.GetUserName())
};
}
// </snip>
}
}
(snip comments added by me)
Notice the routing attributes - it's a bit over the top as I'm trying everything, but as far as I can tell this should be ok.
However in the browser console I'm seeing this:
Failed to load resource: the server responded with a status of 404
(not found) http://localhost:49690/api/account/userinfo
The port number is correct for the default controller so unless it's different for the other controllers for some reason, this should be ok as well.
I've been playing with the RouteConfig.cs file which currently looks as follows:
namespace Api
{
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces: new[] { "Api.Controllers" }
).DataTokens.Add("area", "UI");
routes.MapRoute(
name: "api",
url: "api/{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces: new[] { "Api.Controllers" }
).DataTokens.Add("area", "UI");
}
}
}
The WebApiConfig file looks as follows:
namespace Api
{
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 }
);
// Web API configuration and services
// Web API routes
// config.MapHttpAttributeRoutes();
// Configure Web API to use only bearer token authentication.
// config.SuppressDefaultHostAuthentication();
// config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
//config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
//config.Routes.MapHttpRoute(
// name: "DefaultApi",
// routeTemplate: "api/{controller}/{id}",
// defaults: new { id = RouteParameter.Optional }
//);
}
}
}
Application_Start() is like this:
namespace Api
{
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
//UnityConfig.RegisterComponents();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
log4net.Config.XmlConfigurator.Configure();
}
}
}
What else could be missing or wrong that is preventing the API actions being found?
(Let me know if any other code would be helpful)
Other details:
Visual Studio version: Enterprise 2015 update 3
.NET version: 4.6.1
In .Net Core, attribute routing is now enabled by default. However, in MVC5, you are need to set it up. In your route config, add this:
routes.MapHttpAttributeRoutes();
Note that for normal MVC (i.e. not WebAPI) you need this command instead:
routes.MapMvcAttributeRoutes();
Note: MapHttpAttributeRoutes is an extension method in System.Web.Http so you will need a using System.Web.Http; statement.
if you Porting .net Core application from .net mvc you have add WebApiConfig file and register in global file. and it should be like this. First use Route Attribute because you have use Attribute routing.
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 }
);
}
I'm accessing a WebAPI resource like this:
localhost/myapp/api/values?ParamOne=123&ParamTwo=testing
In ValuesController, I have this:
public class MyParams {
public int? ParamOne {get;set;}
public string ParamTwo {get;set;}
}
[HttpGet]
public HttpResponseMessage Get([FromUri]MyParams someparams) {
...
}
When I try to access the resource, I get this error:
HTTP Error 403.14 Forbidden The Web server is configured to not list
the contents of this directory
Here's the RouteConfig.cs, which is just the default:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new {controller="Home", action="Index", id=UrlParameter.Optional}
Anyone know what I'm doing wrong?
Your WebAPI Get endpoint is expecting someparams as parameter not ParamOne and ParamTwo.
Changing your endpoint signature to the below should work with the given URL:
localhost/myapp/api/values?ParamOne=123&ParamTwo=testing
public HttpResponseMessage Get(int? ParamOne, string ParamTwo)
Updates
The route configuration above in your question is for MVC controller not WebAPI Controller. See below for WebAPI route config:
public static class WebApiConfig
{
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 }
);
}
}
In Global.asax.cs Application_Start() method, it is registered like so:
GlobalConfiguration.Configure(WebApiConfig.Register);
NuGet packages required:
Microsoft.AspNet.WebApi.Core
Microsoft.AspNet.WebApi.WebHost
One more thing, your controller must inherit from ApiController not Controller