2023年6月

使用类编写

使用类打印Report主要需要三个类:

  • Controller
  • Contrect
  • DataProvider

如果需要定制参数页也可以使用UiBuilder:

  • Class_UiBuilder

Controller

    class ReportController extends SrsReportRunController//报表打印入口类.
{
    public static void main(Args    _args) 
    {
        ReportController controller = new ReportController(); 
        controller.parmArgs(_args);
        controller.parmReportName(ssrsReportStr(ReportReport,Report));//(报表格式模版,Design).
        controller.parmDialogCaption('@Label');//打印前配置dialog 标题.
        controller.parmShowDialog(true);//是否显示配置页.
        controller.startOperation();
    }

    protected void prePromptModifyContract()//配置页初始化操作.
    {
        
        ReportContract  contract;
        Args            _args;
        Table           tb;
        List            list;
        FormDataSource  fds;
        MultiSelectionHelper  multiSelectionHelper; 
        ;       
        _args= this.parmArgs();
        contract =this.parmReportContract().parmRdpContract() as ReportContract;//获取本次打印Contract类.
    
        //<如何从窗体Grid多选>
        list = new List(Types::String);
        fds = args.record().dataSource();
        multiSelectionHelper = MultiSelectionHelper::construct();
        multiSelectionHelper.parmDatasource(fds);
        tb = multiSelectionHelper.getFirst();
        while (tb)
        {
            list.addEnd(tb.Id);
            tb = multiSelectionHelper.getNext();
        }
        contract.parmList(list);
        //</如何从窗体Grid多选>


        contract.parmDate(today());//设定配置页初始值.
    }
}

Contract

    [
        DataContractAttribute,
        SysOperationContractProcessingAttribute(classlist(UiBuilder)),
        SysOperationLabelAttribute(literalStr("@label:aaa"))

    ]
    class Contract
    {
        date endDate;
        AssetBookId bookId;
        List list;
                
    
        [   
            DataMember,
            DataMemberAttribute('EndDate')
            ,SysOperationDisplayOrderAttribute('16')
            ,SysOperationControlVisibility(false)    
        ]
        public date parmEndDate(date theEndDate = endDate){
            endDate = theEndDate;
            return endDate;
        }

        [   DataMember,
            DataMemberAttribute('BookId')]
        public AssetBookId parmBookId(AssetBookId theBookId = bookId)
        {
            bookId = theBookId;
            return bookId;
        }

        [   DataMember,
            DataMemberAttribute('List'),
            AifCollectionType("List",Types::String),
            AifCollectionType("return",Types::String)    
        ]
        public List parmList(List theList = list)
        {
            list= theList;
            return list;
        }

    }

DataProvider

    [
    SRSReportParameterAttribute(classStr(XXXContract))
    ]
    class XXXDP Extends SRSReportDataProviderPreProcessTempDb
    {
        Table        tmp;

        [
            SRSReportDataSetAttribute(tablestr(Table))
        ]
            public Table getTmp()
        {
            select tmp;
            return tmp;
        }

        public void processReport()
        {
            Contract contract = this.parmDataContract() as Contract ;
        }

    }

Class_UiBuilder

    [
        SrsReportNameAttribute('Repot_Report.Report'),
        SysOperationContractProcessingAttribute(classstr(Class_UiBuilder),
        SysOperationDataContractProcessingMode::CreateUIBuilderForRootContractOnly)
    ]
    class Class_UiBuilder extends SrsReportDataContractUIBuilder
    {
        Class_Contrat  contract;

        DialogField fieldEndDate;
        DialogField fieldBookId;
        DialogField fieldAssetList;

        public void build()
        {
            contract = this.dataContractObject() as Class_Contrat;
            fieldAssetList = this.addDialogField(
                methodstr(Class_Contrat, parmAssetList),
                contract
                );
            fieldBookId = this.addDialogField(
                methodstr(Class_Contrat, parmBookId),
                contract
                );
            fieldEndDate= this.addDialogField(
                methodstr(Class_Contrat, parmEndDate),
                contract
                );
        }

        public void postBuild()
        {
            super();
            contract = this.dataContractObject() as Class_Contrat;

            fieldAssetList =  this.bindInfo().getDialogField(contract, methodstr(Class_Contrat, parmAssetList));
            fieldAssetList.lookupButton(FormLookupButton::Always);
            fieldAssetList.label("@IWS:IWS01401");

            fieldEndDate =  this.bindInfo().getDialogField(contract, methodstr(Class_Contrat, parmEndDate));
            fieldBookId =  this.bindInfo().getDialogField(contract, methodstr(Class_Contrat, parmBookId));
        }

        public void getFromDialog()
        {
            super();

        }

        public void postRun()
        {
            Query                query            = new Query();
            QueryBuildDataSource    qbdsLegalEntity     = query.addDataSource(tablenum(AssetTable));

            qbdsLegalEntity.fields().addField(fieldNum(AssetTable, AssetId));
            qbdsLegalEntity.fields().addField(fieldNum(AssetTable, Name));

            container selectedFields = [tableNum(AssetTable), fieldNum(AssetTable, AssetId)];

            SysLookupMultiSelectCtrl::constructWithQuery(this.dialog().dialogForm().formRun(), fieldAssetList.control(), query, true, selectedFields);

        }

    }

