在SQL Server 2005中加载CRL程序集:给定的程序集名称或代码库无效.(HRESULT中出现异常:0x801

本文关键字:程序集 无效 代码 HRESULT 0x801 异常 加载 2005 Server SQL CRL | 更新日期: 2023-09-27 18:24:10

我已经编写了一个C#DLL,需要从存储过程中调用它。

我做的所有步骤都有错误,并设法解决了它们。但现在我已经厌倦了错误,所以我不得不求助于这里并询问。我解决不了这个问题。在将这个.DLL安装到SQL Server中的每一个小步骤中,我都会遇到大量的错误需要解决。

以下是该程序的C#代码(编译为类库以获得DLL):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Xml;
using System.IO;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
namespace WebServiceVatEuropa
{
    public class WebServiceVatEuropaClass
    {
        #region "Default Constructor"
        public WebServiceVatEuropaClass()
        {
        }
        #endregion
        [SqlProcedure]
        public static void check(string country, string vatNum)
        {
            bool valid;
            string name;
            string address;
            checkVatService vatchecker = new checkVatService();
            vatchecker.checkVat(ref country, ref vatNum, out valid, out name, out address);
        }
    }
}

它正在使用欧洲增值税检查网络服务(链接到网络服务)提供的另一个免费图书馆,并使用他们的图书馆(图书馆代码)(这个代码又长又复杂,我想你可以阅读我的。

嗯。我在SQLServerManagementStudio中用以下代码创建了存储过程(我在这里遇到了很多问题,很多错误等等,但现在它可以工作了):

CREATE PROCEDURE VAT_CHECKER
@Naz_codi nvarchar(2),
@vatNum nvarchar(max)
AS EXTERNAL NAME WebServiceVatEuropaClass.[WebServiceVatEuropa.WebServiceVatEuropaClass].[check]
GO

然后在数据库中我有:

  1. 使用msn 中的代码启用了clr

    sp_configure 'show advanced options', 1;
    GO
    RECONFIGURE;
    GO
    sp_configure 'clr enabled', 1;
    GO
    RECONFIGURE;
    GO
    
  2. 将数据库所有者更改为sa

  3. 使用此代码注册程序集

    CREATE ASSEMBLY [WebServiceVatEuropaClass] --AUTHORIZATION [mydb'administrator]
    FROM 'C:'Upload'WebServiceVatEuropa.dll'
    --WITH PERMISSION_SET = SAFE
    WITH PERMISSION_SET = UNSAFE
    --WITH PERMISSION_SET = EXTERNAL_ACCESS
    

然后当我启动时

EXEC VAT_CHECKER 'IT','10050721009'

我得到这个错误:

尝试加载程序集id 65545时,Microsoft.NET Framework中发生错误。服务器可能资源不足,或者该程序集可能不受PERMISSION_SET=EXTERNAL_ACCESS的信任或UNSAFE。再次运行查询,或查看文档以了解如何解决程序集信任问题。有关此的详细信息错误:System.IO.FileLoadException:无法加载文件或程序集'webservicevateuropa,版本=0.0.0.0,区域性=中性,PublicKeyToken=null'或其依赖项之一。给定的程序集名称或代码库无效。(HRESULT异常:0x80131047)

System.IO.FileLoadException:
位于System.Reflection.Assembly.nLoad(AssemblyName文件名,字符串codeBase,Evidence assemblySecurity,Assembly locationHint,StackCrawlMark&stackMark,布尔throwOnFileNotFound,布尔用于反省)
位于System.Reflection.Assembly.InteralLoad(AssemblyName assemblyRef,证据汇编Security,StackCrawlMark&stackMark,布尔用于反省)
位于System.Reflection.Assembly.InteralLoad(String assemblyString,Evidence assemblySecurity,StackCrawlMark&stackMark,用于Introspection的布尔值)
在System.Reflection.Assembly.Load(字符串assemblyString)

它可能是什么?我找不到任何修复方法…

在SQL Server 2005中加载CRL程序集:给定的程序集名称或代码库无效.(HRESULT中出现异常:0x801

错误消息基本上告诉了所有人-由于您的程序集正在访问外部web服务,因此必须将其配置为EXTERNAL_ACCESS

您并没有展示如何在SQL Server中创建程序集,但基本上,您需要使用以下内容:

CREATE ASSEMBLY assembly_name
FROM ...(your assembly).....
WITH PERMISSION_SET = { EXTERNAL_ACCESS }

你是这样做的吗?如果没有:请使用EXTERNAL_ACCESS权限集重试!

有关代码访问安全性的更多详细信息,请参阅MSDN文档

所以,我终于解决了这个问题(我简直不敢相信)。

以下是我所做的:

-代码基本上与上面相同。

-我试图在远程桌面计算机上的SQL server 2005上部署dll,但我使用Visual Studio 2010在本地编译它。也许这是个问题,也许不是。但我换了一个安装在远程桌面机器上的VisualStudio2008副本。我在一些网站上读到,Visual Studio中不同的目标体系结构编译设置可能会产生与我类似的问题。

-正如我所说,在将此程序集部署到SQL Server实例的任务中,我所做的每一步都会出错。这次也没什么不同。在远程桌面计算机上编译它之后,它给出了另一个关于XmlSerialization的错误。

注意:我之所以需要XmlSerializers,是因为我使用的Web服务使用Xml和C#Xml对象来操作数据,因此程序中涉及Xml。我不知道在其他情况下是否需要XmlSerializer,但在这种特殊情况下,我需要它,否则SQL服务器会给我带来开放性错误。

这个特殊问题的解决方案在这里解释:

Xml序列化问题

我通过像文章中所示的那样更改编译设置来生成这个额外的dll。

-这就结束了我在Visual Studio中必须做的事情。

现在它启动SQL部分:

  • 我必须为我自己的DLL和XmlSerialization创建一个程序集。

    CREATE ASSEMBLY [WebServiceVatEuropaClass] --AUTHORIZATION [mydb'administrator]
    FROM 'C:'Upload'WebServiceVatEuropa.dll'
    --WITH PERMISSION_SET = SAFE
    WITH PERMISSION_SET = UNSAFE
    --WITH PERMISSION_SET = EXTERNAL_ACCESS
    
    CREATE ASSEMBLY [WebServiceVatEuropaClassXmlSerializers] --AUTHORIZATION [mydb'administrator]
    FROM 'C:'Upload'WebServiceVatEuropa.XmlSerializers.dll'
    --WITH PERMISSION_SET = SAFE
    WITH PERMISSION_SET = UNSAFE
    --WITH PERMISSION_SET = EXTERNAL_ACCESS
    

注意:可能因为问题不是权限(尽管Sql服务器向我提供了完全误导性的SAFE/EXTERNAL权限错误消息),所以将程序集权限设置为EXTERNAL而不是UNSAFE可能就足够了。我这么说只是因为,如果不是严格需要的话,你可能不想允许UNSAFE许可,因为整个过程非常不安全(如果我通过在互联网上阅读很好地记录了自己),即使使用非对称密钥,也有人可以更换你的程序集

然后我创建了用于调用程序集的存储过程(与问题中的代码相同),这次当我调用EXEC时,它工作了!

希望这对其他有同样问题的人有用。