[javascript] Call javascript from MVC controller action

Can I call javascript function from MVC controller action (not from view page) and get return value? How?


I need to make request to server from code (.cs) using javascript like here (but this is aspx page)

function getInitData() { 
var code; code = 'return {' ;
code += 'me: API.getProfiles({uids: API.getVariable({key: 1280}), fields: "photo"})[0]'; 
code += '};'
VK.Api.call('execute', { 'code': code }, onGetInitData); 
} 

This question is related to javascript asp.net-mvc

The answer is


You can call a controller action from a JavaScript function but not vice-versa. How would the server know which client to target? The server simply responds to requests.

An example of calling a controller action from JavaScript (using the jQuery JavaScript library) in the response sent to the client.

$.ajax({
           type: "POST",
           url: "/Controller/Action", // the URL of the controller action method
           data: null, // optional data
           success: function(result) {
                // do something with result
           },                
           error : function(req, status, error) {
                // do something with error   
           }
       });

For those that just used a standard form submit (non-AJAX), there's another way to fire some Javascript/JQuery code upon completion of your action.

First, create a string property on your Model.

public class MyModel 
{
    public string JavascriptToRun { get; set;}
}

Now, bind to your new model property in the Javascript of your view:

<script type="text/javascript">
     @Model.JavascriptToRun
</script>

Now, also in your view, create a Javascript function that does whatever you need to do:

<script type="text/javascript">
     @Model.JavascriptToRun

     function ShowErrorPopup() {
          alert('Sorry, we could not process your order.');
     }

</script>

Finally, in your controller action, you need to call this new Javascript function:

[HttpPost]
public ActionResult PurchaseCart(MyModel model)
{
    // Do something useful
    ...

    if (success == false)
    {
        model.JavascriptToRun= "ShowErrorPopup()";
        return View(model);
    }
    else
        return RedirectToAction("Success");
}

The usual/standard way in MVC is that you should put/call your all display, UI, CSS and Javascript in View, however there is no rule to it, you can call it in the Controller as well if you manage to do so (something i don't see the possibility of).


<script>
    $(document).ready(function () {
        var msg = '@ViewBag.ErrorMessage'
        if (msg.length > 0)
            OnFailure('Register', msg);
    });

    function OnSuccess(header,Message) {
        $("#Message_Header").text(header);
        $("#Message_Text").text(Message);
        $('#MessageDialog').modal('show');
    }

    function OnFailure(header,error)
    {
        $("#Message_Header").text(header);
        $("#Message_Text").text(error);
        $('#MessageDialog').modal('show');
    }
</script>

Since your controller actions execute on the server, and JavaScript (usually) executes on the client (browser), this doesn't make sense. If you need some action to happen by default once the page is loaded into the browser, you can use JavaScript's document.OnLoad event handler.


Yes, it is definitely possible using Javascript Result:

return JavaScript("Callback()");

Javascript should be referenced by your view:

function Callback(){
    // do something where you can call an action method in controller to pass some data via AJAX() request
}

There are ways you can mimic this by having your controller return a piece of data, which your view can then translate into a JavaScript call.

We do something like this to allow people to use RESTful URLs to share their jquery-rendered workspace view.

In our case we pass a list of components which need to be rendered and use Razor to translate these back into jquery calls.


If I understand correctly the question, you want to have a JavaScript code in your Controller. (Your question is clear enough, but the voted and accepted answers are throwing some doubt) So: you can do this by using the .NET's System.Windows.Forms.WebBrowser control to execute javascript code, and everything that a browser can do. It requires reference to System.Windows.Forms though, and the interaction is somewhat "old school". E.g:

void webBrowser1_DocumentCompleted(object sender, 
    WebBrowserDocumentCompletedEventArgs e)
{
    HtmlElement search = webBrowser1.Document.GetElementById("searchInput");
    if(search != null)
    {
        search.SetAttribute("value", "Superman");
        foreach(HtmlElement ele in search.Parent.Children)
        {
            if (ele.TagName.ToLower() == "input" && ele.Name.ToLower() == "go")
            {
                ele.InvokeMember("click");
                break;
            }
        }
    }
}

So probably nowadays, that would not be the easiest solution.

The other option is to use Javascript .NET or jint to run javasctipt, or another solution, based on the specific case.

Some related questions on this topic or possible duplicates:

Embedding JavaScript engine into .NET

Load a DOM and Execute javascript, server side, with .Net

Hope this helps.


It is late answer but can be useful for others. In view use ViewBag as following:

@Html.Raw("<script>" + ViewBag.DynamicScripts + "</script>")

Then from controller set this ViewBag as follows:

ViewBag.DynamicScripts = "javascriptFun()";

This will execute JavaScript function. But this function would not execute if it is ajax call. To call JavaScript function from ajax call back, return two values from controller and write success function in ajax callback as following:

$.ajax({
       type: "POST",
       url: "/Controller/Action", // the URL of the controller action method
       data: null, // optional data
       success: function(result) {
            // do something with result
       },
     success: function(result, para) {
        if(para == 'something'){
            //run JavaScript function
        }
      },                
       error : function(req, status, error) {
            // do something with error   
       }
   });

from controller you can return two values as following:

return Json(new { json = jr.Data, value2 = "value2" });