直接打印

 SRSPrintDestinationSettings printSettings = this.parmReportContract().parmPrintSettings();
    printSettings.printMediumType(SRSPrintMediumType::File);
    printSettings.fileFormat(SRSReportFileFormat::PDF);
    printSettings.overwriteFile(true);
    printSettings.fileName(strFmt("%1.pdf", this.parmDialogCaption()));

图片

字段用 EDT bitmap containner类型直接赋值stream;
design用Image。

对象之间的关系自松到紧可以按此排序:

  • 依赖
  • 关联
  • 聚合
  • 组合
    ## 理解
    ### 依赖
    *最弱的关系,仅仅在执行过程中有接触;
    *一般以方法参数或返回值的形式出现。
    ### 关联
    *较依赖较强,但没有伴随整个生命周期;
    *一般以属性的形式出现。
    ### 聚合
    *伴随整个生命周期,但子对象可以独立存在;
    *一般以构造方法参数的形式出现。
    ### 组合
    *伴随整个生命周期,且子生命周期含于父生命周期;
    *一般以在构造时自己生成。

Context中包含:

ActionDescriptor

Filters

HttpContext

ModelState

Result

RouteData

类型

.Net中Filter都是以特性的形式存在,有如下五类:

  • AuthorizationFilters
  • ReousrceFilters
  • ActionFilters
  • ExceptionFilters
  • ResultFilters

AuthorizationFilters

常做权限验证;

ReousrceFilters

常做缓存;

ActionFilters

常做模型验证、日志记录;

ExceptionFilters

异常捕获;

作用范围

只能捕获ActionFilter及ActionExecution时的报错.

例子

 OnException(ExceptionContext context)
 {
  //记录日志
 }

ResultFilters

处理返回结果。

作用范围

仅Result不为空时才能够执行,若短路器执行或管道中抛出异常,则会跳过ResultFilter.

注册

注册方式

  • 方法注册

将特性注解在方法上;

  • 类注册

将特性注解在类上;

  • 全局注册

在注册Controller时使用委托注册,如:

Builder.Service.AddController( o => o.Filter.Add<CumFilter>());

## 优先级
不同类型Filter按管道模型顺序执行,相同类型的 全局>类>方法;
也可以再注册时指定 add( int order),小的优先;

短路器

当Context.Result被赋值时,将会跳过后续的管线步骤,直接返回结果,这一机制叫做短路器.

利用短路器实现缓存:

在ResourceFilter中:

public class ResourceFilter : Attribute, IResourceFilter
{
    private Static Dictionary< string, object > _dirCache = new Dictionary< string, object >();
    public void OnResourceExecuting(esourceExecutingContext context)
    {
        var path = context.HttpContext.Request.Path;
        _dirCache[path] = context.Result as ObjectReslut;

    }
    public void OnResourceExxcuted(ResourceExecutedContext context)
    {
        var path = context.HttpContext.Request.Path;
        if( _dirCache.ContainsKey(path) ) 
        {
            context.Result = _dirCache[path]  as ObjectReslut;
        }
    }
}

[TypeFilter(typeOf(xxxActionFilterAttribute))]
[ServiceFilter(typeOf(xxxActionFilterAttribute))] // 使用此条需在build中注册改过滤器及其需要注入的参数;