Finding action on wep api 2 - c#

Hi I am using wep api 2 to create this route. I have
in my WebConfigApi defined
config.MapHttpAttributeRoutes();
// In Globa.asax
GlobalConfiguration.Configure(WebApiConfig.Register);
My method is decorated as
[Route("api/pO")]
[AcceptVerbs("Getpo")]
[HttpGet]
public IEnumerable<pOver> Getpo()
{
------
}
When I run this using
../api/pO/Getpo
I keep getting error
"<Error><Message>No HTTP resource was found that matches the request URI 'http://localhost:60482/api/pO/Getp0'.</Message><MessageDetail>No action was found on the controller 'prO' that matches the request.</MessageDetail></Error>"
Please let me know how to decorate it properly to run it.
Thanks

I think you want it to look like this:
[Route("api/pO/Getpo")]
[HttpGet]
public IEnumerable<pOver> Getpo()
{
------
}
The AcceptVerbs attribute is meant to do something similar to the HttpGet attribute that you have put on your Action. you could use AcceptVerbs("GET") in place of the HttpGet attribute.

Related

Multiple controller types were found that match the URL. ASP.Net MVC

This is regarding defining routes using route attribute. I have two controllers
1st Controller
[AllowAnonymous]
[Route("Member/Login")]
public ActionResult Login(string returnUrl)
{
ViewBag.ReturnUrl = returnUrl;
return View();
}
2nd Controller
[Route("{CategoryURL}/{Keywords}")]
public ActionResult BrowseProducts(string CategoryURL, string Keywords)
{
}
I am getting below error If try to access URL xyz.net/Member/Login
Multiple controller types were found that match the URL. This can happen if attribute routes on multiple controllers match the requested URL.
The request has found the following matching controller types:
XYZ.Controllers.AccountController
XYZ.Controllers.CoursesController
I am aware that I have Optional Parameters for second controller, hence when I try to access xyz.net/Member/Login, it finds two action methods to go for and getting the Multiple controller error.
My question is, how could I fix this issue without changing my current Routings. I tried Order, Precedence but nothing worked out.
As I commented above, based on your elected tags you are using MVC 4 yet attribute routing is supported in MVC 5. If you really are in MVC 5, then the following reference would be very helpful for you:
https://blogs.msdn.microsoft.com/webdev/2013/10/17/attribute-routing-in-asp-net-mvc-5/
Most importantly, it's crucial that when you register your routes you active attribute routing -->
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapMvcAttributeRoutes();
}
And also ensure you don't have any other routes being defined that could confict with the attributes you've elected to use.
Otherwise your selected attribute should work fine. Pretty simple application.
The web api constraints may also aply for what you are trying to accomplish
http://www.asp.net/web-api/overview/web-api-routing-and-actions

Remove controller name from URL with Attribute routing

I want to remove controller name from URL for specific Controller.
My Controller name is Product
I found some link to do this
Routing with and without controller name
MVC Routing without controller
But all the above links done in route config file. and those are affecting other controller too. I want to do it using Attribute Routing.
Can it is possible? As I want to do this for only Product controller.
I have tried to do it on action like this
[Route("Sample/{Name}")]
but it is not working.
Gabriel's answer is right, however, it can be a bit misleading since you're asking for MVC and that answer is for Web API.
In any case, what you want is to put the annotation over the class definition instead of an action method. MVC example would be like:
[RoutePrefix("SomethingOtherThanProduct")]
public class ProductController : Controller
{
public ActionResult Index()
{
...
return View();
}
}
I'm also dropping this as an answer since you may find the following article helpful: [Attribute] Routing in ASP.NET MVC 5 / WebAPI 2
Make sure you set the RoutePrefix attribute on the whole controller class, as well as using the Route attribute on the action.
[RoutePrefix("notproducts")]
public class ProductsController : ApiController
{
[Route("")]
public IEnumerable<Product> Get() { ... }
}

Web API routing using RouteAttribute - Multiple actions were found that match the reques

