NetCore - Widok częściowy z szablonu Identity Razor Page a dopisanie innego widoku częściowego

0

Witam. Taki widok częściowy utworzył mi szkielet Identity. Uznaję to za "Panel zarządzania kontem"
screenshot-20201020204613.png

Layout.cshtml:

@{
    if (ViewData.TryGetValue("ParentLayout", out var parentLayout))
    {
        Layout = (string)parentLayout;
    }
    else
    {
        Layout = "/Areas/Identity/Pages/_Layout.cshtml";
    }
}

<h2>Panel użytkownika</h2>

<div>
    <h5>Tutaj możesz zarządzać swoimi danymi oraz kontem</h5>
    <hr />
    <div class="row">
        <div class="col-md-3">
            <partial name="_ManageNav" />
        </div>
        <div class="col-md-9">
            @RenderBody()
        </div>
    </div>
</div>

@section Scripts {
    @RenderSection("Scripts", required: false)
}

manageNav.cshtml:

@using Microsoft.AspNetCore.Identity
@inject SignInManager<ApplicationUser> SignInManager
@inject UserManager<Muzostacja.Data.ApplicationUser> UserManager
@{
    var hasExternalLogins = (await SignInManager.GetExternalAuthenticationSchemesAsync()).Any();
}
    <ul class="nav nav-pills flex-column">
        <li class="nav-item"><a class="nav-link @ManageNavPages.IndexNavClass(ViewContext)" id="profile" asp-page="./Index">Twój profil</a></li>
        <li class="nav-item"><a class="nav-link @ManageNavPages.ChangePasswordNavClass(ViewContext)" id="change-password" asp-page="./ChangePassword">Zmień hasło</a></li>
        <li class="nav-item"><a class="nav-link @ManageNavPages.PersonalDataNavClass(ViewContext)" id="personal-data" asp-page="./PersonalData">Usuń konto</a></li>
    </ul>

Stworzyłem sobie folder w którym trzymam strony od "Zarządzania rezerwacjami" i stworzyłem do tego nowy widok częściowy:
screenshot-20201020205015.png

Layout.cshtml:

@{
    if (ViewData.TryGetValue("ParentLayout", out var parentLayout))
    {
        Layout = (string)parentLayout;
    }
    else
    {
        Layout = "/Areas/Identity/Pages/_Layout.cshtml";
    }
}

<h2>Panel użytkownika</h2>

<div>
    <h5>Tutaj możesz dokonać rezerwacji i zarządzać nimi</h5>
    <hr />
    <div class="row">
        <div class="col-md-3">
            <partial name="_ReservationNav" />
        </div>
        <div class="col-md-9">
            @RenderBody()
        </div>
    </div>
</div>

@section Scripts {
    @RenderSection("Scripts", required: false)
}

ReservationNav.cshtml:

@using Microsoft.AspNetCore.Identity
@inject SignInManager<ApplicationUser> SignInManager
@inject UserManager<Muzostacja.Data.ApplicationUser> UserManager
@{
    var hasExternalLogins = (await SignInManager.GetExternalAuthenticationSchemesAsync()).Any();
}
    <ul class="nav nav-pills flex-column">
        <li class="nav-item"><a class="nav-link @ReservationNavPages.CreateReservationNavClass(ViewContext)" id="create-reservation" asp-page="./CreateRoomreservation">Utwórz rezerwację</a></li>
        <li class="nav-item"><a class="nav-link @ReservationNavPages.CreateVoucherNavClass(ViewContext)" id="create-voucher" asp-page="./CreateVoucher">Dodaj karnet</a></li>
        <li class="nav-item"><a class="nav-link @ReservationNavPages.IndexNavClass(ViewContext)" id="your-reservation" asp-page="./Index">Twoje rezerwacje</a></li>
    </ul>

Co może być nie tak, jeżeli "menu" ze szkieletu Identity działa prawidłowo, a mojego nowego Menu wcale nie widać? Jeżeli potrzebujecie kodu z konkretnego miejsca powiedzcie tylko skąd a zaraz wstawię

