在XML Query中明确定义数据类型以便SSRS从WCF服务中识别

时间:2013-05-29 16:32:21

标签: c# wcf soap reporting-services

好吧,我对这个问题感到困惑,因为我没有得到语法,需要一些指导。 SSRS的XML Query结构用于查询xml结构或WCF服务。我有它工作正常,但数据类型不是它们在WCF服务上定义的所以我需要在它们过来后转换它们。有什么方法可以先做某事吗?

我假设我已经看过这篇MSDN文章: http://msdn.microsoft.com/en-us/library/ms365158%28v=sql.105%29.aspx

但是我迷失了,因为我的结构来自生成的'DataContract'我应用于我的'ServiceContract',无论我尝试什么,我都无法协商结构。我得到全部或全部。

用最简单的术语来说:“如何使用xml查询方法将文本值显式转换为SSRS中的整数”?核心问题是我想做矩阵报告,我可以这样做:

行是:'状态' 列是:'Adjudication_Type' 值为:(表达式)= sum(CINT(Fields!Volume.Value))

但是这是一个解决方法恕我直言,数据应该是合同中的DEFINED,或者当SSRS中的客户端定义时,有一些能力明确地使它成为正确的类型。前几天我遇到了WCF到SSRS的其他问题,并在这个帖子中做了一个解决方法:QUERY method of Soap request for SSRS and WCF testing

让我们来看看我的创作和实施

  1. 我在.NET 4.5中使用C#中的Entity Framework 5在库项目中创建了一个实体模型,以使其与数据的模型部分保持隔离。从t4为数据生成的基本模型是一个类似于这样的类:

    public partial class fMonthlyImpactedVolume_Result
        {
            public string state { get; set; }
            public string ADJUDICATION_TYPE { get; set; }
            public Nullable<int> Yr { get; set; }
            public Nullable<int> Mn { get; set; }
            public Nullable<int> VOLUME { get; set; }
            public Nullable<decimal> QSI_FEES { get; set; }
            public Nullable<int> ActivityDays { get; set; }
        }
    
  2. 然后,我在网站WCF项目中创建了一个接口和实现,使用basicHttpBinding作为其自己的项目来保持它与模型隔离。

  3. 我引用了网站项目中的实体项目,并返回了从t4模板生成的类(* .tt =就像我理解的POCO类生成器一样)

  4. 我的界面如此:

    [ServiceContract]
    public interface IReportingService
    {
        [OperationContract]
        List<fMonthlyImpactedVolume_Result> GetMonthlyData(string aStart, string aEnd);
    
        [OperationContract]
        List<MonthlyType> GetMonthlyData2(string aStart, string aEnd);
    
    }
    
    [DataContract]
    public class MonthlyType
    {
        [DataMember(Order = 0)] 
        public string state;
    
        [DataMember(Order = 1)]
        public string AdjudicationType;
    
        [DataMember(Order = 2)]
        public int Yr;
    
        [DataMember(Order = 3)]
        public int Mn;
    
        [DataMember(Order = 4)]
        public int Volume;
    
        [DataMember(Order = 5)]
        public decimal QSI_Fees;
    
        [DataMember(Order = 6)]
        public int ActivityDays;
    }
    
  5. 我对返回的实现如下:一个是将模型AS IS实现为一个返回,另一个是从“数据契约”中声明显式值,因此它不会生成可为空的类型。

    public List<fMonthlyImpactedVolume_Result> GetMonthlyData(string aStart, string aEnd)
        {
            using (SSRSReportsEntities re = new SSRSReportsEntities())
            {
                DateTime dstart = DateTime.Parse(aStart);
                DateTime dend = DateTime.Parse(aEnd);
    
                return re.fMonthlyImpactedVolume(dstart, dend, null).ToList();
            }
        }
    
        public List<MonthlyType> GetMonthlyData2(string aStart, string aEnd)
        {
            using (SSRSReportsEntities re = new SSRSReportsEntities())
            {
                DateTime dstart = DateTime.Parse(aStart);
                DateTime dend = DateTime.Parse(aEnd);
    
                return re.fMonthlyImpactedVolume(dstart, dend, null)
                        .Select(m => new MonthlyType
                            {
                                state = m.state,
                                AdjudicationType = m.ADJUDICATION_TYPE,
                                Yr = (int) (m.Yr ?? 0),
                                Mn = (int) (m.Mn ?? 0),
                                Volume = (int) (m.VOLUME ?? 0),
                                QSI_Fees = (decimal) (m.QSI_FEES ?? 0),
                                ActivityDays = (int) (m.ActivityDays ?? 0)
                            })
                         .ToList();
            }
        }
    
  6. 我将此发布到Windows 7企业版IIS 7.5上的本地主机下,该应用程序位于名为“报告”的默认网站上,端点为:

    http://(localhost)/Reporting/ReportingService.svc

  7. 我为客户端创建了另一个C#解决方案项目。我添加了两个服务引用。一个用于发现服务项目以便即时测试它。另一个服务一经发布。我检查端点绑定,它们工作正常。

  8. 我测试了客户端上的端点,它们都按预期工作于项目中的所有三种方法并发布引用。大。

  9. 我转到BIDS并在步骤6中设置了一个带端点的数据源,用于连接XML类型并将其命名为WCF Datasource

  10. 我正在测试1或2的方法,但它们都没有转移我定义的类型。这就是问题所在。

    < Query>
    < Method Name="GetMonthlyData2" Namespace="http://tempuri.org/">
    < Parameters>
    < Parameter Name="aStart"></Parameter>
    < Parameter Name="aEnd"></Parameter>
    </Parameters>
    </Method>
    < SoapAction>
    http://tempuri.org/IReportingService/GetMonthlyData2
    </SoapAction>
    < ElementPath>
    // From my reading SOMETHING should magically identify types here but I can't get 
    // ANYTHING to work like ./{Volume}, {Volume}, Document{}/{Volume}, Root{}/{Volume}
    </ElementPath>
    </Query>
    

