0

Global.asax:

   void Application_Start(object sender, EventArgs e)
        {
   public class Global : HttpApplication
    {
      GlobalConfiguration.Configure(config =>
            {
                config.MapHttpAttributeRoutes();

                RouteTable.Routes.MapHttpRoute(
                    name: "DefaultApi",
                    routeTemplate: "api/{controller}/{action}");
            });

}}

i get this url for example :

http://localhost:54404/books/20

what i want instead (appending the name of the book instance 'lawbook'):

http://localhost:54404/books/20/lawbook

Safi Habhab
  • 981
  • 10
  • 17
  • can you guarantee that there will be no other book called "lawbook" in your database? If not, then this can never work because it won't know which record to display. In my admittedly anecdotal experience, it's perfectly possible to come across 2 or more books with the same title, maybe by different authors - or even perhaps just different editions of the same work by the same author. It strikes me that this scheme is a little naive. If you're trying to make a more friendly URL, perhaps you could include the book name in the URL without actually relying on it. – ADyson Aug 06 '18 at 16:06
  • it is more secured to not show the id of an item , that's what i want , i dont want the id to be displayed – Safi Habhab Aug 06 '18 at 16:09
  • How does that help with security, do you imagine? An ID is just a (more or less) random, unique, and otherwise meaningless identifier for the record in the database. Also, if that's the thing which uniquely identifies the record, then you need it in order to ensure you access the correct record. Hiding things merely hides them from immediate view, it doesn't make them secure. It's called "security by obscurity" and if you google it, you'll find lots of discussion about why it isn't secure. And like I said, your proposed scheme is likely to fail due to duplicate names. – ADyson Aug 06 '18 at 16:11
  • you're probably right , but i was asked to do it as a task in work , and yea in my data base the name is unique , so can you tell me how to do it? and if i do it should i then change the actions parameter from int id to string name or is it not necessary ? – Safi Habhab Aug 06 '18 at 16:14
  • But do you _guarantee_ that the name will _always_ be unique in future? You're not going to include a book in your database if you already have one with the same name...really? That's not a real-world situation. – ADyson Aug 06 '18 at 16:15
  • Also, just because you're asked to do something for your work doesn't make it a good idea. If something's a bad idea, you should challenge it. This is a bad idea, and security is not a justification for it. It doesn't provide security. Besides, if, as you state, your book name _is_ always unique, then it's still an ID, so hiding the other ID doesn't make any difference to anything. You've just got two IDs, that's all. If anything, the book name is _less_ secure because it gives away meaningful info about the record, where a numeric ID doesn't. – ADyson Aug 06 '18 at 16:16
  • that's really sharp , ok now i wont do it but just in case , can you tell me how it is done ? i just want to know how in case i was forced to do so – Safi Habhab Aug 06 '18 at 16:20
  • Ok well if you really are forced to do it, then I don't think you need to change your routes, you can just change to `public ActionResult BookInfos(string id)` and Book bookindb = Context.Books.FirstOrDefault(b => b.BookName==id);`. If you want some kind of _real_ security, then also within that same method you would be checking whether the user has permission to access that record. – ADyson Aug 06 '18 at 18:30
  • 1
    You should not be omitting the ID from the route. But what you can do is create a 'slug' (where the name is added to the route as per SO url's) - Refer [how to implement url rewriting similar to SO](https://stackoverflow.com/questions/30349412/how-to-implement-url-rewriting-similar-to-so/30363600#30363600) for an example –  Aug 06 '18 at 23:37

1 Answers1

0

Global.asax:

inside Global:HttpApplication

//add this
   public RouteValueDictionary SetRouteValueDefault(string name, string value = "")
        {
            return new RouteValueDictionary { { name, value } };
        }

        public void Register(RouteCollection routes)
        {

            routes.MapPageRoute("author", "books/{id}/{name}", "~/Books.aspx", false, SetRouteValueDefault("name"));
        }

inside Application_Start():

//add this
            Register(RouteTable.Routes);

you can now assemble a url of an instance as wanted

<a href="/books/book.id/book.name"></a>  

CREDITS : Ali Kleit

Safi Habhab
  • 981
  • 10
  • 17