Blog (3)
Komentarze (5)
Recenzje (0)
@lelu0ASP.NET — C# z JavaScript'em w pokojowym współistnieniu

ASP.NET — C# z JavaScript'em w pokojowym współistnieniu

18.05.2017 02:49

Tło

Pierwszy raz z problemem wywołania funkcji bądź przekazania zmiennych z kodu pisanego w C# do kody JavaScript’owego spotkałem się przy okazji generowania wykresów z użyciem biblioteki Google Charts. Moja aplikacja napisana w ASP.NET MVC korzystała z bazy danych stworzonej przy użyciu Entity Framework. Model przekazywany do widoku z kontrolera nie posiadał w sobie żadnych danych. Były one pobierane z bazy dopiero w momencie wywołania odpowiednich funkcji. I tu pojawił się problem. W jaki sposób dane uzyskane w ten sposób „wstrzyknąć” do tablicy w JS, na podstawie której tworzony był wykres?

Struktura

Dla ułatwienia przybliżę tylko tę część struktury projektu, która jest istotna:

Models

  • /BrandC.cs – klasa modelu

Views/Brand

  • /Index.cshtml – widok
  • /ChartsView.cshtml – widok częściowy renderowany wewnątrz index.cshtml

Views/Shared

  • /_Layout.cshtml – layout strony, zawiera sekcję head oraz body, wewnątrz body w
    renderowane są widoki.

Problem 1. – dodawanie kodu do sekcji head z poziomu widoków

Ideą było zadeklarowanie wszystkich opcji wykresów z poziomu sekcji head strony. Jako, że dane zależne były od modelu przekazanego do widoku wypełnienie tablicy z danymi musiało nastąpić w pliku Index.cshtml. Całkiem eleganckim rozwiązaniem okazało się dodanie do pliku _Layout następującego kodu:

[code=C#] @if (IsSectionDefined("AddToHead")) { @RenderSection("AddToHead", required: false) } [/code]

A następnie w samym Indexie wstawiona została sekcja z kodem JS:

[code=C#] @section AddToHead{

Po tych operacjach w widoku ChartsView można było już wstawić znacznik

odpowiadający za wyświetlanie wykresu.

Problem 2. – przekazanie danych z listy C# do listy w JavaScript

Funkcja przygotowująca dane do wykresu zwracała je w postaci List<int>. Najbardziej naturalnym sposobem przekazania ich do zmiennej z danymi do wykresu wydał się być JSON. I słusznie. Serializację danych w ASP.NET możemy przeprowadzić na dwa sposoby – za pomocą wbudowanej klasy System.Web.Helpers.Json lub frameworka Json.NET. Twórcy frameworka chwalą się, że jest to rozwiązanie szybsze od serializacji wbudowanej. Jak jest naprawdę postanowiłem przekonać się osobiście i test ten znajdzie się w kolejnym wpisie. Samo przygotowanie danych odbywa się bardzo podobnie, a można zrobić je w dwóch miejscach. W przypadku rozwiązania systemowego funkcja wciąż zwracała List<int>. W kodzie JS pojawił się następujący zapis:

[code=JS / C#]var inData = @Html.Raw(Json.Encode(Model.prepareChartDataV2()));[/code]

Kolejno: Html.Raw odpowiada za prawidłowe kodowanie – bez tego zapisu zamiast znaku „ pojawia się "e. Json.Encode jest wywołaniem metody serializującej z systemowej klasy Json. Jako argument przyjmuje obiekt, zwraca rzecz jasna string Model.prepareChartDataV2() jest funkcją zwracającą wspomnianą wcześniej tablicę int’ów.

Korzystając z frameworka w kodzie funkcji zmieniłem typ zwracanych danych na string, a funkcję serializującą wywołałem w momencie zwracania wyniku:

[code=C#] return JsonConvert.SerializeObject(listaInt); [/code]

Sam kod w pliku index uprościł się rzecz jasna o wywołanie metody serializującej: [code=JS/C#] var inData = @Html.Raw(Model.prepareChartDataV2()); [/code]

Serializacja obiektów

Nie tylko listy podlegają serializacji. Równie dobrze można serializować całe obiekty pobrane z bazy danych nawet, jeżeli są typu anonimowego. Załóżmy proste tabele bazy danych:

Wpis: WpisID|Autor|TagID 12|Anon|2 Tag: TagID|Tagi| 2|Personal

W wypadku pobrania tego zestawu danych za pomocą najprostszego zapytanie LINQ do zmiennej var obj, po wykonaniu serializacji na obiekcie obj otrzymamy następującego json'a:

[code=LINQ] using (var db = new _base()) { var pz = (from p in db.Wpis select new { p }).ToList(); return JsonConvert.SerializeObject(pz); } [/code]

[code=JSON] { „WpisID” : „12”, „Autor” : „Anon”, „Tag” : { „TagID” : „2”, „Tagi” : „Personal” } } [/code]

Adnotacja

Powyższy wpis to mój debiut blogerski. Motywacją do napisania tego tekstu był czas poświęcony na poszukiwanie rozwiązań omówionych tu zagadnień. Jako osoba nie będąca ekspertem w .NET uznałem, że warto podzielić się tym rozwiązaniem z innymi stającymi przed koniecznością rozwiązania podobnego problemu.

Wybrane dla Ciebie
Komentarze (4)