Pass values from backend controller to Javascript

Introduction 

There are many of times we need to pass data from backend controller to javascript, in ASP.NET MVC, we can use @VariableName to get backend variable, but this just for that case you write the javascript in MVC view (*.cshtml) , what if I want to put these values in a separated javascript file?

I will introduct a way to how to do that, and this is spearated from the RequireJS.NET lib.

Using the code

1.Create a simple MVC project,

How it works

We can pass a value or object into Dictionary and convert it to a key/value JSON object then pass to frontent, and we should need to serialize the value or object to JSON at first, so we need to use the Newtonsoft.Json lib for do that.

So we create a method for add the backend data into Dictionary object to current http context first:

public static void Add(string key, Dictionary<string, object> value, bool clearExisting = false)
{
    var dictToModify = GetPageValues();//get and create dictionary object from http context
    var existing = dictToModify.FirstOrDefault(r => r.Key == key).Value;
    if (existing != null)
    {
        if (!clearExisting && existing is Dictionary<string, object>)
        {
            AppendItems(existing as Dictionary<string, object>, value);
        }
        else
        {
            dictToModify.Remove(key);
            dictToModify.Add(key, value);
        }
    }
    else
    {
        dictToModify.Add(key, value);
    }
}

And GetPageVaues() method for get vaue from existing Http Context

public static Dictionary<string, object> GetPageValues(HttpContextBase context)
{
    var page = context.Items[PageValuesKey] as Dictionary<string, object>;
    if (page == null)
    {
        context.Items[PageValuesKey] = new Dictionary<string, object>();
    }
    return (Dictionary<string, object>)context.Items[PageValuesKey];
}
public static Dictionary<string, object> GetPageValues()
{
    return GetPageValues(new HttpContextWrapper(GetCurrentContext()));
}
private static HttpContext GetCurrentContext()
{
    if (HttpContext.Current == null)
    {
        throw new Exception("HttpContext.Current is null. JSValues needs a HttpContext in order to work.");
    }
    return HttpContext.Current;
}

After that, we need to serialize the object to send to javascript

public static string SerializeAsVariable<T>(T obj, string varName)
{
    var json = JsonConvert.SerializeObject(obj);
    return string.Format("var {0} = {1};", varName, json);
}

Use the TagBuilder to dynamic build the “script” tag and put the serialized javascript object to frontend

public class JavaScriptBuilder
{
    private const string Type = "application/javascript";
    private readonly TagBuilder scriptTag = new TagBuilder("script");
    private readonly StringBuilder content = new StringBuilder();
    private bool hasNewLine = false;
    public bool TagHasType { get; set; }
    /// <summary>
    /// Call this from HTML helper to render the javascript object
    /// </summary>
    /// <returns></returns>
    public string Render()
    {
        scriptTag.InnerHtml = RenderContent();
        return scriptTag.ToString(TagRenderMode.Normal);
    }
    public string RenderContent()
    {
        return content.ToString();
    }
    /// <summary>
    /// call this method to add the serialized object 
    /// </summary>
    /// <param name="statement"></param>
    public void AddStatement(string statement)
    {
        if (!hasNewLine)
        {
            content.AppendLine();
            hasNewLine = true;
        }
        content.AppendLine(statement);
    }
    //Other logic
    .......
}

Create a HTML helper to register the javascript to frontend

public static MvcHtmlString RenderJsValues(this HtmlHelper html)
{
    var options = JavaScriptHelpers.CreateValuesFrom(html.ViewContext.HttpContext);
    var configBuilder = new JavaScriptBuilder();
    configBuilder.AddStatement(JavaScriptHelpers.SerializeAsVariable(options, "page"));
    return new MvcHtmlString(configBuilder.Render());
}

Final, call the HTML helper method in _Layout.cshtml between <head></head> tag

<head>
   @Html.RenderJsValues()
</head>

Using the code

Below example to pass a UserInfo model to javascript from backend controller.

Create the UserInfo model and use JSValues.add() to add the model object to http context

public ActionResult Index()
{
    UserInfo user = new UserInfo();
    user.Name = "Winson";
    user.Password = "123123";
    user.Website = "https://www.coderblog.in";
    JSValues.JSValues.Add("user", user);
    return View();
}

In the MVC view file, you can get the backend values as below

@section scripts {
    <script>
    $(document).ready(function () {
        console.log(page.pageValues.user);
    });
    </script>
}

Of course, you can also put these code to a separated javascript file.

You will see the below result in browser console

Please find the below demo project for your reference

CoderBlogJSValues.zip (31 downloads)

2,641 total views, 14 views today

Share your vote!


Do you like this post?
  • Fascinated
  • Happy
  • Sad
  • Angry
  • Bored
  • Afraid

You may also like...

shares