ASP.NET MVC Telerik报告:会话为空

时间:2015-12-30 16:59:42

标签: c# asp.net-mvc session telerik

我有一个包含HTML5 Telerik报告查看器的网页,该网页应该在网页中生成并显示报告。

Telerik报告查看器如何获取数据?

您创建了一个ReportControllerBase类的实现,它是从ApiController派生的Telerik框架的一个类。 您创建的类(简称为ApiController)由报表查看器用于检索报表,或者更确切地说是报表源。

报表查看器检索ReportSource,ReportSource检索报表的数据。

因此,在ReportController中,您要构建一个ReportSource,您可以对其进行配置,以便它知道在何处检索数据,然后将其返回。

在我的情况下,ReportSource通过一个名为OffersCRUD的类的方法来检索数据。 在调用WCF服务从数据库获取数据之前,此方法必须从会话中提取用户名,但问题是HttpContext.Current.Session为null。

我知道在Web api中没有启用deafault会话,但是我编写了一些代码来强制它使用会话,这看起来效果很好。

报告生成过程中有两个重要请求。

请求1:调用ReportController,将ReportSource用于使用OffersCRUD作为数据源然后返回。 此会话有效

请求2:现在报表查看器已检索到ReportSource,它会执行其他请求以获取数据,因此我们现在位于OffersCRUD类中。 此处会话无效,无效。

所以,从现在起我只会谈到第二个请求。 从调试器的角度来看,一切都从以下方法开始(在此之前有外部代码,调用该方法的代码被封装)

[DataObjectMethod(DataObjectMethodType.Select)]
public static PersonOfferDTO GetPersonOfferByNumber(string offerNumber)
{
    PersonOfferDTO result = null;
    List<IError> errors = new List<IError>();
    ServiceCaller.GetDataWithServiceUsingParameter(GetPersonOffer, errors, ref result, offerNumber);

    return result;
}

然后,在一些代码行之后,我们在UserSession类中,这是会话的一个wapper。

    public static class UserSession
    {
            private static UserDTO _currentUser;

            public static UserDTO GetCurrentUser()
            {
                HttpContext context = HttpContext.Current;

                if(context.Session["UserLogin"] == null)
                {
                    return null;
                }

                UserDTO currentUser = context.Session["UserLogin"] as UserDTO;

                return currentUser;
            }

            public static void SaveUserStatus(UserDTO user)
            {
                Validate.EnsureArgumentIsNotNull(user);

                HttpContext context = HttpContext.Current;
                context.Session["UserLogin"] = user;
            }

   }

在UserDTO GetCurrentUser(void)方法中,您可以在下图中看到HttpContext.Current的状态。

enter image description here

如您所见,Session为null,因此在尝试访问Session [&#34; UserLogin&#34;]时会失败。

如果您想了解更多详情,请在下面写下评论。

3 个答案:

答案 0 :(得分:1)

创建Telerik报告=&gt;在后台开始流程Thread =&gt; UI =&gt;从后台线程加载已处理的报告

后台线程无权访问当前上下文和当前会话。

您还将业务逻辑与ASP.NET会话对象紧密耦合。

您可以尝试使用常规的MVC Controller / Action而不是WebAPI,但如果在后台线程中调用它并且没有通过浏览器cookie,那么它就不会知道当前会话。

您可以尝试将用户名/密码设置为报告参数,然后将这些参数传递到NeedsDataSource事件中的Web服务中。

或者,如果它是已知报告,您可以将数据加载并附加到报告上的公共属性,并将其绑定到NeedsDataSource事件中。

答案 1 :(得分:0)

Web Api中未启用会话,因为它不遵循基于REST的设计。由于Telerik试图使用此设计,因此不建议使用Telerik Report Viewer会话。

您应该使用ObjectDataSource组件来将数据传递到报表。在此对象中,您可以使用自定义逻辑(但没有会话)包装方法来检索数据。

答案 2 :(得分:0)

我今天遇到了类似的问题。在Telerik知识库中找到了解决方案。在这里。

从这里https://docs.telerik.com/reporting/knowledge-base/how-to-pass-information-from-httpcontext-to-reporting-engine

来自Telerik产品版本12.1 18.620 要访问当前用户上下文,可以使用Telerik.Reporting.Processing.UserIdentity.Current静态属性。还可以在表达式上下文中将新的UserIdentity对象用作全局对象:= UserIdentity。

通过Telerik Reporting 12.1.18.620中引入的更改,可以使用UserIdentity.Context属性存储用户对象(例如,来自HttpContext)。通过覆盖GetUserIdentity()方法,可以在ReportsController中用所需的值填充UserIdentity.Context。这是示例代码:

// include in the ReportsController class

protected override UserIdentity GetUserIdentity()
{
    var identity = base.GetUserIdentity();
    identity.Context = new System.Collections.Concurrent.ConcurrentDictionary<string, object>();
    identity.Context["UrlReferrer"] = System.Web.HttpContext.Current.Request.UrlReferrer;

    // Any other available information can be stored in the identity.Context in the same way

    return identity;
}

然后应使用UserIdentity.Current.Context [“ UrlRefferer”](而不是HttpContext.Current.Request.UrlReferrer)来访问相应的属性/信息。例如,您可以按以下方式访问UrlRefferer:

// can be included in the Resolve() method of the Custom Report Resolver
Uri urlReferrer = (Uri)UserIdentity.Current.Context["UrlRefferer"];