screenshot-20201020210008.png

0

Pierwsza sprawa czy problemem jest to że menu się nie renderuje czy to że go nie widać ?
Dodatkowow dałeś 2 razy kod manageNav.cshtml:
Podczas gdy w tym Layout utworzonym przez ciebie jest
<partial name="_ReservationNav" />

0

Prawdopodobnie menu się nie renderuje, cała strona jest jakby rozszerzona na całe okno. tak jakby jego nie było. A nazwy plików się zgadzają, omyłka przy pisaniu postu.

Po kliknięciu w panel Rezerwacji nie mam menu po lewej:
screenshot-20201020224101.png

0

ppm zbadaj strone dzięki temu dowiesz się czy problem jest z brakiem renderowania czy może menu się renderuje ale gdzieś "poza planszą". Bo tutaj ci widocznie wchodzi inny Layout.
Z tego powodu że gdyby był wymuszony ten wyżej podany to bootstrap nie pozwolił by rozszerzyć się tresci na całą strone. tylko zrobił by to na 3/4 strony.

W takim wypadku problemu szukał bym w

    {
        Layout = (string)parentLayout;
    }
    else
    {
        Layout = "/Areas/Identity/Pages/_Layout.cshtml";
    }

Z tego co zrozumiałem to po kliknieciu w panel rezerwacji powinieneś mieć widok podobny do Panelu użyszkodnika
Z tym że z Loyoutem który wkleiłeś w jako drugi w swoim pierwszym poscie.
Zauważ że ładuje ci się inny Layout bo nie masz nawet nagłówka
<h5>Tutaj możesz dokonać rezerwacji i zarządzać nimi</h5>

Ps. Swoją drogą coś masz nie tak z strukturą html skoro z H2 przeskakujesz na h5 pamiętaj że ważna jest semantyka a od wyglądu jest css, a nie tagi html :D

0

Przeglądałem elementy po kliknięciu F12 w przeglądarce i w ogóle nie ma mojego menu, tak jakby zostało pominięte

0

@Kardash: ale jakim cudem, skoro w folderze identity jest to zrobione identycznie i działa?

0

Kilka tropów
1.Jaką masz zwrotkę z ViewData.TryGetValue("ParentLayout", out var parentLayout)
2. Jak wygląda Layout : ````"/Areas/Identity/Pages/_Layout.cshtml"```
3. Osobiście wyszukał bym jak Layout mi wchodzi tutaj.

Tutaj wygląda to jakby ten Layout wgl nie byłl wczytywany i dostawał byś domyślny. Pamiętaj że przeklejki nie zawsze działają w taki sposob jak byśmy chcieli
Szczerze mówiąc cięzko mi doradzić coś wiecej na takim wycinku kodu :(

0

ViewData.TryGetValue("ParentLayout", out var parentLayout) z tego Layout działającego zwraca mi /Views/Shared/_Layout.cshtml. Drugi layout w ogóle się nie wykonuje
A jeżeli chodzi o /Areas/Identity/Pages/_Layout.cshtml to nie mam wcale takiego pliku, ale TryGetValue wykonuje się prawidłowo.

jeżeli chodzi o /Views/Shared/_Layout.cshtml

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - Muzostacja</title>
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
    <link rel="stylesheet" href="~/css/site.css" />
</head>
<body>
    <header>
        <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
            <div class="container">
                <a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">Muzostacja</a>
                <button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent"
                        aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>
                <div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
                    <partial name="_LoginPartial" />
                    <ul class="navbar-nav flex-grow-1">
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Polityka prywatności</a>
                        </li>
                    </ul>
                </div>
            </div>
        </nav>
    </header>
    <div class="container">
        <main role="main" class="pb-3">
            @RenderBody()
        </main>
    </div>

    <footer class="border-top footer text-muted">
        <div class="container">
            &copy; 2020 - Muzostacja - <a asp-area="" asp-controller="Home" asp-action="Privacy">Polityka prywatności</a>
        </div>
    </footer>
    <script src="~/lib/jquery/dist/jquery.min.js"></script>
    <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
    <script src="~/js/site.js" asp-append-version="true"></script>
    
    @RenderSection("Scripts", required: false)
</body>
</html>

Więc jakim cudem jeden Layout się wykonuje, a drugi już nie?

0

Jak sam zauważyłeś drugi się nie wykonuje ponieważ nie jest wykorzystywany.
Twój widok wywołuje twój Domyślny Layout. a nie ten który sobie utworzyłeś.

Odpowiedzią na to będzie albo akcje kontrolera(chociaż jak widzę to tutaj masz Razor Page)

druga opcja to w sekcji @{} konkretnego Page nie wskazujesz że ma być użyty twój nowy Laoyout i on używa tego domyślnego z ```/Views/Shared/_Layout.cshtml````
pomijając twój.

