订阅概述
目前我们仅开发了”标准订阅”和”文件共享传递”,即由各个用户创建和管理并将报表生成到用户指定得UNC路径下.
订阅创建/更新API
创建订阅API
[C#]
public string CreateSubscription(
string Report,
[Namespace].ExtensionSettings ExtensionSettings,
string Description,
string EventType,
string MatchData,
[Namespace].ParameterValue[] Parameters
);
Member of [Namespace].ReportingService
参数:
Report
订阅的报表全名(包括路径,报表名).
ExtensionSettings
报表扩展设置定义,我们将创建”文件共享传递”的扩展设置.
Description
订阅的描述.
EventType
订阅触发事件,我们仅使用TimedSubscription.
MatchData
描述触发事件的XML串,我们称之为The XML description of Schedule Definition.
Parameters
报表参数数组. 有些报表需要用户输入参数方可执行, 输入该值,使系统自动填充参数并运行报表.
返回值:
订阅ID,Reporing Services数据库描述订阅的唯一标识.
更新订阅API
[C#]
public void SetSubscriptionProperties(
string SubscriptionID,
[Namespace].ExtensionSettings ExtensionSettings,
string Description,
string EventType,
string MatchData,
[Namespace].ParameterValue[] Parameters
);
Member of [Namespace].ReportingService
参数:
SubscriptionID
订阅ID.
ExtensionSettings
报表扩展设置定义,我们将创建”文件共享传递”的扩展设置.
Description
订阅的描述.
EventType
订阅触发事件,我们仅使用TimedSubscription.
MatchData
描述触发事件的XML串.
Parameters
报表参数数组. 有些报表需要用户输入参数方可执行, 输入该值,使系统自动填充参数并运行报表.
文件共享传递
GET ExtendSetting FROM UI
文件共享传递需要七个参数,它们组成了一个设置数组, 如下:
Microsoft.ReportingServices.Interfaces.Setting[] intSettings
= new Microsoft.ReportingServices.Interfaces.Setting[7];
参数数组需要参数实例填充:
intSettings[0]=new Microsoft.ReportingServices.Interfaces.Setting();
intSettings[0].Name=PARAMETER_NAME;
intSettings[0].Value=PARAMETER_VALUE;
分别为设置数组赋实例: "PATH", "FILENAME", "FILEEXTN", "USERNAME", "PASSWORD", "RENDER_FORMAT", "WRITEMODE", 并分别设置对应界面空间上的Value.
SET UI FROM ExtendSetting
当更新订阅时,界面必须根据订阅ID取得订阅设置, 并重新设置界面控件值,此时参数数组变成6个,它不提供PASSWORD设置:
foreach(ParameterValue paramValue in extSetting.ParameterValues)
{
switch(paramValue.Name)
{
case "PATH":
SET_PATH_TEXTBOX_VALUE;
break;
…….
}
}
订阅事件描述
由于我们仅关注” TimedSubscription”事件,所以订阅事件描述也即”任务计划描述”.
GET ScheduleDefinition FROM UI
由上面的API我们知道,任务计划最终时返回其XML描述串.
计划定义包括:
1) 开始时间
2) 结束时间(如果指定)
3) 重复规则(不指定则仅在”开始时间”执行)
private string GetMatchData()
{
ScheduleDefinition schedule = new ScheduleDefinition();
schedule.StartDateTime = _startTime;
if(_hasEndTime)
{
schedule.EndDateSpecified = true;
schedule.EndDate=_endTime;
}
schedule.Item = GetPattern(); //将根据界面选择返回重复规则定义
XmlDocument xmlDoc = GetScheduleAsXml(schedule);//返回任务计划的XML
return xmlDoc.OuterXml;
}
共有五中重复规则定义:
1) MinuteRecurrence: 需要指定MinutesInterval, 可描述每隔X小时X分钟执行的任务计划.
2) DailyRecurrence: 需要指定DaysInterval, 可描述每隔X天,在”开始时间”执行的任务计划.
3) WeeklyRecurrence: 需要指定DaysOfWeek, WeeksInterval, 可描述每隔X周,每星期X1,星期X2,星期X3…在”开始时间”执行的任务计划.
4) MonthlyRecurrence: 需要指定MonthsOfYear, Days, 可描述每X1,X2,X3…月的Y1,Y2,Y3日, 在”开始时间”执行的任务计划.
5) MonthlyDOWRecurrence: 需要指定MonthsOfYear, DaysOfWeek, WhichWeek(可选), 可描述 X1,X2,X3…月的第Y星期的星期Z1,Z2,Z3…在”开始时间”执行的任务计划.
值得注意的是,目前Reporting Services2000 SP2 仍然存在序列化任务计划的XML存在与Reporing Services API的WhichWeek定义不一致的情况, 需要进行如下处理:
private XmlDocument GetScheduleAsXml(ScheduleDefinition schedule)
{
MemoryStream buffer = new MemoryStream();
XmlSerializer xmlSerializer = new XmlSerializer(typeof(ScheduleDefinition));
xmlSerializer.Serialize(buffer, schedule);
buffer.Seek(0, SeekOrigin.Begin);
XmlDocument doc = new XmlDocument();
doc.Load(buffer);
// patch up WhichWeek
XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("rp","http://schemas.microsoft.com/sqlserver/2003/12/reporting/reportingservices");
XmlNode node =
doc.SelectSingleNode("/ScheduleDefinition/rp:MonthlyDOWRecurrence/rp:WhichWeek", nsmgr);
if(node != null)
{
switch (node.InnerXml)
{
case "FirstWeek":
node.InnerXml = "FIRST_WEEK"; break;
case "SecondWeek":
node.InnerXml = "SECOND_WEEK"; break;
case "ThirdWeek":
node.InnerXml = "THIRD_WEEK"; break;
case "FourthWeek":
node.InnerXml = "FOURTH_WEEK"; break;
case "LastWeek":
node.InnerXml = "LAST_WEEK"; break;
}
}
return doc;
}
SET UI FROM ScheduleDefinition
为了为界面控件加载数据,首先需要将API返回的MachData反序列化为ScheduleDefinition:
private ScheduleDefinition GetScheduleFromXml (string sMatchData)
{
MemoryStream vStream =
new MemoryStream(System.Text.Encoding.Default.GetBytes(sMatchData));
XmlAttributes attrs = new XmlAttributes();
attrs.XmlElements.Add(
new XmlElementAttribute("MinuteRecurrence",typeof(MinuteRecurrence)));
attrs.XmlElements.Add(
new XmlElementAttribute("DailyRecurrence",typeof(DailyRecurrence)));
attrs.XmlElements.Add(
new XmlElementAttribute("WeeklyRecurrence",typeof(WeeklyRecurrence)));
attrs.XmlElements.Add(
new XmlElementAttribute("MonthlyRecurrence",typeof(MonthlyRecurrence)));
attrs.XmlElements.Add(
new XmlElementAttribute("MonthlyDOWRecurrence",typeof(MonthlyDOWRecurrence)));
XmlAttributeOverrides attrOver=new XmlAttributeOverrides();
attrOver.Add(typeof(ScheduleDefinition),"ScheduleDefinition",attrs);
XmlSerializer newSr=new XmlSerializer(typeof(ScheduleDefinition),attrOver);
return (ScheduleDefinition)newSr.Deserialize(vStream);
}
根据GetScheduleFromXml返回的字符串,需要再次Patch WhichWeek
if(matchData.IndexOf("WhichWeek")>-1)
{
if(matchData.IndexOf("FIRST_WEEK")>-1)
matchData=matchData.Replace("FIRST_WEEK","FirstWeek");
if(matchData.IndexOf("SECOND_WEEK")>-1)
matchData=matchData.Replace("SECOND_WEEK","SecondWeek");
if(matchData.IndexOf("THIRD_WEEK")>-1)
matchData=matchData.Replace("THIRD_WEEK","ThirdWeek");
if(matchData.IndexOf("FOURTH_WEEK")>-1)
matchData=matchData.Replace("FOURTH_WEEK","FourthWeek");
if(matchData.IndexOf("LAST_WEEK")>-1)
matchData=matchData.Replace("LAST_WEEK","LastWeek");
}
最后根据ScheduleDefinition的Item类型设置重复规则控件值
switch(_ScheduleDefinition.Item.GetType().Name)
{
case "MinuteRecurrence":
SET_MINUTE_CONTROL;
break;
case ….
}