symfony No route found for "GET - symfony

I changed the name of my controller and the routes in the controller and the templates that correspond to it. I even executed the bin/console debug:route to check routes terminal
but when I type http:/localhost:8000/admin/programation/circuit I get an error : No route found for "GET /admin/programation/circuit".
error
Remark: everything was working perfectly before I change the controller name and the routes.
enter image description here

Your route is not correct. To you try to call the route
/admin/programation/circuit
But your route is
/admin/programation/circuit/
So i think that is the problem in your case. So you have to add the / or you should remove them from your action.

The trick is that with the symfony routing system we could not declare a route with a path that ends with '/' only if the path of the rotue is outright the '/' (not préfixed with any thing).
In our case, the index() function is pointed to a route prefixed by '/admin/programation/circuit' and ended with '/' otherwise the following route becomes '/admin/programation/circuit/' and as you can see, it does not respect the convention.
What I tell you, is to redefine the configuration in this way, so that the path becomes empty for the index() function. To define you route in a proper way, you can prefix even the name of the route (from version 3.4)
/**
* #Route("/admin/programation/circuit", name="admin_programtion_circuit_")
*/
class BackofficeProgramationController {
/**
* #Route("", name="index")
*/
public function index() {...}
}

Related

How to get rid of route-name conflicts when ensuring api works both with and without the api-version?

