如何从 .t​​t 文件(T4 模板)中读取来自 web.config 的 appSetting

Posted

技术标签:

【中文标题】如何从 .t​​t 文件(T4 模板)中读取来自 web.config 的 appSetting【英文标题】:How can I read an appSetting from web.config from .tt file (T4 Template) 【发布时间】:2018-03-07 06:01:41 【问题描述】:

我试图在 web.config 文件中提供一个 URL,构建系统将在我的 Web 项目上编译 .tt 文件之前更新该 URL。

我的 .tt 文件中的相关部分如下:

<#@ template debug="true" hostSpecific="true" language="C#" #>
<#@ output extension=".ts" #>
<#@ Assembly Name="System.Core.dll" #>
<#@ Assembly Name="System.Configuration.dll" #>
<#@ import namespace="System" #>
<#@ import namespace="System.Reflection" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Configuration" #>
<#@ import namespace="System.Collections.Specialized" #>

import  Injectable  from "@angular/core";

<#= RegisterNameSpace("Server.Web.Dashboard.Models.APIRequest") #>
<#= RegisterNameSpace("Server.Web.Dashboard.Models.APIResponse") #>
<#= RegisterNameSpace("Server.Web.Dashboard.Models.APIGeneric") #>
<#= RegisterNameSpace("Server.Data.POCODataObjects") #>

@Injectable()
export class WebServiceCommunicatorService 

    rootUrl : string = '<#= ConfigurationManager.AppSettings["ServerServiceURL"] #>';

.....

当我尝试从 .tt 文件生成 .ts 文件时,我收到以下错误消息:

Severity    Code    Description Project File    Line    Suppression State
Error       An expression block evaluated as Null
System.ArgumentNullException: Value cannot be null.
Parameter name: objectToConvert
   at Microsoft.VisualStudio.TextTemplating.ToStringHelper.ToStringWithCulture(Object objectToConvert)
   at Microsoft.VisualStudio.TextTemplatingF553823B88CD6076D80EB08F6EA809752D0E5DC3E61C0FA53FB2F9AC22ACABF3B7BB9C8801A54E5DBC2A556C03FA42F2EA2AFCE58B708BEC94B0968193987868.GeneratedTextTransformation.TransformText() in webservicecommunicator.service.tt:line 35    Dashboard   webservicecommunicator.service.tt   35  

【问题讨论】:

【参考方案1】:

我采用了假装文件是 XML 文件而不是配置文件的方法。首先我找到web.config的绝对路径,然后加载它并读取节点。

首先是依赖项:

<#@ Assembly Name="System.Web.dll" #>
<#@ Assembly Name="System.Configuration.dll" #>
<#@ assembly name="System.Xml" #>

<#@ import namespace="System.Configuration" #>
<#@ import namespace="System.Web.Configuration" #>
<#@ import namespace="System.Collections.Specialized" #>
<#@ import namespace="System.Xml" #>
<#@ import namespace="System.IO" #>

所以这是我的尝试:

string GetWebServiceUrl() 
    XmlDocument doc = new XmlDocument();
    string absolutePath = this.Host.ResolvePath("../../../web.config");                
    doc.Load(absolutePath);
    XmlNode node = doc.DocumentElement.SelectSingleNode("/configuration/appSettings/add[@key='ServerServiceURL']");
    return node.Attributes["value"].Value.ToString();

【讨论】:

我认为 2 个答案的组合可能是正确的解决方案? 有时任何可行的方法都可能是正确的解决方案 :) 是的,当我将它作为配置文件打开时,由于访问保护级别,我无法访问它。但是 XmlDocument 的事情奏效了。【参考方案2】:

您可以尝试使用ConfigurationManager.OpenExeConfiguration(path) 方法打开硬编码路径(不确定是否可以执行相对路径)。此时您可以使用返回的Configuration 对象自己的AppSettings 属性。

【讨论】:

到目前为止,我已经设法找到了 web.config 的路径:string absolutePath = this.Host.ResolvePath("../../../web.config"); 我试过你的解决方案,但它不起作用,我认为它允许查看的位置有一些限制,当前目录在 C:\ProgramFiles 某处【参考方案3】:

添加 System.Configuration 程序集并将其导入您的模板文件,如下所示。这将允许您使用 ConfigurationManager 引用 AppSettings。

<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ output extension=".cs" #>
<#@ assembly name="System.Configuration" #>
<#@ import namespace="System.Configuration" #>

<#
    var myVariable = ConfigurationManager.AppSettings["MyConfigSetting"];

    ... more code here
#>

【讨论】:

虽然此代码可能会回答问题,但提供有关此代码为何和/或如何回答问题的额外上下文可提高其长期价值。 @AlexRiabov 我已经更新了我的答案。让我知道这是否足够。

以上是关于如何从 .t​​t 文件(T4 模板)中读取来自 web.config 的 appSetting的主要内容,如果未能解决你的问题,请参考以下文章

T4语法快速入门

T4语法快速入门

从 t4 脚手架模板访问我的模型中的元数据(数据注释)

来自服务器资源管理器的 T4 模板使用连接

如何从 PowerShell 脚本触发 T4 模板

如何使用从解决方案中现有基类继承的 T4 模板生成类?