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();
Book.cs
namespace ConfigSample.Books.Models;
public record Book
{
public int Id { get; init; }
public string Name { get; init; } = "";
}
HomeController.cs
using Microsoft.AspNetCore.Mvc;
namespace ConfigSample.Controllers;
public class HomeController: Controller
{
[Route("")]
public IActionResult Index()
{
return View("Views/Index.cshtml");
}
}
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>
book.ts
export type Book = {
id: number,
name: string
};
main.page.ts
export function init(): void {
// gets the arguments and output.
console.log("hello world");
}
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>
main.page.ts
export function init(stringValue: string): void {
// output "Hello World".
console.log(stringValue);
}
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>
main.page.ts
export function init(stringValue: string, encodedStringValue: string): void {
// output "こんにちは世界".
console.log(stringValue);
// output "こんにちは世界".
console.log(decodeURI(encodedStringValue));
}
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>
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);
}
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>
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>
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>
main.page.ts
import moment from "moment";
export function init(dateValue: Date): void {
console.log(moment(dateValue).format("yyyy-MM-DD HH:mm:ss"));
}
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>
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>
main.page.ts
export function init(ids: number[]): void {
// [1, 2, 3]
console.log(ids);
}
Top comments (0)