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]?
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}));
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;
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
}
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
try to have a rsid after the ? so the value will map to rsid
window.location.href = "@Url.Action("Step1", "Reports")" + "/?rsid=" + rsidValue;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.