OData gives result only after making a web API request - odata

I have created an Odata in web Api 2
I am adding routes like
config.MapODataServiceRoute(
routeName: "ODataRoute",
routePrefix: "odata",
model: GetModel()
);
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
I am getting a strange result.
If I hit the OData service first (after a building/publishing) it is showing the below image.
But if I hit an api request first and making the OData request next,
then I am getting the expected JSON.
In short an OData request works only after making an API request.
Can anyone say what would be reason for this behavior?

Order matters. Try moving the OData config after the Web API config:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.MapODataServiceRoute(
routeName: "ODataRoute",
routePrefix: "odata",
model: GetModel()
);
If you don't have any regular Web API controllers, eliminate the call to MapHttpRoute entirely.

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.

web api 404 error after hosting in existing web application

I have developed a Web Api and I created a directory/folder(myWebApi) on the server where my web application(www.mydomain.com) is already hosted. I Hosted/uploaded that web api in that folder myWebApi and when i try to access
www.mydomain.com/myWebApi/api/mycontroller/action
its returning a 404 error
HTTP Error 404.0 - Not Found
The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.
here is my WebApiConfig
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "myWebApi/api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "DefaultApi1",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
Please give me solution.

Non Api routing with SPA and Web Api

I have been trying for a few days to solve this problem so I may in fact be trying to solve the wrong problem or don't know the right terms to search so here goes.
I'm creating a SPA with AngularJS and Web Api (4.5). All of my views are client side. So the server doesn't know all the possible routes that may become present in the URI. This isn't a problem until a user uses one of the browser controls (back, forward, refresh, history) and the server attempts to route the requested URI.
My thoughts on dealing with this have centered around mapping all non API routes to the root of the application.
So I would like to either, know the correct syntax for MapHttpRoute to pick up any route that does not attempt to reference controllers (API's) or if there is a better method for dealing with this problem.
public static void Register( HttpConfiguration config )
{
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
//
// This doesn't work
//
config.Routes.MapHttpRoute(
name: "Default",
routeTemplate: "{*catchall}"
);
}
This XML file does not appear to have any style information associated with it. The document tree is shown below.
No HTTP resource was found that matches the request URI 'http://localhost:9234/login'.
No route providing a controller name was found to match request URI 'http://localhost:9234/login'
Not a good idea, just workaround
config.Routes.MapHttpRoute(
name: "Default",
routeTemplate: "{*catchall}",
defaults: new { controller = "Spa"}
);
[AllowAnonymous]
public sealed class SpaController : ApiController
{
public HttpResponseMessage Get()
{
var indexHtml = HostingEnvironment.MapPath("~/index.html");
var stringContent = new StreamContent(File.OpenRead(indexHtml));
var response = new HttpResponseMessage(HttpStatusCode.OK) {Content = stringContent};
return response;
}
}

No HTTP resource was found that matches the request URI

I just deployed my MVC app to a subdomain and I just can't get webapi to work.
Accessing locally:
localhost:40052/api/apiEmpreendimento/GetObjects
works just fine, but accessing the following online:
http://subdomain.mysite.com/api/apiEmpreendimento/GetObjects
Gives me
{"Message":"No HTTP resource was found that matches the request URI 'http://subdomain.mysite.com/api/apiEmpreendimento/GetObjects'."}
App_Start/WebApiConfig.cs
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { action = "get", id = RouteParameter.Optional }
);
}
}
Any tip is much appreciated.
Thanks
I thought it's about new WepApi. MVC understands it like WebApi controller, Microsoft Reserved Api Controlller for their selves, I changed my Controller name With MyApiController and problem solved.

Asp.net MVC/Web Api Routing: Need to route a little different

I have setup a asp.net web api project (it works exactly the same as a Mvc Project) using routing - hence i have the following
routes.MapHttpRoute(
name: "API Default",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
So everything works just the way i want it .... I enter api/Products/15 it it arrives in my Products Controller passing in 15 as the id.
Great.
I also have 2 controllers more, 1 called UploadsController and 1 called DownloadsController. These offer Uploads and Downloads (GET / PUT etc)
Now i don't want them to be picked up by the original rule (see above)
But what i would like is to use these 2 urls to access them
/api/Transport/Uploads/15
/api/Transport/Downloads/15
I have passed in 15 as the ID, probably wouldn't happen in real life... just its good for demonstration :-)
Now Transport doesn't exist so i could do the following
routes.MapHttpRoute(
name: "API Default",
routeTemplate: "api/Transports/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
which i believe works...
but the problem is that if i do
/api/Uploads/15 - this would also be caught by the original rule which i don't want..
I want the Uploads and DOwnloads controller to be accessed through the fake "Transports" and not without the Transports
Can anyone help?
Thanks in advance
You could use route constraints and define 2 API routes in the following order:
// matches /api/transports/downloads/id or /api/transports/uploads/id only
// and no other possible controller
routes.MapHttpRoute(
name: "API Transport",
routeTemplate: "api/transports/{controller}/{id}",
defaults: new { id = RouteParameter.Optional },
constraints: new { controller = "uploads|downloads" }
);
// matches anything in the form /api/{controller}/id where {controller}
// could be anythnig different than "downloads" or "uploads" because we don't
// want to allow the following urls: /api/downloads/id and /api/uploads/id
routes.MapHttpRoute(
name: "API Default",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional },
constraints: new { controller = #"^((?!(downloads|uploads)).)*$" }
);

Resources