Ten widok wygenerowany przez identity działa tak że

Layout główny renderuje widok z pionowym menu i wybór czegoś z pionowego menu generuje widok strony

U ciebie widok główny od razu generuje widok strony z domyślnym Layoutem.

Czemu jest taka różnica cięzko mi określić

Jedyne co jeszcze mi przychodzi na myśl to
Podaj mi wywołania które kierując cię do tych widoków w wypadku implementacji Identity oraz twojej własnej.

0

Właśnie w tym rzecz, że ten widok na którym widać moje menu zwraca domyślny widok i to mnie dziwi (znaczy nie dziwi bo kod wyraźnie na to wskazuje). Dziwi mnie dlaczego właśnie to menu z Identity/Pages/Account/Manage działa prawidłowo. I jeżeli działa to dlaczego analogicznie nie działa identycznie utworzony kod dla Identity/Pages/Reservation/Manage

screenshot-20201022220500.png

A więc pokolei (bo próbowałem metodą prób i błędów)

  1. Area/Identity/Pages/Account/Manage
    a) _Layout.cshtml - https://pastebin.com/mzfQchX5
    b) _ViewImports.cshtml - https://pastebin.com/aiRpLrKR

  2. Area/Identity/Pages/Account
    a) _ViewImports.cshtml - @using Muzostacja.Areas.Identity.Pages.Account

  3. Area/Identity/Pages/Reservation/Manage
    a) _Layout.cshtml - https://pastebin.com/B7yQ870z
    b) _ViewImports.cshtml - https://pastebin.com/Tw5ddSfr

  4. Area/Identity/Pages/Reservation
    a) _ViewImports.cshtml - @using Muzostacja.Areas.Identity.Pages.Reservation

  5. Area/Identity/Pages
    a) _ManageNav1.cshtml - https://pastebin.com/SXz50by5
    b) _ManageNav2.cshtml - https://pastebin.com/rThSDnt1
    c) _ViewImports.cshtml - https://pastebin.com/GYXik6dZ
    d) _ViewStart.cshtml - https://pastebin.com/9BsYFZEi
    e) ManageNavPages.cs - https://pastebin.com/eSseszrv

Jeżeli potrzebujesz czegokolwiek jeszcze powiedz. Nadal działa menu z Area/Identity/Pages/Account/Manage i nie widać menu z Area/Identity/Pages/Reservation/Manage

0

Wzorując się na tym.
https://www.mikesdotnetting.com/article/164/nested-layout-pages-with-razor

wydaje mi się że w swoich podstronach (tych co masz jako zakładki w pionowym menu)
Musisz jako Layout jawnie wskazać ten Area/Identity/Pages/Reservation/Manage/_Layout.cshtml
To powinno rozwiązać problem.

czemu Identity zaciąga sobie inny Layout tam nie jestem wstanie określić, a próba debugowania tego skończyła się dla mnie
screenshot-20201022233725.png

aktualnie wywołując Index z Reservation on nie ma informacji o tym Layoucie z pionowym menu. Czemu w wypadku Identity wie... nie mam pojęcia
Musiał by się ktoś z wiekszym know-how wypowiedzieć

0

Próbowałem tak wcześniej na sztywno layout ustawić i faktycznie działa, jednak tracę wtedy położenie przycisków z panelu górnego. Zamiast napisu muzostacja po lewej i przycisków po prawej wszystko mam wyrównane do lewej strony.

