3

I am new to MVC, and trying to navigate via js to a controller action method. The code works (as in the action method is hit), but the parameter value I am passing in is always null

js:

  window.location.href = "@Url.Action("Step1", "Reports")" + "/?" + rsid;

Controller action:

public class ReportsController : Controller    {

     public ActionResult Step1(int? rsid)
        {

          //do stuff
        }
}

The rsid parameter is always null. I have tried various link formats, eg "/?rsid=[id]", "/[id]"

Do I need a custom route for the parameter to be picked up?

Or maybe annotate the action method with [httpPost] or [httpGet]?

3
  • have you tried "@Url.Action("Step1", "Reports")" + "/?rsid=" + rsid ? Commented Apr 16, 2015 at 0:44
  • 1
    You not providing any value for the parameter rsid (so it null) Commented Apr 16, 2015 at 0:46
  • 2
    Also, download fiddler. Its very helpful to see what parameters are sent and makes it easier to identify issues Commented Apr 16, 2015 at 1:02

5 Answers 5

2

The easiest way to do it is to just name the parameter "id" since it is in the default route and call from js like this:

'@Html.ActionLink("Step1", "Reports", new { id = ' + rsid + ' })'

public ActionResult Step1(int? id)
{

          //do stuff
}
Sign up to request clarification or add additional context in comments.

1 Comment

In my case parameter value (for example rsid here) are encode with javaScript encodeURIComponent() so in MVC Action return parameter has null value, I don't know why!
2

You probably mapping to a default route which is: /controller/action/id. Now in your action declaration you named your parameter as rsid which will not map to id because name is different. Change your action signature to:

public ActionResult Step1(int? id)

or option b) is specify the name of your parameter from js side:

window.location.href = "@Url.Action("Step1", "Reports")" + "/?rsid=" + rsid;

Comments

2

No need for string concatenation. It's bug prone, as you've discovered. Simply provide an anonymous object with your route values (using a different overload of UrlHelper.Action) and let MVC routing decide how to represent it all.

To make this fail-safe, you'll also need to make sure your URL is safe to store in a JavaScript string by wrapping it in a call to HttpUtility.JavaScriptStringEncode, then rendered without HTML encoding by wrapping in Html.Raw:

window.location.href = 
 "@Html.Raw(HttpUtility.JavaScriptStringEncode(Url.Action("Step1", "Reports", new{rsid})))";

You could simplify matters with a helper extension method (an extension on HtmlHelper seems convenient to me)

public static class JavascriptHelperEx
{
    public static IHtmlString QuotedJsString(this HtmlHelper htmlHelper, string str)
    {
        //true parameter below wraps everything in double quotes:
        return htmlHelper.Raw(HttpUtility.JavaScriptStringEncode(str, true));
    }
}

So now:

window.location.href = @Html.QuotedJsString(Url.Action("Step1", "Reports", new{rsid}));

3 Comments

Yes, also still need @Html.Raw(... as @ will HtmlEncode the url. location.href may handle such over-encoded url, but regular url manipulation in JavaScript will likely be completely confused (not directly applicable to OP's case)...
Yes... One option is to wrap it in helper code that will return HtmlString to avoid Html.Raw (combining answers from here for example... ). I know there are couple good answers with versions I like, can't find them now.
@AlexeiLevenkov: Thx for your contributions
0

What URL does this create?

"@Url.Action("Step1", "Reports")" + "/?" + rsid;

Something like this:

http://server/controller/action/?123

There's no parameter in that URL called rsid, so the model binder doesn't know where to find that value. You need to give the value a key:

"@Url.Action("Step1", "Reports")" + "/?rsid=" + rsid;

This would create something more like this:

http://server/controller/action/?rsid=123

1 Comment

Thanks David, I think I discovered the issue, if I rename my controller param to id and get rid of the question mark in the url it works because it matches a default routing pattern. So does that mean if I want to have meaningful parameter names (rather than just id) in controller actions I need to have a custom route mask for each param pattern? (or just extract the param values from the query string old-school)
0

try to have a rsid after the ? so the value will map to rsid

window.location.href = "@Url.Action("Step1", "Reports")" + "/?rsid=" + rsidValue;

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.