T4MVC W ASP.NET MVC w wielu miejscach podajemy informację o widokach, kontrolerach, skryptach JavaScript, stylach css pod postacią zwykłego napisu string.

Co prawda obecnie Visual Studio oferuje Intellisense co do tych odwołań, więc się nie pomylisz.

Jest to jednak wciąż zła praktyka.

image

Jak więc pozbyć się tych napisów string i zamienić je na jakieś klasy.

Otóż od jakiegoś czasu istnieje skrypt T4, który generuje klasy, które  rozwiązują ten problem.

Używając NuGet, łatwo możemy dodać wszystko, co jest potrzebne do tego skryptu T4.

Istnieje też paczka “T4MVCJS”, która wygeneruje plik JS z polami do akcji kontrolerów. Obecnie jednak nie działa z najnowszą wersją ASP.NET MVC, dlatego nie polecam.

image

Po każdej zmianie projektu warto pamiętać o tym, że skrypt T4 automatycznie nie uruchamia się ponownie. Jest to nawet dobry pomysł, jeśli pomyślimy o systemach kontroli wersji jak TFS.

Gdy więc dodaliśmy nowy kontroler, widok, styl, skrypt JavaScript, wtedy uruchamiamy opcje "Run Custom Tool" na tym skrypcie T4.

image

Jak korzystać z tych wygenerowanych klas?

Na początku do widoku .cshtml trzeba dodać przestrzeń nazw "links".

@using Links;

Zacznijmy od plików styli CSS. Normalnie możemy się do nich odwołać na dwa sposoby. Każdy z tych sposobów tworzy jednak napis. Jeśli plik zmieni folder, to dowiemy się o tym dopiero przy uruchomieniu strony.

<link href="~/Content/Site.css" rel="stylesheet" />
    <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" />

T4MVC wygenerował klasę "Content", posiada ona pole statyczne odwołujące się do określonych plików css. Jeśli pliki znajdują się w kolejnych folderach, klasa Content zawiera w sobie kolejną statyczną klasę, która nazywa się jak folder.

<link href="@Url.Content(Content.Site_css)" rel="stylesheet" />
    <link href="@Url.Content(Content.bootstrap_min_css)" rel="stylesheet" />
    <link href="@Url.Content(Content.pluginStyles.AnotherStyle_css)"
    rel="stylesheet" />


Oto jak układ plików CSS wygląda w projekcie.

image

Do skryptów JavaScript normalnie odwołujemy się w taki sposób.

<script src="~/scripts/jquery-2.1.1.js" type="text/javascript"></script>
    <script src="@Url.Content("/scripts/jquery-2.1.1.js")"
    type="text/javascript"></script>

T4MVC utworzyło statyczną klasę "Scripts" w niej znajdują się pola określające ścieżkę do określonych plików JavaScript.

<script src="@Url.Content(Scripts.jquery_2_1_1_min_js)"
    type="text/javascript"></script>
    <script src="@Url.Content(Scripts.Vendor.VendorScript_js)"
    type="text/javascript"></script>

Oczywiście VisualStudio podpowiada, co się znajduje w każdej wygenerowanej klasie. Na poniższym obrazku widzę wszystkie pliki znajdujące się w folderze Scripts.

image

A co z akcjami poszczególnych kontrolerów?

Używając napisów - robimy to w ten sposób. Piszemy jaką akcję kontrolera chcemy wywołać.

<ul>
    <li><a href="@Url.Action("Index")">Strona główna</a></li>
    <li><a href="@Url.Action("Contact")">Kontakt</a></li>
    <li><a href="@Url.Action("Options")">Opcje</a></li>
    </ul>

T4MVC posiada klasę statyczną MVC. Klasa ta posiada kolejne klasy statyczne określające każdy istniejący kontroler w projekcie. Wygenerowana klasa kontrolera posiada kolejną klasę “ActionNames”, w niej są pola statyczne określające nazwy poszczególnych akcji.

<ul>
    <li><a href="@Url.Action(MVC.Demo.ActionNames.Index)">Strona główna</a></li>
    <li><a href="@Url.Action(MVC.Demo.ActionNames.Contact)">Kontakt</a></li>
    <li><a href="@Url.Action(MVC.Demo.ActionNames.Options)">Opcje</a></li>
    </ul>

Aby uzyskać dostęp do samej nazwy kontrolera, korzystamy z pola name.

<a href="@Url.Action(MVC.SecondPage.ActionNames.Index,MVC.SecondPage.Name)">
    Druga strona
    </a>

Widoki w T4MVC znajdują w przestrzeni klasy kontrolera. 

@Html.Partial("PartialView")

    @Html.Partial(MVC.Demo.Views.PartialView)

Warto też zwrócić uwagę, że T4MVC posiada plik z ustawieniami.

image

W nim możemy np. dodać kolejne statyczne foldery plików. Przykładowo, jeśli byśmy chcieli przechowywać pliki CSS i JS w innych folderach niż w domyślnym projekcie...

<StaticFilesFolders>
    <FileFolder>Scripts</FileFolder>
    <FileFolder>Content</FileFolder>
    </StaticFilesFolders>