繁体   English   中英

在Dynamics AX X ++中解压缩GZip流

[英]Decompress a GZip Stream in Dynamics AX X++

我正在尝试在X ++中压缩.NET GZIPStream,但遇到了一个错误。 创建字符串的.NET代码非常简单:

    private string CompressString()
    {
        string stringToCompress = "Some data here";
        string result = string.Empty;

        using (MemoryStream output = new MemoryStream())
        using (GZipStream gzip = new GZipStream(output, CompressionMode.Compress, true))
        using (StreamWriter writer = new StreamWriter(gzip))
        {
            writer.Write(stringToCompress);
            writer.Close();
            result = Convert.ToBase64String(output.ToArray());
        }

        return result;
    }

AX端将通过某些Web服务调用获得压缩的字符串。 我目前的X ++代码如下,但在创建StreamWriter时,我收到错误“无法创建对象'CLRObject'。

static void Job2(Args _args)
{
   System.String decodedString;
   System.Byte[] buffer;
   System.IO.Compression.GZipStream gzip;
   System.IO.StreamWriter writer;
   System.IO.MemoryStream output;
   InteropPermission permission;
   CLRObject ex;

   str compressedString ="Compressed data here";
   ;

   ttsBegin;
   permission = new InteropPermission(InteropKind::ClrInterop);
   permission.assert();

   buffer = System.Convert::FromBase64String(compressedString);
   output = new System.IO.MemoryStream(buffer);
   gzip = new System.IO.Compression.GZipStream(output, System.IO.Compression.CompressionMode::Decompress);

   try {
       //Error here: "Object 'CLRObject' could not be created"
       writer = new System.IO.StreamWriter(gzip);
       writer.Write(decodedString);
       writer.Close();

       CodeAccessPermission::revertAssert();
   } 
   catch (Exception::CLRError) {
       //Code never executes past this point 
       ex = CLRInterop::getLastException();

       while(ex != null) {
           error(ex.ToString());
           ex = ex.get_InnerException();
       }
   }

   ttsCommit;
   info(decodedString);
}

编辑 :建立在下面的@ robert-allen的答案上,在AX中完成此操作的正确代码是:

static void Job2(Args _args)
{
   System.String decodedString;
   System.Byte[] buffer;
   System.IO.Compression.GZipStream gzip;
   System.IO.StreamReader reader; //<-- Reader instead of writer
   System.IO.MemoryStream output;
   InteropPermission permission;
   CLRObject ex;

   str compressedString ="Compressed data here";
   ;

   ttsBegin;
   permission = new InteropPermission(InteropKind::ClrInterop);
   permission.assert();

   buffer = System.Convert::FromBase64String(compressedString);
   output = new System.IO.MemoryStream(buffer);
   gzip = new System.IO.Compression.GZipStream(output, System.IO.Compression.CompressionMode::Decompress);

   try {
       //Reader code changes
       reader = new System.IO.StreamReader(gzip);
       decodedString = reader.ReadToEnd();
       reader.Close();
       //End reader code changes

       CodeAccessPermission::revertAssert();
   } 
   catch (Exception::CLRError) {
       //Code never executes past this point 
       ex = CLRInterop::getLastException();

       while(ex != null) {
           error(ex.ToString());
           ex = ex.get_InnerException();
       }
   }

   ttsCommit;
   info(decodedString);
}

您是否可以在代码周围添加try catch以查看得到的确切消息,因为Ax中有2个错误并不能真正告诉您发生了什么:

  • 调用的目标已引发异常
  • 无法创建CLRObject

第一个是.net在.NET类型的构造函数中遇到问题,并且可能有多种原因,因此异常详细信息应该能够为您提供帮助。

第二个可能更困难,因为它可能是找不到的程序集。 但是在那种情况下,您可能会了解正在寻找什么文件的信息,并且应该将您带到Axe期望它们所在的位置。 (因此,将您的程序集放入“全球程序集”案例中无疑是一个好主意。

要从异常中获取更多信息,您可以执行以下操作:

catch (Exception::CLRError)
{
     ex = ClrInterop::getLastException();
     if (ex != null)
     {
        ex = ex.get_InnerException();
        while (ex != null)
        {
            error(ex.ToString());
            ex = ex.get_InnerException();
        }
    }
}

Kenny Saelen方法的问题在于,许多CLRInterop错误都达到了这样的水平,即它们突破了Dynamics AX X ++ catch子句,无论它是否被指定为捕获Exception :: CLRError。 我在使用System.IO方法之前遇到过这种情况,例如文件移动/删除。

更好地查看错误的一种方法(因为您无法在X ++中正确捕获它)是用.NET代码重写您的作业,并使用一个完全能够捕获该错误的.NET catch块。 在C#控制台应用程序中生成对象,然后重新创建封装在.NET try / catch中的相同行为。

像这样的东西:

static void Main(string[] args)
{
    System.String decodedString;
    System.Byte[] buffer;
    System.IO.Compression.GZipStream gzip;
    System.IO.StreamWriter writer;
    System.IO.MemoryStream output;

    string compressedString = "sample";

    buffer = System.Convert.FromBase64String(compressedString);
    output = new System.IO.MemoryStream(buffer);
    gzip = new System.IO.Compression.GZipStream(output, System.IO.Compression.CompressionMode.Decompress);

    try
    {
        writer = new System.IO.StreamWriter(gzip);
        writer.Write(decodedString);
        writer.Close();

        Console.Write(decodedString);
        Console.ReadKey();
    }
    catch (Exception ex)
    {
        Console.Write(ex.Message);
        Console.ReadKey();
    }
}

让我知道这是否对您有用。

干杯

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM