【问题标题】:Using Custom Culture with ReportViewer returns a CultureNotFoundException将自定义文化与 ReportViewer 一起使用会返回 CultureNotFoundException
【发布时间】:2014-12-10 15:28:13
【问题描述】:

我的网站使用这样创建的自定义文化:

var cib = new CultureAndRegionInfoBuilder("en-gb-xxxx", CultureAndRegionModifiers.None);
cib.LoadDataFromCultureInfo(new CultureInfo("en-gb"));
cib.LoadDataFromRegionInfo(new RegionInfo("en"));
cib.Register();

而且是这样使用的:

Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-gb-xxxx");
Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-gb-xxxx");

在我想使用 ReportViewer 控件呈现报告之前,一切正常。报告文本呈现正常,但图像失败,我收到以下错误:

System.Globalization.CultureNotFoundException:不支持文化。参数名称:culture 4096 (0x1000) 是无效的文化标识符

经过大量谷歌搜索后,我发现很多其他人都在问同样的问题,不幸的是总是没有答案。 This article 非常清楚地描述了问题,但没有提供任何解决方案。

有没有人可以提供如果不是修复,解决方法?

【问题讨论】:

    标签: c# asp.net reporting-services reportviewer cultureinfo


    【解决方案1】:

    由于没有答案,我不得不破解:

    首先,我创建了一个CustomReportViewer,继承自原生Microsoft.Reporting.WebForms.ReportViewer,覆盖OnPreRender 方法。它检查登录用户的文化(保存在 Session 中)并回滚到父文化(如果有)。

    protected override void OnPreRender(EventArgs e)
    {
        var culture = new CultureInfo(HttpContext.Current.Session["UserCulture"]);
        if (culture.CompareInfo.LCID != culture.LCID){
            var baseCulture = new CultureInfo(culture.CompareInfo.LCID);
            System.Threading.Thread.CurrentThread.CurrentCulture = baseCulture;
            System.Threading.Thread.CurrentThread.CurrentUICulture = baseCulture;
        }
        base.OnPreRender(e);
    }
    

    然后我更改了aspx页面中的对象:

    <web:CustomReportViewer ID="ReportViewer1" runat="server" AsyncRendering="false" SizeToReportContent="true" ProcessingMode="Remote">
    

    等等

    我不会接受这个答案,希望有人能想出点什么……更清洁

    【讨论】:

    • 我们遇到了完全相同的问题并找到了类似的解决方案。我们做了以下不同的事情:(1)我们只“修复”了 CurrentCulture。让 CurrentUICulture 指向用户定义的文化似乎工作正常。注意:我们只使用 LocalReport.Render 创建 PDF,而不是完整的 ReportViewer 控件,因此可能会有所不同。 (2) 我们通过从 CurrentCulture.ToString() 中删除“-xxxx”后缀来创建“基础”文化。您的 CompareInfo.LCID 解决方案看起来很有趣,但我不明白为什么它可以正常工作,这就是我没有使用它的原因。
    • (3) 在调用 LocalReport.Render 后,我们将区域性恢复为原始值。
    【解决方案2】:

    我找到了上述问题的解决方案:

    问题:

    不支持在报告查看器中导出文化。参数名称:culture 4096 (0x1000) 是无效的文化标识符。

    解决方案::

    1.) 在顶部添加以下指令

    <% @Import Namespace="System.Globalization" %> 
    <% @Import Namespace="System.Threading" %>
    

    或者

    using System.Threading;
    using System.Globalization;
    

    2.) 添加事件如下:

    protected void FPReportViewer_PreRender(object sender, EventArgs e)
    {
        CultureInfo ci = new CultureInfo("en-US");
        Thread.CurrentThread.CurrentCulture = ci;
        Thread.CurrentThread.CurrentUICulture = ci;
    }
    

    3.) 更新 Reportviewer html 标签如下:

    <rsweb:ReportViewer runat="server" ID="FPReportViewer" OnPreRender="FPReportViewer_PreRender" AsyncRendering="false" width="100%"  SizeToReportContent="True"> </rsweb:ReportViewer>
    

    希望这段代码对您有所帮助。

    非常感谢!

    【讨论】:

    • 不太确定这个答案与我的答案有何不同,但还是谢谢!
    【解决方案3】:

    在发送到 SSRS 之前试试这个

        Thread.CurrentThread.CurrentCulture =
            Thread.CurrentThread.CurrentUICulture =
                CultureInfo.DefaultThreadCurrentCulture =
                    CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.GetCultureInfo("en-US");
    

    例如:

     [SessionExpire]
            public ActionResult ReportProduct(string ExpenseCenter)
            {                   
                Thread.CurrentThread.CurrentCulture =
                    Thread.CurrentThread.CurrentUICulture =
                        CultureInfo.DefaultThreadCurrentCulture =
                            CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.GetCultureInfo("en-US");
    
                ReportViewer reportViewer = new ReportViewer();
                reportViewer.ProcessingMode = ProcessingMode.Remote;
                reportViewer.SizeToReportContent = true;
                reportViewer.AsyncRendering = false;
    
                reportViewer.ZoomMode = ZoomMode.FullPage;
                reportViewer.Width = Unit.Percentage(100);
                reportViewer.Height = Unit.Percentage(100);
    
                var serverReport = reportViewer.ServerReport;
    
                serverReport.ReportPath = "/Reports/ReportPrice";
                serverReport.ReportServerUrl = new Uri("http://ssrs-server:94/ReportServer_MSSQLSERVER2016/");
                serverReport.SetParameters(GetParametersServer());
                serverReport.Refresh();
    
                ViewBag.ReportViewer = reportViewer;
    
                return View();
            }
    

    【讨论】:

      猜你喜欢
      • 2018-01-19
      • 2011-09-27
      • 1970-01-01
      • 1970-01-01
      • 2016-06-28
      • 2017-09-30
      • 2017-07-04
      • 2018-04-01
      相关资源
      最近更新 更多