1 个答案:

答案 0 :(得分:0)

第一步是确保您使用简单查询从此服务请求中获取数据,而不尝试定义如下所示的数据类型:

<Query>
<Method Name="GetMonthlyData2" Namespace="http://tempuri.org/">
<Parameters>
<Parameter Name="aStart">
       <DefaultValue>1/1/2016</DefaultValue>
</Parameter>
<Parameter Name="aEnd">
       <DefaultValue>2/1/2016</DefaultValue>
</Parameter>
</Parameters>
</Method>
<SoapAction>
http://tempuri.org/IReportingService/GetMonthlyData2
</SoapAction>
 <ElementPath IgnoreNamespaces="true">*</ElementPath>
</Query>

如果要获取数据,您可以在fiddler中找出响应的样子,然后尝试查询正确的结构并单独定义每个字段的类型,如下所示:

<Query>
<Method Name="GetMonthlyData2" Namespace="http://tempuri.org/">
<Parameters>
<Parameter Name="aStart">
       <DefaultValue>1/1/2016</DefaultValue>
</Parameter>
<Parameter Name="aEnd">
       <DefaultValue>2/1/2016</DefaultValue>
</Parameter>
</Parameters>
</Method>
<SoapAction>
http://tempuri.org/IReportingService/GetMonthlyData2
</SoapAction>
 <ElementPath IgnoreNamespaces="true">
GetMonthlyData2Response/GetMonthlyData2Result/dataItems{state(string)}
</ElementPath>
</Query>

找出这条路径的一种方法是通过查看fiddler中对服务的良好请求的原始响应。如果安装了fiddler,则可以使用WCFTestClient,将配置更改为在http端点上的WCFTestClient中使用端口8888。在WCFTestClient中提出请求。您将在fiddler中看到请求。转到fiddler中的Composer选项卡,将成功的请求拖放到编辑器中,然后单击Inspectors选项卡,然后单击检查器中的TextView选项卡。响应包络将让您了解元素路径应该是什么样的。