I want to apply asp.net api-versioning to my web app (which didn't have versioning). However, the tricky issue is that I must ensure that APIs should work both with and without the api-version.
[ApiVersion("1.0")]
[Route("api/products/{productId}/[controller]")]
[Route("api/v{version:apiVersion}/products/{productId}/[controller]")]
[ValidateModel]
[Produces("application/json")]
public partial class ProductController : ControllerBase {
internal const string GetLatestRoute = "GET Product/GetLatestAsync";
[HttpGet(Name = GetLatestRoute)]
public async Task<IActionResult> GetLatestAsync() {
}
}
I have a controller with multiple actions, each of them is defined with a unique route name. When I add two routes (with and without versions) to the controller, there comes a route-name conflict error:
Attribute routes with the same name 'GET Products/GetLatestAsync' must have the same template:
Action: 'Service.Controllers.ProductController.GetLatestAsync (ProductFD)' - Template: 'api/products/{productId}/Product'
Action: 'Service.Controllers.ProductController.GetLatestAsync (ProductFD)' - Template: 'api/v{version:apiVersion}/products/{productId}/Product'
There are several answers on StackOverflow that say the issue can be solved by removing the route names defined for the action methods. However, in my scenario, the route names are used to create Url Links in several places in the project.
Is there an approach that I can get rid of the issue? I'm wondering whether I could append version to the route name variable or mapping the non-version api to the version/1.0 ...? On the other hand, there is a rare case that I update all the methods in a controller. So is it possible that I only define a route-prefix on the top-level of the controller and only apply the api-version on the method-level?
Route names and the route table are not API version aware. In order for this to work, you need to use double route registration like you have because you are versioning by URL segment (not recommended). If clients are properly following the links returned by the server, then always using the route generated with the explicit version in it will do. If the client doesn't honor that and just calls the APIs directly without the API version, the second template will handle that for you. If you are only generating links with the same controller, then I would suggest using CreatedAtAction instead because it will not rely on the route name. If memory serves me correct, you can specify the order of each [Route] for precedence. If unspecified, it will be the first attribute specified - which matters.
You'll also need to enable:
services.AddApiVersioning(options => options.AssumeDefaultVersionWhenUnspecified = true);
If you haven't already.
Last, but not least, beware the known, breaking change: Async suffix trimmed from controller action names. This has snared many people.

Routing redirection not working properly (Symfony 3)

I have an issue with my application, I have several routes declared on my controller which works properly but I have trouble with one of them.
I used the annotation system to declare the route of this method (like all my routes which works) like this :
/**
* Do something
*
* #Route("/synchro", name="app_synchro")
*/
public function synchroAction(Request $request){
//code here etc...
}
I checked it with the debug:router command so I know this route exists, I also tried to print $route and the value is good but when I made a redirection using :
return $this->redirectToRoute('app_synchro');
I encounter a 404 error.
Please, could someone help me to understand the origin of this issue ?
The proper way to redirect is to return it directly like so:
return $this->redirectToRoute('my_route_name');
What you are doing is returning the result code of redirecting...
$route= $this->redirectToRoute('my_route_name');
So $route contains the result of the redirect, which is NOT what you want.

asp.net web api route for controllers with same name

I am integrating my project with another one
Multiple types were found that match the controller named 'XXXXX'.
This can happen if the route that services this request ('api/{controller}/{action}/{id}') found multiple controllers defined with the same name but differing namespaces, which is not supported.
The request for 'XXXXX' has found the following matching controllers:
COM.example.host.XXXXXController
COM.example.parasite.XXXXXController
Is there a way to make this somehow work with the least amount of edit from either side?
I would like to avoid having to make modifications to all of my controllers.
Thank you
Unfortunately, that is not very simple because default controller selector (DefaultHttpControllerSelector) does not look for namespace in the full controller name when it selects controller to process request.
So, there are at least two possible solutions to your problem:
Write your own IHttpControllerSelector which takes controller type namespace into account. Sample can be found here.
Rename one of controller types to make then unique.
TL;DR Default controller selector uses the cache of controller types (HttpControllerTypeCache) which holds something like:
{
"Customers" : [
typeof(Foo.CustomersController),
typeof(Bar.CustomersController)
],
"Orders" : [
typeof(Foo.OrdersController)
]
}
So it uses controller name as dictionary key, but it can contain several types which have same controller name part. When request is received, controller selector gets controller name from route data. E.g. if you have default route specified "api/{controller}/{id}" then request api/customers/5 will map controller value to "customers". Controller selector then gets controller types which are registered for this name:
if there is 1 type, then we can instantiate it and process request
if there is 0 types, it throws NotFound exception
if there is 2 or more types, it throws AmbiguousControllerException exception (your case)
So.. definition of another named route will not help you, because you can only provide controller name there. You cannot specify namespace.
Even if you'll use Attribute Routing and specify another route for one of the controller actions
[RoutePrefix("api/customers2")]
public class CustomersController : ApiController
{
[Route("")]
public IHttpActionResult Get()
//...
}
you will still face the controller selector problem because attribute routes are applied to actions - there will be no controller value in route data for those requests. Attributed routes are treated differently - they are processed as sub-routes of the "MS_attributerouteWebApi" route.
The easiest path for you might be to add action based routing to your web api:
RouteTable.Routes.MapRoute(
"WithActionApi",
"api/{controller}/{action}/{id}"
);
To your WebApiConfig.cs, be sure to put it above the default rule. Then, change how you call your controllers by including the method name, which at this point should be or should be made unique.

Symfony2 impersonation route parameters missing

I receive an error when I change pages if I am impersonated as another user in Symfony2. It only happens when the route has additional parameters. There is no sign of route generation at the pointed line number.
Controller action
/**
* #Route("/member/{id}", name="member_page")
* #Template()
*/
public function memberAction($id)
Error
An exception has been thrown during the rendering of a template ("Some mandatory parameters are missing ("slug") to generate a URL for route "member_page".") in members.html.twig at line 2.
Do you have two routes with the same name?
Watch your routing.yml file or the class annotation, maybe you have defined a prefix with slug parameter.
If the "slug" parameters is not necessary, provide a default for that as NULL. Here is an example
message_edit:
pattern: /edit/{slug}
defaults: { _controller: CommunicationBundle:Default:edit, slug: null }
Thanks for the answers, but there was something else going on:
The template was extending another template in which the bug could be found. Therefor an incorrect linenumber was displayed in the eror message. After setting up a smaller test environment I could replicate the problem. It was an anchor to exit impersonation which I wanted to redirect to the current page, but was obviously missing the parameters of the current page:
Stop impersonation
I fixed it for now by just using the named 'home' route.

How to pass arguments to controller from route in Symfony2

I'm working on a Symfony2 project and am trying to figure out how to pass parameters from the route configuration to the controller. I know I can configure default values in the route configuration, and retrieve the values in the controller using the appropriate var name in the function declaration, but that isn't exactly what I want.
My use case is the following. I have a standard method in my controller that I want to access from 2 or 3 different routes. Depending on which route is being called, I want to "configure" the method differently. I can accomplish this in a few ways:
In my controller, check the route name using `$this->container->get("request")->get("_route"), but that is ugly, and then I am hardcoded to the route name. Moves configuration to the controller, which should just be logic - not configuration.
Create a base controller class, and subclass each method for my different routes. Each subclassed method would then have the necessary configuration within the method. Cleaner soln than #1, but still "heavy" in the sense of having multiple classes for a simple need and still pushes configuration data into the business logic.
Put configuration data into the route configuration. In the controller, access the configuration data as required. Ideal solution, but don't know how.
I can use the route default array to specify my arguments, but then must make sure to use a regex to ensure that the params are not overridden at the URL level (security risk). This is functional, but still kinda cludgy and not a pretty hack.
I presume that there must a better way to do this, but I can't seem to figure it out. Is there a way to access the routing object from the controller, and access the different configuration parameters?
You can pull the actual route from the router service. Something like:
$routeName = $this->container->get("request")->get("_route");
$router = $this->container->get("router");
$route = $router->getRouteCollection()->get($routeName);
Not sure if this would be such a great design though. Consider passing a $configName to your controller method, adding a parameter with the same name in a config file then using getParameter to access it. That would eliminate the route stuff from the equation.
Something like:
zayso_arbiter_import:
pattern: /import
defaults: { _controller: ZaysoArbiterBundle:Import:index, configName: 'someConfigName' }
public function importAction(Request $request, $configName)

Resources