简体   繁体   中英

Asp.net MVC controller parameter null when action called from javascript

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM