How to get via route details in here map route? - here-api

I am able to get the following details from route object like :
route duration,route length and eta etc..
Route route = routeResultList.get(position).getRoute();
int routeDuration = route.getTtaExcludingTraffic(Route.WHOLE_ROUTE).getDuration();
int routeLength = mapRoute.getRoute().getLength();
Similarly I want to get via route details as well.

You can make use of getManeuvers() method to get the complete details of the via route details.
java.util.List getManeuvers()
Gets the list of all maneuvers that travelers will encounter along the route.
Please refer the below API reference, for the different methods available for Route class object.
https://developer.here.com/documentation/android-premium/3.18/api_reference_java/index.html

Related

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)

Authorize request in ASP.NET Web API based on specific user

I followed this tutorial http://www.tugberkugurlu.com/archive/api-key-authorization-through-query-string-in-asp-net-web-api-authorizationfilterattribute
to create custom Authorization filter.
I have CarController with my custom Authorize Attribute:
[ApiKeyAuth("apiKey", typeof(ApiKeyAuthorizer))]
I send two parameters in the url .. host/Car/4?username=xxx&pass=xxx
It works basically fine, however I want to allow only car owners to see information about their cars.
E.g. user ABC can see only host/Car/5 and user DEF can see host/Car/6 and host/Car/10
how can I solve this scenario?
How can I access the id of the car used in query (host/Car/ID) in my ApiKeyAuthorizer.
Greetings
If you look at his code, https://github.com/tugberkugurlu/ASPNETWebAPISamples/tree/master/TugberkUg.Web.Http/src/samples and https://github.com/tugberkugurlu/ASPNETWebAPISamples/tree/master/TugberkUg.Web.Http/src/TugberkUg.Web.Http, I think you'll find that he's pulling the data directly from the query string. It should simply be a matter of extending that method to pull in the id parameter. You might also want to look at the RequestContentKeyValueModel on the HttpActionContext parameter passed into the OnAuthorization method. The documentation is sketchy and I haven't played with it yet, but that seems like a likely candidate to me. However, the route data is available indirectly through the HttpRequestMessage via an extension method, specifically:
message.GetRouteData();

What is Ambient Route Values in ASP.NET MVC and how it works?

I am new to ASP.NET MVC. I read Professional ASP.NET MVC 3 and it has two pages talk about Ambient Route Values but I don't understand how it works. I search "asp.net mvc ambient route values" on google and still not find any articles or websites that explain what is it or how it works.
I want to know what is "Ambient Route Values" in ASP.NET MVC? How it works?
Ambient route values are related to all those values that are not needed for the current route outbound processing.
Let's explain through an example
Take for instance this route definition:
routes.MapRoute(
"Complex",
"{securityArea}/{permission}/{action}/{id}",
new { controller = "Administration", action = "List", id = UrlParameter.Optional }
);
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
The scenario of ambient route values in this case would be:
User does some administration, so he's currently on URL served by the first route definition:
/users/change/apply/45
He edits some form on this URL and posts data back.
When he hits the server (executes some controller action), all of those route values get populated and are part of the context's route values now.
Controller does what it has to do and in the end we want it to redirect to non-admin part of the application, so hitting the second Default route.
Now if we take a look of the URL generation in #4. What happens?
route values that are defined during request are:
controller = "Administration"
action = "Apply"
securityArea = "Users"
permission = "Change"
id = 45
Only the first two are needed to generate the URL of the second Default route
What happens with the rest ambient route values?
They get added to the URL as well:
/Home/Index/?securityArea=Users&permission=Change
And we don't want that.
That's why they're called ambient because they are just *hanging in there orphaned in the request. This is my explanation of ambient route values. Hopefully explained in an understandable way.
I've also written about removing these ambient values in one of my blog posts where I've provided a custom route class that does this removal.
As referred on page 232
Ambient route values in the book that you linked also refer to outbound route processing but it talks about ambient values as those that we don't need to supply for outbound route processing because they will be taken from current values (namely controller and action may as well be ambient values).
Book though doesn't talk about the problem with ambient route values that I outlined in my upper answer. All defined route values can be ambient and they may cause problems when we don't realise how routing works.
The url generated does not need to contain the controller or action params of the current request. The page param indicated in the example is matched as one of the params in the RouteData, and the controller and action, since they weren't supplied, remain as they are on the current request.

Asp.NET MVC Route Performance

