Mensaje de error cuando se utiliza un objeto de common language runtime de SQL Server 2005: "No se puede cargar el ensamblado de serialización generado dinámicamente"


Nº de error: 101935 (SQLBUDT)

Síntomas


Cuando utiliza un objeto de common language runtime (CLR) de Microsoft SQL Server 2005, puede recibir un mensaje de error similar al siguiente:
Msj 6522, nivel 16, estado 2, línea 1
Se ha producido un error de.NET Framework durante la ejecución de la rutina de definido por el usuario o agregado 'ObjectName':
System.InvalidOperationException: No se puede cargar el ensamblado de serialización generado dinámicamente. En algunos ensamblados de entornos de hospedaje la funcionalidad de carga está restringida, considere utilizar un serializador pre-generado. Vea la excepción interna para obtener más información. ---> System.IO.FileLoadException: se deshabilitaron LoadFrom(), LoadFile(), Load y LoadModule() por el host.
System.IO.FileLoadException:

en System.Reflection.Assembly.nLoadImage (Byte [] rawAssembly, Byte [] rawSymbolStore, evidencia, evidencia, StackCrawlMark & stackMark, Boolean fIntrospection)
en System.Reflection.Assembly.Load (Byte [] rawAssembly, Byte [] rawSymbolStore securityEvidence pruebas)
en Microsoft.CSharp.CSharpCodeGenerator.FromFileBatch (CompilerParameters opciones, nombres de archivo de cadena [])
en Microsoft.CSharp.CSharpCodeGenerator.FromSourceBatch (CompilerParameters opciones, fuentes de cadena [])
en Microsoft.CSharp.CSharpCodeGenerator.System.CodeDom.Compiler.ICodeCompiler.CompileAssemblyFromSourceBatch (CompilerParameters opciones, fuentes de cadena [])
en System.CodeDom.Compiler.CodeDomProvider.CompileAssemblyFromSource (CompilerParameters opciones, String [] s
...
System.InvalidOperationException:
en System.Xml.Serialization.Compiler.Compile (padre del ensamblado, cadena ns, parámetros de CompilerParameters, evidencia evidence)
en System.Xml.Serialization.TempAssembly.GenerateAssembly (xmlMappings de XmlMapping [], tipos de tipo [], String defaultNamespace, evidencia evidence, parámetros de CompilerParameters, ensamblado, ensamblados Hashtable)
en System.Xml.Serialization.TempAssembly.. ctor (xmlMappings de XmlMapping [], tipos de tipo [], String defaultNamespace, ubicación de la cadena, evidencia evidence)
en System.Xml.Serialization.XmlSerializer.GenerateTempAssembly (XmlMapping xmlMapping, tipo, String defaultNamespace)
en System.Xml.Serialization.XmlSerializer.. ctor (tipo, String defaultNamespace)
en System.Xml.Serialization.XmlSe...
Por ejemplo, puede recibir el mensaje de error cuando se utiliza un objeto CLR que llama a un servicio Web o realice la conversión de tipos definidos por el usuario a XML dentro de SQL Server.

Causa


Este problema se produce cuando un objeto CLR se convierte al tipo de datos XML. Cuando se produce esta conversión, Windows Communication Foundation (anteriormente con nombre en código "Indigo") intenta hacer lo siguiente:
  • Generar un nuevo ensamblado de serialización XML.
  • Guardar el ensamblado en el disco.
  • Cargar el ensamblado en el dominio de aplicación actual.
Sin embargo, SQL Server no permite este tipo de acceso al disco en el CLR de SQL por razones de seguridad. Por lo tanto, recibirá el mensaje de error que se menciona en la sección "Síntomas". Varios escenarios pueden hacer que el objeto CLR para convertirse en el tipo de datos XML.

Para obtener más información acerca de Windows Communication Foundation, visite el siguiente sitio Web de Microsoft Developer Network (MSDN):Puede recibir el mensaje de error que se menciona en la sección "Síntomas" en las siguientes situaciones:
  • El código CLR que implementa explícitamente objetos CLR utiliza la clase XmlSerializer . Estos objetos CLR pueden incluir procedimientos almacenados, funciones, tipos definidos por el usuario, agregados y desencadenadores.
  • Utilizar un servicio Web en el código CLR.
  • Enviar o recibir objetos CLR en SQL Server mediante el acceso directo de HTTP/SOAP a SQL Server.
  • El objeto CLR convierte a un tipo definido por el usuario en el tipo de datos XML.

Solución


Para resolver este problema, debe utilizar la herramienta Generador de serializador XML (Sgen.exe) para crear el ensamblado de serialización XML para el ensamblado original manualmente. A continuación, cargue los ensamblados en una base de datos de SQL Server.

Ejemplo de código

Por ejemplo, desea crear una función CLR que devuelve datos XML mediante el uso de un ensamblado que se crea mediante el ejemplo de código siguiente:
using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.Xml;
using System.Xml.Serialization;
using System.Text;
using System.IO;
public partial class StoredProcedures
{
[Microsoft.SqlServer.Server.SqlFunction]
public static SqlString XMLTest()
{
Person p = new Person();
return new SqlString(p.GetXml());

}
public class Person
{
public String m_FirstName = "Jane";
public String m_LastName = "Dow";

public String GetXml()
{
XmlSerializer ser = new XmlSerializer(typeof(Person));
StringBuilder sb = new StringBuilder();
StringWriter wr = new StringWriter(sb);
ser.Serialize(wr, this);

return sb.ToString();
}

}
}
Cuando se llama a la función PruebaXml en SQL Server Management Studio, que espera recibir el resultado siguiente:
<?xml version="1.0" encoding="utf-16"?>
<Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m_FirstName>Jane</m_FirstName>
<m_LastName>Dow</m_LastName>
</Person>
Para devolver el resultado correcto, debe crear manualmente el ensamblado de serialización XML para el ensamblado original. Utilice uno de los métodos siguientes para crear manualmente el ensamblado de serialización.

Nota: Estos métodos suponen que las condiciones siguientes son verdaderas:
  • Ha creado una base de datos dbTest en una instancia de SQL Server 2005.
  • Todos los archivos de proyecto se guardan en la carpeta C:\CLRTest.

Método 1: Crear un proyecto CLR de SQL Server mediante Microsoft Visual Studio 2005

Puede crear el ensamblado de serialización mediante la opción de Eventos de generación en Microsoft Visual Studio 2005. Para ello, siga estos pasos:
  1. Inicie Visual Studio 2005.
  2. Cree un nuevo proyecto de SQL Server que se denomina MyTest.
  3. En el cuadro de diálogo Agregar referencia de base de datos , haga clic en la referencia que se conecta a la base de datos de la documentación y, a continuación, haga clic en Aceptar.

    Si la referencia no está en la lista, debe crear una nueva referencia. Para ello, haga clic en Agregar nueva referencia.
  4. En el menú proyecto , haga clic en La función definida. Aparecerá el cuadro de diálogo Agregar nuevo elemento .
  5. Haga clic en Agregar para agregar un nuevo archivo. De forma predeterminada, el archivo se denomina Function1.cs.

    Nota: Recibe el mensaje de error que se menciona en la sección "Síntomas" si se implementa el proyecto en la base de datos y, a continuación, ejecute la siguiente instrucción de Transact-SQL:
    SELECT [dbTest].[dbo].[XMLTest] ()
    Debe seguir los pasos 6 a 16 para resolver este problema.
  6. Agregue el código que aparece en la sección "Ejemplo de código" en el archivo Function1.cs.
  7. En el menú proyecto , haga clic en Propiedades de MyTest.
  8. En el cuadro de diálogo MyTest , haga clic en el
    Opción de Eventos de generación .
  9. Escriba el comando siguiente en el cuadro línea de comandos del evento de generación posterior :
    "C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\sgen.exe" /force "$(TargetPath)"
    Nota: La opción/force genera un nuevo ensamblado de serialización cada vez que modifica el ensamblado de origen. Además, se debe modificar este comando si tiene instalado Visual Studio 2005 en otra carpeta.
  10. En la carpeta C:\CLRTest, cree dos archivos de texto que se denominan Predeployscript.sql y Postdeployscript.sql.
  11. Agregue las siguientes instrucciones de Transact-SQL en el archivo Predeployscript.sql:
    IF EXISTS (SELECT [name] FROM sys.assemblies WHERE [name] = N'MyTest.XmlSerializers') 
    DROP ASSEMBLY [MyTest.XmlSerializers]
  12. Agregue las siguientes instrucciones de Transact-SQL al archivo Postdeployscript.sql:
    CREATE ASSEMBLY [MyTest.XmlSerializers] from
    'C:\CLRTest\MyTest\MyTest\bin\Debug\MyTest.XmlSerializers.dll'
    WITH permission_set = SAFE
  13. En el menú proyecto , haga clic en Agregar elemento existente.
  14. En el cuadro de diálogo Agregar elemento existente , busque la carpeta C:\CLRTest y, a continuación, haga clic en todos los archivos (*. *)en la lista archivos de tipo .
  15. En el cuadro nombre de archivo , escriba
    Postdeployscript.sql; PreDeployScript.SQLy, a continuación, haga clic en
    Aceptar.
  16. En el menú Generar , haga clic en Implementar MyTest.
  17. Ejecute la siguiente instrucción de Transact-SQL en SQL Server Management Studio:
    SELECT [dbTest].[dbo].[XMLTest] ()
    Recibir el resultado correcto.

Método 2: Crear un proyecto de CLR de SQL en la ventana del símbolo del sistema de Visual Studio

  1. Busque la carpeta C:\CLRTest.
  2. Crear un archivo de texto denominado MyTest.cs.
  3. Agregue el código que aparece en la sección "Ejemplo de código" en el archivo MyTest.cs.
  4. Abra la ventana de símbolo del sistema de Visual Studio 2005.
  5. Escriba CD C:\CLRTesty, a continuación, presione ENTRAR.
  6. Escriba csc/t: library MyTest.csy, a continuación, presione ENTRAR.
  7. Escriba sgen.exe /force MyTest.dlly, a continuación, presione ENTRAR.
  8. Ejecute las siguientes instrucciones de Transact-SQL en SQL Server Management Studio:
    USE dbTest
    GO
    CREATE ASSEMBLY [MyTest] from 'C:\CLRTest\MyTest.dll'
    GO
    CREATE ASSEMBLY [MyTest.XmlSerializers.dll] from 'C:\CLRTest\MyTest.XmlSerializers.dll'
    GO

    CREATE FUNCTION XMLTest()
    RETURNS nvarchar (max)
    AS
    EXTERNAL NAME MyTest.StoredProcedures.XMLTest
    GO
  9. Ejecute la siguiente instrucción de Transact-SQL en SQL Server Management Studio:
    SELECT [dbTest].[dbo].[XMLTest] ()
    Recibir el resultado correcto.

Si utiliza un ensamblado principal que hace referencia a otros ensamblados, debe generar ensamblados de serialización XML para todos los ensamblados a los que hace referencia el ensamblado principal. A continuación, debe cargar estos ensamblados de serialización XML en la base de datos de SQL Server mediante la instrucción CREATE ASSEMBLY.

Estado


Este comportamiento es por diseño.

Referencias


Para obtener más información acerca de la serialización XML de objetos de base de datos CLR, visite el siguiente sitio Web de MSDN:Para obtener más información acerca de la herramienta Generador de serializador XML, visite el siguiente sitio Web de MSDN: