7

Attualmente sto cercando di migrare un progetto ASP.net MVC 5 a 6. MVCCome si possono definire sezioni con contenuto predefinito in MVC 6?

Come faccio a migrare il seguente codice:

public static class SectionExtensions 
{ 
    public static HelperResult RenderSection(this WebPageBase webPage, [RazorSection] string name, Func<dynamic, HelperResult> defaultContents) 
    { 
     return webPage.IsSectionDefined(name) ? webPage.RenderSection(name) : defaultContents(null); 
    } 
} 

[RazorSection] fa parte del gruppo JetBrains.Annotations.

risposta

6

Invece di WebPageBase ho usato RazorPage in Microsoft.AspNet.Mvc.Razor

namespace Stackoverflow 
{ 
    public static class SectionExtensions 
    { 
     public static IHtmlContent RenderSection(this RazorPage page, [RazorSection] string name, Func<dynamic, IHtmlContent> defaultContents) 
     { 
      return page.IsSectionDefined(name) ? page.RenderSection(name) : defaultContents(null); 
     } 
    } 
} 

quindi fare riferimento alla classe nella pagina rasoio @using static Stackoverflow.SessionExtensions, e lo chiamano in questo modo:

@this.RenderSection("extra", @<span>This is the default!</span>)) 

Un alternativa modo sarebbe quella di basta fare questo nella vista (preferisco in questo modo, sembra molto più semplice):

@if (IsSectionDefined("extra")) 
{ 
    @RenderSection("extra", required: false) 
} 
else 
{ 
    <span>This is the default!</span> 
} 

Spero che questo aiuti.

Update 1 (dai commenti)

facendo riferimento allo spazio dei nomi

@using Stackoverflow 

non si deve includere la parola chiave static, ma quando si chiama esso, si dovrà fare riferimento al reale classe nello spazio dei nomi e anche passare 'questo' nella funzione.

@SectionExtensions.RenderSection(this, "extra", @<span>This is the default!</span>) 

Update 2

C'è un bug nel rasoio che non consente di chiamare i delegati modello Func <dynamic, object> e = @<span>@item</span>; all'interno di una sezione. Si prega di consultare https://github.com/aspnet/Razor/issues/672

Una soluzione attuale:

public static class SectionExtensions 
{ 
    public static IHtmlContent RenderSection(this RazorPage page, [RazorSection] string name, IHtmlContent defaultContents) 
    { 
     return page.IsSectionDefined(name) ? page.RenderSection(name) : defaultContents; 
    } 
} 

e poi la pagina di rasoio:

section test { 
    @this.RenderSection("extra", new HtmlString("<span>this is the default!</span>")); 
} 
+0

Grazie per la risposta. Non mi piace il modo alternativo semplicemente perché mi piace mantenere se le dichiarazioni al di fuori della vista. Ho provato quello che hai citato e tutto sembra funzionare tranne per il namespace. Sembra come se dovessi usare: SectionExtensions.RenderSection al posto di this.RenderSection. L'istruzione using non sembra fare nulla? –

+0

Ho aggiornato la mia risposta, per qualche motivo il mio precedente montaggio non è andato a buon fine. Per fare riferimento direttamente a una classe statica, si utilizzerà la parola chiave statica es. '@utilizzando Stackoverflow.SessionExtensions statici', tuttavia se si fa semplicemente riferimento allo spazio dei nomi, non è necessario aggiungere statici ad es. '@using StackOverflow'. Tutto dipende se vuoi includere l'intero spazio dei nomi nella tua vista. In tal caso, devi chiamare '@ SessionExtension.RenderSection' invece di '@ this.RenderSection' e quindi passare 'this' nella funzione RenderSection (this, "test", @ default). Fammi sapere se questo aiuta. –

+0

Ho pensato che funzionasse, ma ho riscontrato un problema. Diciamo che hai un layout annidato.Nel MasterLayout hai uno standard @RenderSection ("test", falso). Quindi hai un SubMasterLayout che eredita il MasterLayout. Se provo prova @section { @ SectionExtensions.RenderSection (questo, "extra", @ Questa è l'impostazione predefinita!) } ottengo la seguente eccezione: '__razor_template_writer': un parametro o una variabile locale non può avere lo stesso nome di un parametro del tipo di metodo. Questo ha funzionato perfettamente in MVC5? –