DEV Community

Masui Masanori
Masui Masanori

Posted on

[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

Discussion (0)