7

I would like to have an Index action with an optional string parameter. I'm unable to make it work.

I need the following routes:

http://mysite/download
http://mysite/download/4.1.54.28

The first route will send a null model to the Index view, and the second one will send an string with the version number.

How can I define the route and the controller?

This is my route definition:

routes.MapRoute(
    name: "Download",
    url: "Download/{version}",
    defaults: new { controller = "Download", action = "Index", version = UrlParameter.Optional }
);

 routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

And this is the controller:

    public ActionResult Index(string version)
    {
        return View(version);
    }

Why does this not work? I'm not an expert in ASP MVC but this seems to be a very simple problem.

The error

  • When I go to http://mysite/downloads it works fine
  • When I go to http://mysite/downloads/4.5.6, the controller is correctly called, and the parameter is correctly passed. But then seems that the view is not found. This is the error I found:

enter image description here

11
  • public ActionResult Index(string version="") { return View(version); } Commented Sep 16, 2014 at 11:11
  • 1
    Do you have other routes defined? Is this one defined before the default route? Commented Sep 16, 2014 at 11:11
  • 2
    Your route has action="Version" but your method is Index(string version) Commented Sep 16, 2014 at 11:14
  • 2
    The problem is the dots in the version parameter. Try http://mysite/download/4-1-54-28 and the action method should be hit Commented Sep 16, 2014 at 11:21
  • 1
    Then its something else. I just copied you code into my project and it works fine. Commented Sep 16, 2014 at 11:28

7 Answers 7

7

string? will not work because string is not a value type.

You can set a default value to your parameter:

public ActionResult Index(string version="")
{
    return View(version);
}
Sign up to request clarification or add additional context in comments.

Comments

5

The issue is fixed passing the parameter to the view in the following way:

public ActionResult Index(string version)
{
    return View((object)version);
}

Or

public ActionResult Index(string version)
{
    return View("Index", version);
}

When you pass a string model to the view, if the model is a string parameter, it is interpreted as the view name due to the following overload method

View(String viewName)

Comments

1

Your Download route is conflicting with your Default route. Comment out the Download route and it will probably work.

BTW you can install RouteDebugger to figure out these kind of problems for yourself.

1 Comment

Please simplify your question as much as possible before posting. The dots were misleading. What happens if you change your controller method to just expect an int? What happens in a brand new solution? Have you tried RouteDebugger or Glimpse?
1

Your controller is looking for a view with the same name as the version attribute entered in the url (e.g. 4.1.54.28). Are you intentionally looking for a view with that name, in which case it should be in the Views/Download folder or your project. If however you simply want to pass it to the default view as a variable to be used on the page your best off sticking it in a model or you can just stick it in ViewBag if it's a one off.

Also you don't need to use:

Public ActionResult Index(string version)

You can use routedata instead e.g.

Public ActionResult Index()
{
    string version = RouteData.Values["Version"].ToString();

    ViewBag.version = version;

    return View();
}

Hope this of some help

Comments

0

You are not set action name in url like {action} you can try:

routes.MapRoute(
        name: "Download",
        url: "Download/{action}/{version}",
        defaults: new { controller = "Download", action = "Index", version = UrlParameter.Optional }
    );

Comments

0

I'm pretty sure it's because in the View you state it is an optional parameter, but your controller says that it is mandatory. Change the signature of your index method to expect a nullable param

    public ActionResult Index(string? version)
    {
        return View(version);
    }

Comments

-1

Why not have two methods in your download controller:

public ActionResult Index()
{
        return View();
}
[HttpGet, ActionName("Index")]
public ActionResult IndexWithVersion(string version)
{
        return View(version);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.