我已经为C#中的文本语音转换编写了一些例程。这些例程需要一堆定义的转换规则(search-string / replace-string)。我们的想法是将规则存储为程序集中的嵌入式资源,然后从中读取规则。反序列化的起点如下
public static phonet42n.Core.Rules Deserialize(phonet42n.Core.Rules.Ressources ressource)
{
string ressourceName;
phonet42n.Core.Rules returnValue;
System.Xml.XmlReader reader;
System.Xml.Serialization.XmlSerializer xmlSerializer;
phonet42n.Core.SerializableRules serializeableRules;
returnValue = new phonet42n.Core.Rules();
switch (ressource)
{
case Ressources.German_01:
ressourceName = RESSOURCE_XML_GERMAN_01;
break;
case Ressources.German_02:
ressourceName = RESSOURCE_XML_GERMAN_02;
break;
default:
ressourceName = RESSOURCE_XML_GERMAN_01;
break;
}
using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(ressourceName))
{
using (reader = System.Xml.XmlReader.Create(stream))
{
xmlSerializer = new System.Xml.Serialization.XmlSerializer(typeof(phonet42n.Core.SerializableRules));
serializeableRules = (phonet42n.Core.SerializableRules)xmlSerializer.Deserialize(reader);
}
}
foreach (phonet42n.Core.Rule entry in serializeableRules.Rules)
{
if (entry.SearchString != null && entry.SearchString.Length > 0)
{
returnValue.Add(entry.Index, entry);
}
}
return returnValue;
}
在常规可执行文件中执行时,应用程序正常工作。
在SQL Server中执行注册函数时,出现以下错误:
SELECT [dbo].[Phonet42n]('mayer', 1)
...产生
Meldung 6522,Ebene 16,Status 1,Zeile 22
.NET Framework-FehlerbeimAusführenderbenutzerdefinierten Routine oder des benutzerdefinierten Aggregats'Phonet42n':
System.InvalidOperationException:Fehler im XML-Dokument(3,4)。 ---> System.MethodAccessException:Fehler beim Versuch der Methode“Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReader1.Read8_SerializableRules(Boolean,Boolean)”,auf Methode“phonet42n.Core.Rule..ctor()”zuzugreifen。
System.MethodAccessException:
bei System.RuntimeTypeHandle.CreateInstance(RuntimeType type,Boolean publicOnly,Boolean noCheck,Boolean& canBeCached,RuntimeMethodHandleInternal& ctor,Boolean& bNeedSecurityCheck)
bei System.RuntimeType.CreateInstanceSlow(Boolean publicOnly,Boolean skipCheckThis,Boolean fillCache,StackCrawlMark& stackMark)
bei System.Activator.CreateInstance(Type type,Boolean nonPublic)
bei System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr,Binder binder,Object [] args,CultureInfo culture,Object [] activationAttributes,StackCrawlMark& stackMark)
bei System.Activator.CreateInstance(Type type,BindingFlags bindingAttr,Binder binder,Object [] args,CultureInfo culture,Object [] activationAttributes)
bei System.Activator.CreateInstance(Type type,BindingFlags bindingAttr,Binder binder,Object [] args,CultureInfo culture)
bei Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReader1.Read8_SerializableRules(Boolean isNullable,Boolean checkType)
bei Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReader1.Read19_Rules()
System.InvalidOperationException:
bei System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader,String encodingStyle,XmlDeserializationEvents事件)
bei System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader)
bei phonet42n.Core.Rules.Deserialize(Ressources ressource)
bei phonet42n.Core.Rules..ctor(Ressources ressource,Characters characters)
bei phonet42n.Core.HashTable..ctor(Ressources ressource)
bei phonet42n.Core.Match..ctor(Re ...
有什么想法吗?
答案 0 :(得分:2)
每当有安全例外情况时,您可以先尝试将程序集设置为PERMISSION_SET = EXTERNAL_ACCESS
,如果这不起作用,您可以尝试UNSAFE
。但是,如果有人试图动态加载程序集,那么即使对于标记为UNSAFE
的程序集,也应禁止该程序集。
由于此处的问题是想要包含一组规则,这可能可以在另一个程序集中完成。然后主程序集可以引用包含规则的那个,然后只需将包含规则的规则加载到SQL Server中。这将允许两个程序集保持标记为SAFE
。
当然,如果没有迫切需要将规则分开,那么您也可以直接将它们放入类中的集合中。
答案 1 :(得分:1)
我对evreything做了一个撤消,除了构造函数部分(私有/公共)。无论是否签署程序集,我都会收到以下消息(10327):
为程序集“phonet42n.Core”创建程序集失败,因为程序集 'phonet42n.Core'未获得PERMISSION_SET =的授权 EXTERNAL_ACCESS。当任何一个组件被授权时,组件被授权 以下是真实的:数据库所有者(DBO)具有EXTERNAL ACCESS ASSEMBLY权限和数据库具有TRUSTWORTHY数据库 财产;或者使用证书或证书签署程序集 具有EXTERNAL ACCESS的相应登录的非对称密钥 大会许可。
不幸的是我不熟悉签署程序集:我刚刚检查了项目属性的属性页中的复选框:
不知道是否缺少其他步骤。
无论如何,正如消息中所建议的那样,我尝试使用以下语句创建非对称密钥:
USE master;
GO
IF EXISTS (SELECT * FROM [sys].[syslogins] WHERE [sid] = SUSER_SID('SQLCLRTestLogin'))
BEGIN
PRINT 'Dropping Login...'
DROP LOGIN [SQLCLRTestLogin]
PRINT 'End'
END
GO
IF EXISTS (SELECT * FROM [sys].[asymmetric_keys] WHERE [name] = 'SQLCLRTestKey')
BEGIN
PRINT 'Dropping Asymmetric Key...'
DROP ASYMMETRIC KEY [SQLCLRTestKey]
PRINT 'End'
END
GO
BEGIN
PRINT 'Creating Login...'
CREATE ASYMMETRIC KEY [SQLCLRTestKey] FROM EXECUTABLE FILE = 'D:\phonet42n.net\Core\bin\Debug\phonet42n.Core.dll'
PRINT 'End'
PRINT 'Creating Asymmetric Key...'
CREATE LOGIN [SQLCLRTestLogin] FROM ASYMMETRIC KEY [SQLCLRTestKey]
PRINT 'End'
PRINT 'Granting Access...'
GRANT EXTERNAL ACCESS ASSEMBLY TO [SQLCLRTestLogin];
PRINT 'End'
END
GO
如果已签名的程序集,这些语句会成功,而在无符号程序集的情况下,我会收到以下错误消息(15208):
顺便说一句..不知道这是否重要。组件的目标.NET Framework是4.5。最后......出现初始错误消息:Adwaenyth对于缺少的公共默认构造者是正确的。该消息到目前为止具有误导性,因为缺少的构造函数不会影响程序集的注册。只有在运行时成功注册后,才能调用phonet42n函数。证书,非对称密钥或私钥文件不存在或 格式无效。
我真的不知道,这是否是设计的解决方案。我不知道是否为任何可能的线程打开了门。
我可以强调Stairway series articles特别是在SQLCLR上。优秀!它有助于理解SQLCLR如何工作以及它有什么用处。
而且(真的)最后:对我来说,总体结果是,我将从XML中提取规则并通过填充srutzky建议的集合来直接加载它们。可能会更高效。