Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/31.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ASP.NET-LocalReport.Render()-模拟的令牌无效_C#_Asp.net_Asp.net Mvc_Multithreading_Reporting Services - Fatal编程技术网

C# ASP.NET-LocalReport.Render()-模拟的令牌无效

C# ASP.NET-LocalReport.Render()-模拟的令牌无效,c#,asp.net,asp.net-mvc,multithreading,reporting-services,C#,Asp.net,Asp.net Mvc,Multithreading,Reporting Services,我正在尝试在ASP.NET MVC web应用程序中使用本地reporting services生成PDF报告 问题是,当对Render()方法的调用在单独的任务中完成时,我得到一个异常: Microsoft.ReportingServices.ReportProcessing.ReportProcessingException: 未能加载表达式宿主程序集。详细信息:的令牌无效 模拟-它不能被复制 如果对Render()的调用被同一线程中的用户请求(通过控制器->类库)命中,则不会引发异常 我现

我正在尝试在ASP.NET MVC web应用程序中使用本地reporting services生成PDF报告

问题是,当对
Render()
方法的调用在单独的
任务中完成时,我得到一个异常:

Microsoft.ReportingServices.ReportProcessing.ReportProcessingException: 未能加载表达式宿主程序集。详细信息:的令牌无效 模拟-它不能被复制

如果对
Render()
的调用被同一线程中的用户请求(通过控制器->类库)命中,则不会引发异常

我现在没有选择了。到目前为止我尝试过的事情:

我已尝试使用
块将任务包装到

// Doesn't work even with (true) or ()
IntPtr currentUser = WindowsIdentity.GetCurrent(false).Token;
Task.Run(() =>
{
    using (WindowsIdentity.Impersonate(currentUser))
    {
        ProcessStart();
    }
});

public static void ProcessStart()
{
    LocalReport localReport = new LocalReport();

    ...
    getting data for the report
    ...

    // this statement throws the exception
    byte[] pdfStream = localReport.Render(formatString,
                       deviceInfo,
                       out mimetype,
                       out encoding,
                       out fileNameExtension,
                       out streams,
                       out warnings);

    ...
    saving bytestream to file
    ...
}
我检查了,但我看不出这对我有什么帮助,因为我目前正在本地主机中调试

我检查了,但它建议删除任务并在同一线程中进行报告,这是我无法做到的


提前感谢您的时间。

在我去工作解决方案的路上,我首先开始修补
alwaysFlowImpersonationPolicy
配置标志,该标志似乎用于处理ASP.NET请求生命周期中线程之间传递模拟令牌的问题,虽然有一些,但它是一条死胡同

这里的问题是身份,以及
LocalReport.Render
使用沙盒应用程序域编译和执行表达式的事实

如果我们可以阻止报表引擎创建沙盒应用程序域,那么它的代码将在与调用代码相同的域和执行上下文中执行,从而避免引发内部异常的额外令牌传播。检查
LocalReport
类的找到了
ExecuteReportInCurrentAppDomain
方法,该方法承诺:

public static void ProcessStart()
{
    var localReport = new LocalReport();

    /* ...
     * getting data for the report
     * ... */

    /* prepare to do all rendering in the same appdomain */
    localReport.ExecuteReportInCurrentAppDomain(Assembly.GetExecutingAssembly().Evidence);
    /* now this fails no more */
    byte[] pdfStream = localReport.Render(
        formatString,
        deviceInfo,
        out mimetype,
        out encoding,
        out fileNameExtension,
        out streams,
        out warnings
    );

    /* ...
     * saving bytestream to file 
     * ... */
}
我测试了它,它确实有效!但也有一个缺点:该方法在.NET4.0及更高版本中已被弃用。有必要添加两个传统配置开关以使其正常工作:

<configuration>
    <system.web>
        <trust legacyCasModel="true" />
    </system.web>
    <runtime>
         <legacyCasPolicy enabled="true" />    
         <NetFx40_LegacySecurityPolicy enabled="true"/>
    </runtime>
</configuration>

如果未添加这些属性,则调用executeReportUrrentAppDomain会引发异常。我现在正在生产中使用此代码;我知道,在未来的.NET版本中,这可能会中断—也许在此之前,报表引擎也会得到改进。当然,不建议添加这些旧的CAS支持内容,因为它可能会影响应用程序的其他部分,例如,它将阻止运行时使用GAC提供的NGEN映像

尝试在任务上下文中植入请求标识与在Aspnet.config文件中一样毫无意义

总的来说,这种方法还存在许多其他问题,例如,没有任何机制可以防止主机进程终止工作线程和后台任务。 其他几篇文章都在讨论这些额外的复杂问题,无论如何,最可靠的解决方案仍然是让服务进程独立于IIS运行,并使用消息队列、命名管道或类似的方式为其分配后台任务。从.NET framework 4.5.2版开始,您可以使用
HostingEnvironment.QueueBackgroundWorkItem


既然有这么多反对这一点的建议,我们为什么还要坚持呢?在我看来,只有一个很好的理由:每当我们想要一个请求快速返回时,我们不在乎结果是否被丢弃。我不知道OP的用户故事,但我的允许:我们在页面导航上触发SCORM电子学习包的请求,我们需要避免任何延迟。如果用户在使用异步提交的报告之前离开,工作线程也可以提前终止任务。

您是否解决了此保留任务?@San很遗憾,我记不起确切的解决方案,已经有一段时间了,同时我换了公司。如果你想让我整理一下,我可以删除这个问题。我刚才也遇到了同样的问题,并且认为在
任务
代码中,标识不再是应用程序池标识,而是
NT-AUTHORITY\SYSTEM
。如果我找到了解决方案,我会发布一个答案。谢谢你花时间回答这个问题!很抱歉,我不记得我是怎么做到的,很长一段时间后我就离开了.NET。我很高兴找到了一条出路。:)