1

ok. A czy ten Layout wskazuje na twój Layout główny ? ten z gornym menu ?

Zakładając Miejmy dwa layouty

  1. LayoutGóra ( z górnym menu)
  2. LayoutLewo (z lewym pionowym menu)

Twoje widoki które są zakładkami w lewym pionowym menu powinny wskazywać na LayoutLewo, a LayoutLewo powinien wskazywać na LayoutGóra

0

Moje menu górne jest wbite w layout w Views/Shared w <Body><Header>

<body>
    <header>
        <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
            <div class="container">
                <a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">Muzostacja</a>
                <button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent"
                        aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>
                <div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
                    <partial name="_LoginPartial" />
                    <ul class="navbar-nav flex-grow-1">
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Polityka prywatności</a>
                        </li>
                    </ul>
                </div>
            </div>
        </nav>
    </header>
    <div class="container">
        <main role="main" class="pb-3">
            @RenderBody()
        </main>
    </div>

Tak wygląda widok z menu Identity:
screenshot-20201023000511.png

1

no ok czaje baze :)
I jego zostaw w spokoju :)

a w

@{
    if (ViewData.TryGetValue("ParentLayout", out var parentLayout))
    {
        Layout = (string)parentLayout;
    }
    else
    {
        Layout = "/Areas/Identity/Pages/_Layout.cshtml";
    }
}

<h2>Panel użytkownika</h2>

<div>
    <h5>Tutaj możesz dokonać rezerwacji i zarządzać nimi</h5>
    <hr />
    <div class="row">
        <div class="col-md-3">
            <partial name="_ReservationNav" />
        </div>
        <div class="col-md-9">
            @RenderBody()
        </div>
    </div>
</div>

@section Scripts {
    @RenderSection("Scripts", required: false)
}

wskaż bezpośrednio na ten głowny Layout z Views/Shared
Nazwijmy go też dla ułatwienia LayoutemPobocznym

I następnie masz widok Index który wowułje Twoje rezerwacje

W nim musisz wskazać na LayoutemPoboczny i tak samo w ./CreateVoucher oraz /CreateRoomreservation

0

ustanowiłem _Layout na sztywno:

@page
@model IndexModel
@{
    ViewData["Title"] = "Twoje rezerwacje";
    ViewData["SubTitle"] = "Historia rezerwacji";
    ViewData["ActivePage"] = ManageNavPages.YourReservation;
    Layout = "_Layout.cshtml";
}

Menu pojawiło się, jednak zobacz komentarz wyżej na widok strony z menu z Identity: napis muzostacja jest z lewej, a Nazwa użytkownika oraz przyciski utwórz rezerwacje i panel rezerwacji z prawej. Tutaj wszystko wyrównało mi się do lewej. Dlaczego?

  1. Widok z https://localhost:44376/Identity/Account/Manage/ChangePassword
    screenshot-20201023090121.png

  2. Widok z https://localhost:44376/Identity/Reservation/Manage/CreateRoomReservation?
    screenshot-20201023090236.png

0

wygląda to na jakiś nadpisany Css.
Najlepiej będzie jak za pomocą Devtools sprawdzisz różnice w css (aczkolwiek to i tak dziwne). BO struktura html nie powinna się różnić

0

Account/Manage/Index
screenshot-20201023092400.png

Reservation/Manage/CreateReservation z ustawionym Layoutem
screenshot-20201023092607.png

Może będzie łatwiej jak zobaczysz to na stronie: https://muzostacja.azurewebsites.net/
Login: [email protected]
Hasło: qwe

1

Wniosek jest szybki :)
Oba te widoki korzystają z innych szablonów.

W wypadku Reservation masz w nagłówku head

<meta name="x-stylesheet-fallback-test" content="" class="sr-only">````

a na Account masz 
````<link rel="stylesheet" href="/lib/bootstrap/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="/css/site.css">````