In my Web API 2 project I have two POST methods:
[HttpPost]
public virtual IHttpActionResult Create([FromBody]TDto value) { ... }
[Route("many")]
[HttpPost]
public virtual void CreateMany([FromBody]TDto[] value) { ... }
My route template looks like this:
config.Routes.MapHttpRoute(name: "DefaultApi", routeTemplate: "api/{controller}")
When I make a POST to http://server/api/Products I get the following error: "Multiple actions were found that match the request: Create on type ProductsController, CreateMany on type ProductsController"
Why does the method with the RouteAttribute set to "many" match the route? Shouldn't "many" be a mandatory part of the URL?
When I post to http://server/api/Products/many the correct method is called.
I know I can get around the problem by specifying the Order in the Route-attribute, but I want to understand why this is happening.
Edit:
Just found out that if I added an empty route to the Create-method, it works as I want:
[Route("")] // <-- ADDED THIS
[HttpPost]
public virtual IHttpActionResult Create([FromBody]TDto value) { ... }
[Route("many")]
[HttpPost]
public virtual void CreateMany([FromBody]TDto[] value) { ... }
If anyone can explain why this is happening I'm still all ears :-)
OK, maybe this wasn't so strange after all...
In my original setup this is what happens:
When doing a POST to http://server/api/Products/many it matches the second method by its RouteAttribute. No need to check the "DefaultApi"-routing. So that worked.
When doing a POST to http://server/api/Products it does not match any RouteAttribute route so instead it checks the "DefaultApi"-routing andboth methods match the route in config. I get the "Multiple actions..."-exception.
After adding [Route("")] to the first method this is what happens:
The POST to http://server/api/Products/many still works the same way.
When doing a POST to http://server/api/Products it matches the new (empty) RouteAttribute. No need to check "DefaultApi"-routing. Everything works.
I think I believed that the RouteAttribute disabled the "DefaultApi"-route for that method. That was obviously not the case.

Web API 2 default routing scheme

This question suddenly pops up in my mind.
In Startup.cs I have:
HttpConfiguration config = new HttpConfiguration();
config.MapHttpAttributeRoutes();
app.UseWebApi(config);
When I have a method like this one:
[RoutePrefix("api/Order")]
public class OrderController : ApiController
{
// don't use any attribute here
public IHttpActionResult HelloWorld()
{
...
return Ok();
}
}
Is it possible to access HelloWorld()?
Should a GET or POST or whatever action be sent?
You can access to HttpWorld() using GET if you rename your method as: GetHelloWorld().
The same with POST renaming to PostHelloWorld().
But I prefer using [HttpGet], [HttpPost], ... attributes, even if my action methods has the "Get" or "Post" characters in the name, to avoid possible errors.
Updated
After making some tests, I realised that my comments about that is not possible to call the HelloWorld are not correct.
Indeed it is possible to call your HelloWorld() method if you make a POST call to http://<YourProjectUrl>/order.
So, the default method will be POST and, as you haven't configured any Route for your action method (take in account that RoutePrefix is just a prefix, so needs a Route attribute to be considered), it will get your controller name without "Controller" (OrderController -> Order).

Routing Undefined Controllers

How would you set up the routing in ASP.NET MVC in order to route paths with undefined controllers to a specific controller.
For example, I have a UserController, so I would want http://example.com/user to route to the UserController, but I would want http://example.com/supercoolproject to route to the ProjectController in order to find the Super Cool Project item
I believe you shouldn't use http://example.com/supercoolproject address. Instead, it should be http://example.com/project/supercool, but if you want to use address in http://example.com/{projectname}project format, you can define rule in global.asax like this:
routes.MapRoute(
"ProductByNameRule",
"{projectName}project",
new { controller = "Project", action = "ByName" }
);
and have
public ActionResult ByName(string projectName) {
}
in ProjectController.
You can create a custom controller factory to do this.
http://keyvan.io/custom-controller-factory-in-asp-net-mvc
In the CreateController method of the custom controller factory's IControllerFactory implementation first try to create the controller using DefaultControllerFactory, then if this fails create an instance of your fallback controller and return it instead.

Categories