4

I have been working on desktop applications mostly and thought to learn web development using ASP.Net MVC5 and thus going through the book by Jon Galloway. So I was reading about how you can pass the parameters to action methods using query string like

/Store/Browse?genre=Disco

or directly embed them in the url like

/Store/Details/5

Now the controller code that I wrote (taken from book) is below :

namespace MvcMusicStore.Controllers
{
    public class StoreController : Controller
    {
        // GET: Store
        public string Index()
        {
            return "Hello from Store.Index()";
        }

        public string Browse(string genre)
        {
            string message = HttpUtility.HtmlEncode("Store.Browser, Genre = " + genre);
            return message;
        }

        public string Details(int id)
        {
            string message = "Store.Details, ID = " + id;
            return message;
        }
    }
}

The url opens fine and the actions return the message as expected. But just to try I tried to pass the genre value by embedding it in the url like

/Store/Browse/Rap

but that doesn't work like it did for the Details() action. I thought it may have to do something with the datatype of genre, so I tried changing the data type of id in Details() to string as below :

public string Details(string id)
        {
            string message = "Store.Details, ID = " + id;
            return message;
        }
}

and opened the url

/Store/Details/5

and the Details() action returns message with id value 5, but when i do the same for Browse() action

/Store/Browse/Rap

the action doesn't return the message with genre value "Rap". I tried to pass the genre value and removed the html encoding to see if that had anything to do with it, but it didn't.

I looked at the post here but that didn't help either. Any comments appreciated.

Community
  • 1
  • 1
Naphstor
  • 2,356
  • 7
  • 35
  • 53

1 Answers1

4

Your using the Default route which is defined as

url: "{controller}/{action}/{id}",

and expects a value for id. When you use /Store/Browse/Rap, then the value of the 3rd segment ("Rap") will be bound to a paramater named id, but your Browse() method does not contain one (its named genre).

Either change the name of the parameter so its

public string Browse(string id)

and the value of id will be "Rap",

Or create a specific route definition and place it before the Default route (and keep the Browse() method as is)

routes.MapRoute(
    name: "Browse",
    url: "Store/Browse/{genre}",
    defaults: new { controller = "Store", action = "Browse", genre = UrlParameter.Optional }
);
... // default route here

Side note: You do not need to change the type of the parameter in the Details method if your always passing a value that is a valid int