wiec wciąż masz inne Layouty dlatego wygląda to inaczej. Polecał bym na potrzeby testów użyc do Layoutów linków "absolutnych"


jezeli to nie komercyjne to polecam link do gita było by o wiele szybciej.
0

Z racji braku pomysłów wkurzyłem się i przeniosłem wszystko prócz panelu użytkownika do MVC i działa <3 Poniżej rozwiązanie:
ReservationPanelController:

namespace Muzostacja.Controllers
{
    public class ReservationPanelController : Controller
    {
        // GET: Index
        [Authorize]
        public ActionResult Index()
        {
            return View();
        }

Views/ReservationPanel/Index.cshtml

@{
    ViewData["Title"] = "Twoje rezerwacje";
    ViewData["SubTitle"] = "Historia rezerwacji";
    ViewData["ActivePage"] = Muzostacja.Data.ManageNavPagesData.Nav_PanelRezerwacji.Index;
    Layout = "_Layout_PanelRezerwacji";
}

<div class="text-center">
    <h1 class="display-4">Welcome</h1>
    <p>HEH KURDE CHYBA NAWET DZIAŁA</a>.</p>
</div>

Views/Shared/_Layout_PanelRezerwacji - tutaj podałem bezwzględną nazwę głównego Layoutu

@{
    Layout = "_Layout.cshtml";
}

<!DOCTYPE html>

<h2>Panel rezerwacji</h2>

<div>
    <h5>Tutaj możesz tworzyć rezerwacje, przeglądać historię oraz zarządzać karnetami i wydarzeniami</h5>
    <hr />
    <div class="row">
        <div class="col-md-3">
            <partial name="_ManageNav_PanelRezerwacji" />
        </div>
        <div class="col-md-9">
            @RenderBody()
        </div>
    </div>
</div>

@section Scripts {
    @RenderSection("Scripts", required: false)
}

Views/Shared/_ManageNav_PanelRezerwacji.cshtml - Tutaj zamiast asp-page dałem akcje do kontrolera

@using Microsoft.AspNetCore.Identity
@inject SignInManager<ApplicationUser> SignInManager
@inject UserManager<Muzostacja.Data.ApplicationUser> UserManager
@{
    var hasExternalLogins = (await SignInManager.GetExternalAuthenticationSchemesAsync()).Any();
}
    <ul class="nav nav-pills flex-column">
        <li class="nav-item"><a class="nav-link @Muzostacja.Data.ManageNavPagesData.Nav_PanelRezerwacji.CreateReservationNavClass(ViewContext)" id="create-reservation" asp-controller="ReservationPanel" asp-action="CreateRoomreservation">Utwórz rezerwację</a></li>
        <li class="nav-item"><a class="nav-link @Muzostacja.Data.ManageNavPagesData.Nav_PanelRezerwacji.CreateVoucherNavClass(ViewContext)" id="create-voucher" asp-controller="ReservationPanel" asp-action="CreateVoucher">Dodaj karnet</a></li>
        <li class="nav-item"><a class="nav-link @Muzostacja.Data.ManageNavPagesData.Nav_PanelRezerwacji.IndexNavClass(ViewContext)" id="your-reservation" asp-controller="ReservationPanel" asp-action="Index">Twoje rezerwacje</a></li>
    </ul>

Na koniec zmieniłem w _LoginPartial.cshtml

<li class="nav-item">
                <form class="form-inline" asp-area="" asp-controller="ReservationPanel" asp-action="Index" method="get">
                    <button type="submit" class="nav-link btn btn-link text-dark">Panel rezerwacji</button>
                </form>
            </li>

screenshot-20201023133215.png

Naprawdę dziękuję Ci za pomoc @Kardash. Dzięki Tobie wiele się nauczyłem o layoutach. Pozdrowienia!

1

Supcio :)
Jak tak patrze to te RazorPage to takie kontrolery po każdy widok. Wydaje mi się ze jak byś na poprzednim rozwiązaniu zastosował takie nazewnictwo to też by zadziałało w identyczny sposób.
Co od nauki tez się dowiedziałem mnóstwo o Layoutach :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1