I have an application with a couple thousand routes.
This is because for each product we use a custom URL, as opposed to the textbook /product/id.
With this many urls, the performance is unacceptable in the router.
I am trying to find ways to improve it, but I am drawing a blank.
I have about 20 regex routes and about 3 thousand unique url routes.
Any Ideas?
Sorry for being so open ended, but I am not sure where to start.
If your urls are all on the format yoursite.com/{url}, you can still store all the three thousand urls in the database, and create a custom controller factory which uses the {url} parameter to look the correct information up in the database and assign correct controller, action and any parameters you're using.
There are lots of posts on google on how to implement the controller factory.
I imagine you'll also want some parsing of the existing routes to put them all in the database - this can probably be done by iterating over the RouteTable after you instantiate your application (i.e. after RegisterRoutes() is called).
I would get rid of the 3 thousand unique url routes and replace them with a generic route that is the last catch-all route. Something like:
routes.MapRoute("productRoute", "{category}/{manufacturer}/{productTitle}", new { controller = "Products", action = "Index", category = UrlParameter.Optional, manufacturer = UrlParameter.Optional, productTitle = UrlParameter.Optional });
You could also then add a custom IRouteConstraint to validate that the category exists (but just make sure it doesn't hit your database every time or performance will degrade).

Asp.net MVC RouteBase and IoC

I am creating a custom route by subclassing RouteBase. I have a dependency in there that I'd like to wire up with IoC. The method GetRouteData just takes HttpContext, but I want to add in my unit of work as well....somehow.
I am using StructureMap, but info on how you would do this with any IoC framework would be helpful.
Well, here is our solution. Many little details may be omitted but overall idea is here. This answer may be a kind of offtop to original question but it describes the general solution to the problem.
I'll try to explain the part that is responsible for plain custom HTML-pages that are created by users at runtime and therefore can't have their own Controller/Action. So the routes should be either somehow built at runtime or be "catch-all" with custom IRouteConstraint.
First of all, lets state some facts and requirements.
We have some data and some metadata about our pages stored in DB;
We don't want to generate a (hypothetically) whole million of routes for all of existing pages beforehand (i.e. on Application startup) because something can change during application and we don't want to tackle with pushing the changes to global RouteCollection;
So we do it this way:
1. PageController
Yes, special controller that is responsible for all our content pages. And there is the only action that is Display(int id) (actually we have a special ViewModel as param but I used an int id for simplicity.
The page with all its data is resolved by ID inside that Display() method. The method itself returns either ViewResult (strongly typed after PageViewModel) or NotFoundResult in case when page is not found.
2. Custom IRouteConstraint
We have to somewhere define if the URL user actually requested refers to one of our custom pages. For this we have a special IsPageConstraint that implements IRouteConstraint interface. In the Match() method of our constraint we just call our PageRepository to check whether there is a page that match our requested URL. We have our PageRepository injected by StructureMap. If we find the page then we add that "id" parameter (with the value) to the RouteData dictionary and it is automatically bound to PageController.Display(int id) by DefaultModelBinder.
But we need a RouteData parameter to check. Where we get that? Here comes...
3. Route mapping with "catch-all" parameter
Important note: this route is defined in the very end of route mappings list because it is very general, not specific. We check all our explicitly defined routes first and then check for a Page (that is easily changeable if needed).
We simply map our route like this:
routes.MapRoute("ContentPages",
"{*pagePath}",
new { controller = "Page", action = "Display" }
new { pagePath = new DependencyRouteConstraint<IsPageConstraint>() });
Stop! What is that DependencyRouteConstraint thing appeared in mapping? Well, thats what does the trick.
4. DependencyRouteConstraint<TConstraint> class
This is just another generic implementation of IRouteConstraint which takes the "real" IRouteConstraint (IsPageConstraint) and resolves it (the given TConstraint) only when Match() method called. It uses dependency injection so our IsPageConstraint instance has all actual dependencies injected!
Our DependencyRouteConstraint then just calls the dependentConstraint.Match() providing all the parameters thus just delegating actual "matching" to the "real" IRouteConstraint.
Note: this class actually has the dependency on ServiceLocator.
Summary
That way we have:
Our Route clear and clean;
The only class that has a dependency on Service Locator is DependencyRouteConstraint;
Any custom IRouteConstraint uses dependency injection whenever needed;
???
PROFIT!
Hope this helps.
So, the problem is:
Route must be defined beforehand, during Application startup
Route's responsibility is to map the incoming URL pattern to the right Controller/Action to perform some task on request. And visa versa - to generate links using that mapping data. Period. Everything else is "Single Responsibility Principle" violation which actually led to your problem.
But UoW dependencies (like NHibernate ISession, or EF ObjectContext) must be resolved at runtime.
And that is why I don't see the children of RouteBase class as a good place for some DB work dependency. It makes everything closely coupled and non-scalable. It is actually impossible to perform Dependency Injection.
From now (I guess there is some kind of already working system) you actually have just one more or less viable option that is:
To use Service Locator pattern: resolve your UoW instance right inside the GetRouteData method (use CommonServiceLocator backed by StructureMap IContainer). That is simple but not really nice thing because this way you get the dependency on static Service Locator itself in your Route.
With CSL you have to just call inside GetRouteData:
var uow = ServiceLocator.Current.GetService<IUnitOfWork>();
or with just StructureMap (without CSL facade):
var uow = ObjectFactory.GetInstance<IUnitOfWork>();
and you're done. Quick and dirty. And the keyword is "dirty" actually :)
Sure, there is much more flexible solution but it needs a few architectural changes. If you provide more details on exactly what data you get in your routes I can try to explain how we solved our Pages routing problem (using DI and custom IRouteConstraint).

Resources