canxss
canxss

Reputation: 213

Generating an action URL in JavaScript for ASP.NET MVC

I'm trying to redirect to another page by calling an action in controller with a specific parameter. I'm trying to use this line:

window.open('<%= Url.Action("Report", "Survey",
    new { id = ' + selectedRow + ' } ) %>');

But I couldn't make it work; it gives the following error:

CS1012: Too many characters in character literal.

Can't I generate the action URL this was on the client side? Or do I have to make an Ajax call by supplying the parameter and get back the needed URL? This doesn't seem right, but I want to if it's the only way.

Is there an easier solution?

Upvotes: 20

Views: 51997

Answers (9)

Premson Baby
Premson Baby

Reputation: 21

Just if someone is still looking for this. The controller action can have normal parameters or a model object with these fields. MVC will bind the valus automatically.

 var url = '@Url.Action("Action", "Controller")';
 $.post(url, {
      YearId: $("#YearId").val(),
      LeaveTypeId:  $("#LeaveTypeId").val()
 }, function (data) {
      //Do what u like with result
 });

Upvotes: 2

maxspan
maxspan

Reputation: 14177

The easiest way is to declare a javascript variable than concate your parameter value to the link.

  var url = '@Url.Action("Action","Controller")' + "/" + yourjavascriptvariable;
  <a href='" + url + "'> 

Upvotes: 0

user2792022
user2792022

Reputation: 1

One more thing that can be done, no so clean i guess:

var url = "@Url.RouteUrl(new { area = string.Empty, controller = "Survey", action = "Report" })";
var fullUrl = url  + '?id=' + selectedRow;

Upvotes: 0

Kenny Evitt
Kenny Evitt

Reputation: 9801

A way to do this that might be considered cleaner involves using the T4MVC T4 templates. You could then write the JavaScript inside your view like this:

var reportUrl = '<%= Url.JavaScriptReplacableUrl(MVC.Survey.Report())%>';
reportUrl = myUrl.replace('{' + MVC.Survey.ReportParams.id + '}', selectedRow);

window.open(reportUrl);

The advantage of this is that you get compile-time checking for the controller, action, and action parameter.

Upvotes: 1

Israfel
Israfel

Reputation: 1162

Could you do

window.open('/report/survey/' + selectedRow);

instead where selected row I assume is the id? The routing should pick this up fine.

or use getJSON

Perhaps you could use JSONResult instead. Wherever the window.open should be call a method instead i.e. OpenSurveyWindow(id);

then add some jquery similar to below

function OpenSurveyWindow(id){
      $.getJSON("/report/survey/" + id, null, function(data) {
          window.open(data);
     });
}

now in your controller

public JsonResult Survey(int id)
{
    return Json(GetMyUrlMethod(id));
}

That code isnt syntactically perfect but something along those lines should work

Upvotes: 3

Jaco Pretorius
Jaco Pretorius

Reputation: 24840

I usually declare a javascript variable in the section to hold the root of my website.

<%="<script type=\"text/javascript\">var rootPath = '"
    + Url.Content("~/") + "';</script>" %>

To solve your problem I would simply do

window.open(rootPath + "report/survey/" + selectedRow);

Upvotes: 10

Dylan Beattie
Dylan Beattie

Reputation: 54150

Remember that everything between <% and %> is interpreted as C# code, so what you're actually doing is trying to evaluate the following line of C#:

Url.Action("Report", "Survey", new { id = ' + selectedRow + ' } )

C# thinks the single-quotes are surrounding a character literal, hence the error message you're getting (character literals can only contain a single character in C#)

Perhaps you could generate the URL once in your page script - somewhere in your page HEAD, do this:

var actionUrl =
    '<%= Url.Action("Report", "Survey", new { id = "PLACEHOLDER" } ) %>';

That'll give you a Javascript string containing the URL you need, but with PLACEHOLDER instead of the number. Then set up your click handlers as:

window.open(actionUrl.replace('PLACEHOLDER', selectedRow));

i.e. when the handler runs, you find the PLACEHOLDER value in your pre-calculated URL, and replace it with the selected row.

Upvotes: 54

Brian Mains
Brian Mains

Reputation: 50728

If selectedRow is a client-side variable, it won't work. You have to use @Israfel implementation to link. This is because the server-side runs before the client-side variable even exists.

If selectedRow is a server-side variable within the view, change to this:

window.open('<%= Url.Action("Report", "Survey", new { id = selectedRow } ) %>');

This is because the id will infer the selectedRow variable type, or you could convert to string with ToString() method (as long as it's not null).

Upvotes: 0

Pharabus
Pharabus

Reputation: 6062

You wont be able to do this, the URL.Action is a server side process so will parse before the clientside selectedRow is available. Israfel has the answer I would suggest.

Upvotes: 0

Related Questions