微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 ASP.NET Core RazorPages 中更改 cshtml 文件的名称

如何解决在 ASP.NET Core RazorPages 中更改 cshtml 文件的名称

我的环境:带有 RazorPages 的 ASP.NET Core 5、Webpack 5。

在引用 svg 文件的剃刀页面 (.cshtml) 中,我想内联它们。这是 Webpack 可以做到的(通过插件),但我不确定如何集成这两个技术堆栈。

我可以编写模板化的 cshtml 文件,并通过 webpack 填充它们:

ContactUs.cshtml.cs
ContactUs.cshtml                     <------ read by webpack
ContactUs.generated.cshtml           <------ generated by webpack

但是如何强制 msbuild / aspnet 在构建时使用生成文件 (ContactUs.generated.cshtml) 而不是模板文件 (ContactUs.cshtml)?

我怀疑答案是使用 IPageRouteModelConvention,但我不确定如何使用。

一个肮脏的解决方法是使用文件ContactUs.template.cshtmlContactUs.cshtml,但我更喜欢上面的内容,因为“生成”更清晰。)


更新

为了简化问题:

编译器查找 Foo.cshtml.csFoo.cshtml

我如何告诉它改为查找 Foo.cshtml.csFoo.generated.cshtml

解决方法

加载应用程序时,框架会为您加载一组 PageRouteModel,这些 SelectorModel 是从 razor 页面文件夹自动生成的(按照惯例)。每个这样的模型都包含一组 AttributeRouteModel,每个模型都有一个 AttributeRouteModel.Template。您需要做的只是通过从自动生成的值中删除后缀部分来修改 IPageRouteModelConvention

您可以创建自定义 PageRouteModel 来定位每个 AttributeRouteModel.Template。但是,您无法确保路线不会重复(因为修改 IPageRouteModelProvider 后,它可能会与其他一些现有路线重复)。除非您必须管理一组共享的路由模板。相反,您可以创建自定义 PageRouteModel。它在一处提供所有 Index.cshtml,以便您可以修改、添加或删除任何内容。这种方式非常方便,您可以支持 2 个剃刀页面,其中一个页面的优先级高于另一个页面(例如:您有 Index.generated.cshtmlIndex.generated.cshtml,并且您希望它选择 Index.cshtml。如果该生成的视图不存在,则将使用默认的 public class SuffixedNamePageRouteModelProvider : IPageRouteModelProvider { public SuffixedNamePageRouteModelProvider(string pageNameSuffix,int order = 0) { _pageNameSuffixPattern = string.IsNullOrEmpty(pageNameSuffix) ? "" : $"\\.{Regex.Escape(pageNameSuffix)}$"; Order = order; } readonly string _pageNameSuffixPattern; public int Order { get; } public void OnProvidersExecuted(PageRouteModelProviderContext context) { } public void OnProvidersExecuting(PageRouteModelProviderContext context) { if(_pageNameSuffixPattern == "") return; var suffixedRoutes = context.RouteModels.Where(e => Regex.IsMatch(e.ViewEnginePath,_pageNameSuffixPattern)).ToList(); var overriddenRoutes = new HashSet<string>(StringComparer.OrdinalIgnoreCase); foreach (var route in suffixedRoutes) { //NOTE: this is not required to help it pick the right page we want. //But it's necessary for other related code to work properly (e.g: link generation,...) //we need to update the "page" route data as well route.RouteValues["page"] = Regex.Replace(route.RouteValues["page"],_pageNameSuffixPattern,""); var overriddenRoute = Regex.Replace(route.ViewEnginePath,""); var isIndexRoute = overriddenRoute.EndsWith("/index",StringComparison.OrdinalIgnoreCase); foreach (var selector in route.Selectors.Where(e => e.AttributeRouteModel?.Template != null)) { var template = Regex.Replace(selector.AttributeRouteModel.Template,""); if (template != selector.AttributeRouteModel.Template) { selector.AttributeRouteModel.Template = template; overriddenRoutes.Add($"/{template.TrimStart('/')}"); selector.AttributeRouteModel.SuppressLinkGeneration = isIndexRoute; } } //Add another selector for routing to the same page from another path. //Here we add the root path to select the index page if (isIndexRoute) { var defaultTemplate = Regex.Replace(overriddenRoute,"/index$","",RegexOptions.IgnoreCase); route.Selectors.Add(new SelectorModel() { AttributeRouteModel = new AttributeRouteModel() { Template = defaultTemplate } }); } } //remove the overridden routes to avoid exception of duplicate routes foreach (var route in context.RouteModels.Where(e => overriddenRoutes.Contains(e.ViewEnginePath)).ToList()) { context.RouteModels.Remove(route); } } } )。

这里是详细代码:

IPageRouteModelProvider

Startup.ConfigureServices 中注册 services.AddSingleton<IPageRouteModelProvider>(new SuffixedNamePageRouteModelProvider("generated"));

import React from "react";
import {
  View,StyleSheet,Text,ImageBackground,Image,Button,TouchableOpacity,} from "react-native";
import { LinearGradient } from "expo-linear-gradient";
import colors from "../config/colors";
import { withNavigation } from "react-navigation";

export default function HomePageScreen({ navigation }) {
  return (
    <ImageBackground
      style={styles.background}
      source={require("../assets/background.jpg")}
    >
      <Image style={styles.logo} source={require("../assets/logo2.png")} />
      {/* the create button */}
      <LinearGradient
        colors={[colors.primary,colors.secondary]}
        start={{ x: 0,y: 0 }}
        end={{ x: 1,y: 0 }}
        style={styles.createButton}
      >
        <TouchableOpacity
          style={styles.touch}
          onPress={() => navigation.navigate("Create Project")}
        >
          <Text style={styles.buttonText}>Create</Text>
        </TouchableOpacity>
      </LinearGradient>
      {/* the search button */}
      <LinearGradient
        colors={[colors.primary,y: 0 }}
        style={styles.searchButton}
      >
        <TouchableOpacity
          style={styles.touch}
          onPress={() => navigation.navigate("Search Projects")}
        >
          <Text style={styles.buttonText}>Search</Text>
        </TouchableOpacity>
      </LinearGradient>
    </ImageBackground>
  );
}

const styles = StyleSheet.create({
  background: {
    width: "100%",height: "100%",alignItems: "center",justifyContent: "center",},logo: {
    height: 275,width: 275,position: "absolute",top: 60,createButton: {
    height: 70,width: 325,bottom: 150,borderRadius: 999,touch: {
    height: 70,textAlignVertical: "center",searchButton: {
    height: 70,bottom: 50,buttonText: {
    color: "white",fontSize: 28,fontWeight: "bold",alignSelf: "center",});

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。