DEV Community

Masui Masanori
Masui Masanori

Posted on

3 2

[ASP.NET Core] Send data from Razor to TypeScript

Intro

When I send some data from Razor pages to TypeScript codes, I sometimes get troubles.
In this time, I will try avoid them.

Environments

  • .NET ver.6.0.200
  • Newtonsoft.Json ver.13.0.1
  • Microsoft.AspNetCore.Mvc.NewtonsoftJson ver.6.0.2

  • Node.js ver.17.6.0

  • TypeScript ver.4.5.5

  • Webpack ver.5.69.1

  • Moment ver.2.29.1

Base projects

Program.cs

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllers();

var app = builder.Build();
app.UseStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints => endpoints.MapControllers());
app.Run();
Enter fullscreen mode Exit fullscreen mode

Book.cs

namespace ConfigSample.Books.Models;
public record Book
{
    public int Id { get; init; }
    public string Name { get; init; } = "";
}
Enter fullscreen mode Exit fullscreen mode

HomeController.cs

using Microsoft.AspNetCore.Mvc;

namespace ConfigSample.Controllers;
public class HomeController: Controller
{
    [Route("")]
    public IActionResult Index()
    {
        return View("Views/Index.cshtml");
    }
}
Enter fullscreen mode Exit fullscreen mode

Index.cshtml

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>Razor sample</title>
        <meta charset="utf-8">
    </head>
    <body>
        <script src="js/main.page.js"></script>
        <!-- add various types arguments here -->
        <script>Page.init();</script>
    </body>
</html>
Enter fullscreen mode Exit fullscreen mode

book.ts

export type Book = {
    id: number,
    name: string
};
Enter fullscreen mode Exit fullscreen mode

main.page.ts

export function init(): void {
    // gets the arguments and output.
    console.log("hello world");
}
Enter fullscreen mode Exit fullscreen mode

string values

I can put string values directly.

Index.cshtml

@{
    var stringValue = "Hello World";
}
<!DOCTYPE html>
<html lang="en">
...
    <body>
        <script src="js/main.page.js"></script>
        <script>Page.init('@stringValue');</script>
    </body>
</html>
Enter fullscreen mode Exit fullscreen mode

main.page.ts

export function init(stringValue: string): void {
    // output "Hello World".
    console.log(stringValue);
}
Enter fullscreen mode Exit fullscreen mode

Japanese or other languages

I should take care if the values has Japanese or any other languages.
I have to encode and decode.

Index.cshtml

@{
    var japaneseValue = "こんにちは世界";
    var encodedValue = System.Web.HttpUtility.UrlEncode(japaneseValue);
}
<!DOCTYPE html>
<html lang="en">
...
    <body>
        <script src="js/main.page.js"></script>
        <script>Page.init('@japaneseValue', '@encodedValue');</script>
    </body>
</html>
Enter fullscreen mode Exit fullscreen mode

main.page.ts

export function init(stringValue: string, encodedStringValue: string): void {
    // output "&#x3053;&#x3093;&#x306B;&#x3061;&#x306F;&#x4E16;&#x754C;".
    console.log(stringValue);
    // output "こんにちは世界".
    console.log(decodeURI(encodedStringValue));
}
Enter fullscreen mode Exit fullscreen mode

int, float, double

I can put number values directly.

Index.cshtml

@{
    var intValue = 3;
    var floatValue = 4.56f;
    var minusValue = -3.005d;
}
<!DOCTYPE html>
<html lang="en">
...
    <body>
        <script src="js/main.page.js"></script>
        <script>Page.init(@intValue, @floatValue, @minusValue);</script>
    </body>
</html>
Enter fullscreen mode Exit fullscreen mode

main.page.ts

export function init(intValue: number, floatValue: number, minusValue: number): void {
    // output "3"
    console.log(intValue);
    // output "4.56"
    console.log(floatValue);
    // output "-3.005"
    console.log(minusValue);
}
Enter fullscreen mode Exit fullscreen mode

bool

I can't put bool values like string and number types.

Because the bool values are treated as string values.
But in C#, when I convert from a boolean "true" value to a string value, it will be a "True".

Index.cshtml

@{
    var trueValue = true;
    var falseValue = false;
}
<!DOCTYPE html>
<html lang="en">
    <head>
        <title>Razor sample</title>
        <meta charset="utf-8">
    </head>
    <body>
        <script src="js/main.page.js"></script>
        <!-- I will get an error "Uncaught ReferenceError: True is not defined" -->
        <script>Page.init(@trueValue, @falseValue);</script>
    </body>
</html>
Enter fullscreen mode Exit fullscreen mode

So I have to treat them as string values and set lower case manually.

Index.cshtml

@{
    var trueValue = true;
    var falseValue = false;
}
<!DOCTYPE html>
<html lang="en">
    <head>
        <title>Razor sample</title>
        <meta charset="utf-8">
    </head>
    <body>
        <script src="js/main.page.js"></script>
        <!-- OK -->
        <script>Page.init(@trueValue.ToString().ToLower(), @falseValue.ToString().ToLower());</script>
    </body>
</html>
Enter fullscreen mode Exit fullscreen mode

Date

I can put date values as string values.

Index.cshtml

@{
    var dateValue = DateTime.Now;
}
<!DOCTYPE html>
<html lang="en">
...
    <body>
        <script src="js/main.page.js"></script>
        <!-- "3/1/2022 2:42:19 AM" -->
        <script>Page.init('@dateValue');</script>
    </body>
</html>
Enter fullscreen mode Exit fullscreen mode

main.page.ts

import moment from "moment";
export function init(dateValue: Date): void {
    console.log(moment(dateValue).format("yyyy-MM-DD HH:mm:ss"));
}
Enter fullscreen mode Exit fullscreen mode

List, Array

I can't put list or array values directly.
Because they are also treated as string values.

Index.cshtml

@{
    var ids = new List<int>
    {
        1, 2, 3
    };
}
<!DOCTYPE html>
<html lang="en">
...
    <body>
        <script src="js/main.page.js"></script>
        <!-- Because the value becomes "System.Collections.Generic.List`1[System.Int32]" -->
        <!-- so I will get an error: "Uncaught SyntaxError: Unexpected end of input" -->
        <script>Page.init('@ids');</script>
    </body>
</html>
Enter fullscreen mode Exit fullscreen mode

Because I don't want to create string values like "[1, 2, 3]" manually, I use Newtonsoft.Json and serialize them as JSON values.

Index.cshtml

@using Newtonsoft.Json
@{
    var ids = new List<int>
    {
        1, 2, 3
    };
    var idsJson = JsonConvert.SerializeObject(ids);
}
<!DOCTYPE html>
<html lang="en">
...
    <body>
        <script src="js/main.page.js"></script>
        <script>Page.init(@idsJson);</script>
    </body>
</html>
Enter fullscreen mode Exit fullscreen mode

main.page.ts

export function init(ids: number[]): void {
    // [1, 2, 3]
    console.log(ids);
}
Enter fullscreen mode Exit fullscreen mode

Sentry image

Hands-on debugging session: instrument, monitor, and fix

Join Lazar for a hands-on session where you’ll build it, break it, debug it, and fix it. You’ll set up Sentry, track errors, use Session Replay and Tracing, and leverage some good ol’ AI to find and fix issues fast.

RSVP here →

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay