Aspnetcore: Asp.Net Core Reporting (SSRS)

Created on 2 Jun 2016  ·  269Comments  ·  Source: dotnet/aspnetcore

I am working on ASP.NET Core app and cannot find a solution for displaying SSRS reports. With the absents of "Microsoft.Reporting.WebForm" no longer works. What is the best practice for displaying SSRS reports on the web in ASP.NET Core

External

Most helpful comment

Almost 2 years. Core 2.0 is released. SSRS team, wake up.

All 269 comments

With Core still being in RC (RTM by the end of the month), I don't think that an SSRS scenario is planned within the next 6 months but I'm not part of the team.

I would either generate those reports on the client side by using some javascript libraries or pre-generate those reports.

If you need something more "integrated", you can check out this community package:

https://github.com/ilich/MvcReportViewer

By the look of the issue https://github.com/ilich/MvcReportViewer/issues/121, they are interested in integrating it but with no success thus far.

I don't understand why the dotnet and ASP.net core initiatives are keeping silent on this issue on all previous announcements. It is like
[Reporting is not a major concern for developers and they can deal with it using html and print css classes]
currently we are migrating a small erp with alot of ssrs rdlc files and css approach is not doing any good in cross browsers reporting.
on the other hand, past week microsoft released ssrs 2016 with pure html5 viewer that eliminated the need for activex installation [which was the only downside for using ssrs on non-ie browser]
ssrs 2016 viewer fit perfectly in asp.net core eco system perfectly
but no official statement regarding asp.net core support was declared.

is it all blocked by System.Drawing?? because even itextsharp hadn't release a library until now.
if it is System.Drawing then at least windows implementation can be completed before [linux and OSX] in order to increase adoption for current windows developer instead of waiting for the full cross-platform implementation for System.Drawing

I hope this post will make the team reconsider some priorities to enable ssrs within asp.net core

with respect for MvcReportViewer mentioned in previous post (it is a wrapper around webforms viewer) and it helped alot of mvc developers in the past to overcome the lack of mvc report viewer in mvc1 to mvc5 [Thanks so much ilich], I hope to see a full solution because ssrs was not a first class priority and people kept quite about it in pre-core mvc.

Please developers,
forward this issue to your colleagues in order to comment about it.
this might give a priority for it and motivate the team to do something.

@ddddddddeee22211 It's a V1.

You don't ship with SSRS support initially. The support with SSRS would probably come from the SSRS team and not the .NET team. Since we're not even out of RC yet, I don't see this as a critical feature in V1.

If you need to do reports, may I recommend just running the webforms version? Yeah. It's old. But at least it works and it's supported.

If you need X-Plat reports, I'll recommend something like Chartist. It allows you to generate charts directly on the client. Add a CSS file for printing purposes and boom. You have reports that can be printed.

from your perspective it might not be critical
but some other developers are considering it very important for their projects because once they develope an app and go live with it, development tasks get holded and reporting tasks become daily routine tasks. also some projects handle reports creation to BI (business intelligence) team who knows how to use ssrs but dont have an idea about asp.net core.

the aim of my post was to understand ssrs position within asp.net core eco system. or if it will be ignored as in mvc1 to mvc5. ssrs team are within microsoft and asp.net core team may discuss the issue with them.
what drove me crazy was when i saw ssrs 2016 release note past week without mentioning anything about asp.net core. while on the other hand you see continous support for azure within asp.net core.believe me if we didn't rise a demand for ssrs, it will be ignored as in the previous mvc 5.

your advice about using webforms is an example about slowing down adoption of core initiative.at least if I had a statement about wether it will be supported or not , I'll be able to make strategic decisions about it.

thanks for chatist tip. I'll check it out and I hope you understood my point of view.

@ddddddddeee22211 Ahhh... then I can't answer.

Right now, the only way to make SSRS components work on ASP.NET is on WebForms.

If you want their strategic position or if they will support it, we'll need to wait for an MS Employee to answer.

Maybe we can /cc @coolcsh ? He might not answer here but a blog post clarifying the position would be nice.

In the SSRS team we are aware of the limitations of the ASP.NET WebForms and we are actively investigating and working in new options for the Report Viewer control
Thanks

@jtarquino

Thanks for the reply man!

We've been wanting an alternative since MVC. :stuck_out_tongue_winking_eye:

That just made my day. [~happy ending~]
Thanks @jtarquino , @MaximRouiller for all effort.

@jtarquino
That sounds great :-)

Can you say anything about when you expext to release first version of the "new option" for Report Viewer Control ?
(Are there any roadmap/plan for this?)

Br.
Boe

Unfortunately I don't have a timeline to share at the moment

have you tried using a Library by installing a Package on Package Manager Console and type following command into command window.

PM> Install-Package ReportViewerForMvc
although i have tried on web-forms and they look pretty good.

untitled

@bethwellagat
again fire error "the dependency ReportViewerForMvc doesn't support framework .NetCoreapp"
notes:
working on ASP.NET Core project

@jtarquino ping on this. Looks like there's more interest: https://github.com/aspnet/Mvc/issues/5332

@jtarquino BTW if you want to start some discussions with my team, please email me and we can chat.

Ohhh me like! The ball is rolling! 😀

Hey everyone, I just finished writing a custom port of the report viewer control using the ReportExecutionService.asmx that's built into SSRS and I was targeting ASP.NET MVC. I had someone suggest porting it to .NetCore & MVC so I have completed that. Give it a try and let me know what you guys think: https://github.com/alanjuden/MvcReportViewer

Alan

It looks like it has been about three months since ReportViewer in ASP Netcore MVC has been discussed here. I am working with the version Alan Juden has provided in a project I am moving from WinForms to netcore. Is there any signs Microsoft is stepping up to provide first class SSRS ReportViewer support or have they put SSRS in the same closet they put Visual FoxPro into a few years back?

Any progress MS? Best option for now is to use a third party tool like Telerik Reports for browser rendering and SSRS backend for report subscriptions. Maybe as ddddddddeee22211 wrote, SSRS 2016 already has capability via HTML5 rendering engine but no documentation exists?

Hey @Eilon.

Any news since September? Especially since you guys now launched 1.0 (congrats!), pressure must be down a bit.

Anything you can share?

/cc @jtarquino

Nothing that I can share yet, as soon I have news for .NET core you will be the first one to know.
As you mentioned we just released the latest nuget for the ASP.NET Webforms and Winforms control

I would like to add my prompt to the team as well... This is a major issue. I appreciate AlanJuden's solution, but we need an "official" solution... Given that core 1 has been out for months now it would be helpful to have some word on the status of this. If you could get us word on the timeline for a solution that would be something. This issue is large enough that it will prevent us from using mvc core. One note. We really need a solution that gets around the need for the users to log into the ssrs server. This is why my project has to use the current reportviewer (using reportviewer we have the mvc project provide a standard login to the ssrs server for all users)

Sql server 2017 is community preview2 now
And
.net standard 2.0 release is close with the latest announcement
And still no word on native asp.net core reporting service viewer
Please invite other developers to this issue to give feedback and make the team aware of the need for such an effort for a masterpiece framework that every developer is dreaming about.

@jtarquino : is there a forum or uservoice for SSRS ?
how can users contact the SSRS team ?

Thanks , I’d really like to get some help with getting my new app to work with SSRS.
Is there any way to get the code used by the web forms control for an aspx page to tear into ?
I’d like to see if I can make an angular 2 view that “works like” and “looks like” the web forms control.

Hi,

We are looking to migrate some of our websites etc to asp.net core but some include an SSRS Report Viewer Control. Is there any progress on a report viewer control for .net core?

Thanks
Tim

if you are targeting Full .NET 4.x and not .NET Core, please take this #2022 in consideration before moving to ASP.NET Core.
ASP.NET Core 2 will not support Full .NET 4.x

@ikourfaln. Rather a moot point a this stage seeing there is no reportviewer in asp.net core to break. With the upcoming changes in Q3 in asp.net core 2 as well as .net standard 2 with the compatibility shims that allow targeting the .net framework, I would think it's highly unlikely that Microsoft will write a reportviewer for the current asp.net core 1.1.

currently i have tried to get into the auth extensions for SSRS and found it to be a real mess to try and change, you can put in a new auth / login but then when you try to enable CORS so that a web app can call SSRS to run a report the browser can't get an OPTIONS preflight request to work and that ends that whole idea.

so now i am making a web forms web app that i am adding OpenId Connect support to so that i can have SSO working between my shiny new angular app and my reports

then i will see if i can some how bring them together with iframes hackery or some other means.

wish microsoft would update ssrs to play better with new web tech.

another line of thought: SSRS KPI and Mobile reports: is there any way to use them in a web app ??

@alanjuden Any chance to configure your package to enable rdlc reports rendering? Installing Reporting Server and manage it for each client is a real pain.

@IonRobu, I may be crazy...but I'm not that crazy! :P

The real reason that I won't do that is because I have only made the front end viewer of the report viewer. I'm relying entirely on SSRS to render the report and give me back the report data via the SSRS API. So it requires having the report server backend. Sorry but that would be way more work than I'm looking to do on this project. I created my MvcReportViewer as an easy solution to get around the pains of bringing in the ASP.NET WebForms version of the control in.

Report Server or RDLC which is called "client reports"
report server is more work to setup and manage yes that is true.
but it has a number of benefits:

reports are rendered on a back end server, that takes work load off the front end web servers.
the results of a report can be cashed and that can take work load off your productions sql server.
complex reports can be run on a schedule and do work at a time when few users are on the system and
requests can then be served up from that pre-compiled snapshot.
also using SSRS the sql server connection strings stay on the report server and do not need to be managed in the web server config file
also the SSRS server becomes a central point that report authors can publish to and all users can get the reports from the server.
SSRS can setup automatic emailing of reports to users, you can email a link to the report server for some users and a pdf, word or excel file to others.

also scaling up, if you need to serve more users you may need to add more web servers before you need more report servers, you do not then need to copy large numbers of rdlc files to all the web servers.

so yeah if you only have a few reports and do not need any of the benefits you can go with rdlc.
but for a larger system that will need to serve a lot of reports to a lot of users the SSRS server has some really good benefits.
also that SSRS api is very powerfull to work with, you can call the api to return a report pdf for example without the need to have any client side web forms or mvc viewer controls.
the api can also manage the reports, upload them to the server, set permissions and list the reports.
at work i am using the api to allow our client app to list the reports that the user can run, to check the parameters the report needs and then run the report for the user.

so take a good look at the benefits not just at the admin overhead.

@figuerres
Client reports excel in different context from the one you descriped
Many clients does not use report server and do not have qualified personnel to administer and maintain its issues
Also when you ship a product with customized reports (60+) for each client you face an overhead of deploying application + deploying reports
Many users are not techies who can understand reports generated by server and rendered as per response without previewing them first (invoice for example can be verified via viewer easily than downloading multiple corrected invoices into different tabs)

As you can see it is a easy for user to adapt to simple report viewer than complex scenarios
Also developed spent countless effort to develop clients reports and now they are rendered useless in their true usage

I hope Microsoft team understand our pain

Not quite sure I get all of what you said but yes client reports are usefully, I was just outlining reasons for the server , why it might be worth looking at. Your mileage may vary and all that.

today net standards 2 is released with more api surface for system.drawing
could this be a chance for a word from srss team about ssrs viewer for asp.net core?

My company heavily relies on RDLC reports export documents in PDF format. Not being able to do this in .net core is basically a blocker to us using .net core and running on other platforms like docker.

i hope from every coder to encourage his/her colleagues to comment on this issue here

For those that are still looking for a solution:
If Java is installed, you could alternatively embed Eclipse BIRT or JasperReports.
Of the two, JasperReports is most definitely the best SSRS alternative (a little more complicated, but also a lot more powerful / pixel-perfect ).
It has a stand-alone and embeddable reporting server, capable of accessing any JDBC datasource, and also BigData like Cassandra or Apache Spark (SparkSQL).

It provides reporting and analytics that can be embedded into a web or mobile application as well as operate as a central information hub for the enterprise by delivering mission critical information on a real-time or scheduled basis to the browser, mobile device, or email inbox in a variety of file formats.

You could do a self-contained deployment of the Java runtime by supplying BIRT/Jasper via Launch4j.

@jtarquino any good news for .Net Core ?

I can't believe this is still an issue some 15 months after it was raised. Very disappointed.

We really need this to work, even a simple point at SSRS, ReportName and Params, open in DIV or something. We have invested a lot of time in creating SSRS reports on SQL directly and I need a way to display them in a simple Core2.0 MVC application.

Any tips?

@cgountanis, This works for me:
https://github.com/aspnet/Home/issues/1528#issuecomment-259169426

@cgountanis
do you need a pdf of the report or full interactive reports like the web portal shows ??

i can give you some starters on how i do them from an angular app

This is what I am doing. Uses the client's credentials which may not work for most.
Resizing the page larger works, making it smaller not.


@model string

@{
    ViewData["Title"] = "View Report";
}

<style>
    body {
        overflow-x: hidden;
    }
</style>

@{
    var src = "http://192.168.0.1/ReportServer/Pages/ReportViewer.aspx?/";
    src += ViewData["argument"];
}

<iframe style="overflow:hidden; overflow-x:hidden; overflow-y:hidden; border:none; width:100%; height: 1250px;" src=@src></iframe>

one thing is to use the report server web services, from them you can get lists of the reports and folders and data sources etc... and use that data to build your own portal / report menus and manage which reports the users can see in your app.
we created a set of windows users on the report server and used them to limit which reports they get,
mapped the application users role to a report server user.

when we run a report we pass the report server user as the user who is running the report, kind of sucks as that means we lose the "real user" unless we log that in our code.
but that deals with the report server's dependence on windows user accounts. if they would updated it to use a jwt token and get roles from the token things would be better for us.

we use an iframe to put the web forms control into an angular app view, also not the best but it works.
the user can't really see the behind the scene hacks we do.

@ctrl-brk I am having this issue with Core 2.0, maybe I missed something. https://github.com/alanjuden/MvcReportViewer/issues/43

@steelwil Thanks but I need custom NetworkCredential.

@figuerres We display reports from a firewalled SSRS, the WebForm application did all the hard work with the SSRS.ReportViewer, not able to just Windows Users. Agreed JWT would be nice though. Examples would be cool, trying to match the ReportViewer functionality that we had with WebForms/NUGET.

Thanks all!

Eventually they will release an official NUGET for this right?

@cgountanis The "they" is the SQL Server team, not the ASP.NET Core team. Therein lies the problem. It's a different team.

@giddev the real question here is whether this other team you are referring to actually still exists at Microsoft and has active developers that still work in the team and if they have enough pride in their work to produce and publish a first class solution for imbedding SSRS reports into a ASP.Net Core 1 or 2 web application. Do they have a published roadmap? Is ASP.Net Core part of the plan or has SSRS been abandoned and replaced with the POWER BI stuff? I am beginning to see signs that SSRS is heading to the same rat hole that Microsoft Visual FoxPro fell into.

@wqwalter something like that.....
I get the impression that Microsoft has way to many teams that each follow thier own map and not many folks making sure that they have a common set of deliverable and communication between them.
it's like herding cats, they all take off in different directions ....

if that is wrong -- well it seems that way.

I find it hard to believe they would abandon SSRS as it is heavily used by developers now that Crystal Reports is unpopular.

@cgountanis
well as much as i like some things from Microsoft i have seen a 20 year history of them repeatedly halting products and doing things that defy my understanding. one example was Virtual PC, acquired by Microsoft, sold by Microsoft for a time, then they made it free, then they killed it.
that is just one of many cases like that....

i did hear talk about power BI and some gossip that it might be the new SSRS in time.
i am not sure if that is for sure or just gossip. it would follow the model of pushing Azure based services.

Love to see SSRS support web-based authentication - OpenID Connect preferrably - out of the box. A step further - it'd be awesome if SSRS was a nuget for ASP.NET Core. Report scheduling and user admin - maybe provide a sample project, but I'd be fine to develop that part given documentation on the SSRS API.

@Morgma
agreed!
OIDC would be a perfect fit for what i am doing.
the roles need to be done so that we can supply a mapping for report server roles to our application roles.

right now i have an app that is using OIDC with an Angular 4/5 front end that has to load a web forms report page into an iFrame and has to use windows user accounts to control permissions so if i query the report server database i can't actually see which users run the reports. it's a kluge that we can use but far from ideal.

This is a major issue for us as well and I really can't believe we still have not heard ANYTHING from Microsoft on this. Its seriously making us consider non-microsoft options at this point. If we at least had a timeline we could make an informed decision.

I agree, I have gone down the route of using the ReportServer/ReportExecution2005.asmx directly just to get export working directly. Works great then when hosted under IIS getting strange errors.

It's been frustrating.

System.ServiceModel.Security.MessageSecurityException: The HTTP request is unauthorized with client authentication scheme 'Basic'. The authentication header received from the server was ''

that error says the header for authorization is missing, the http request needs to include the header. is nust the one call a problem ?

Works fine until hosted under IIS. Even my development machine is talking to the same report server and it works but once published and hosted with IIs you get that error. Think what it's saying is the server is responding with some kind of error empty but I'm sending it everything.

Remember that IIS Express runs under your user credentials so the double hop is probably fine. What is likely happening is you do not have kerberos set up on your IIS server and even if you have delegation turned on your report wont work because the report is running as anonymous.

Short answer: you cannot use delegation without kerberos set up, which requires settings on your domain controller for the account the IIS App Pool runs as.

https://blogs.msdn.microsoft.com/chiranth/2014/04/17/setting-up-kerberos-authentication-for-a-website-in-iis/

I know this is not the right place but I wanted to follow up. Hosting Core on IIS, it does not care what you set the IIS settings to. Just for S&G, I made the appPool user Administrator and it worked. Go figure... This is with no IIS Authentication settings enabled other than Anonymous. Anyone explain this? Does it need to access a lib for WCF on Core that it needs special access for? What gives? I BE CONFUSED... and worried about security.

@cgountanis can you open a new issue with your question?

@jtarquino Do you have any updates for timeline on release of a .net core based report viewer? I'm desperate to get at least a timeline. Are we talking 6 months? 12 months? We are basically facing the decision to abandon all of our current SSRS reports and go with another solution since we have no alternative and no timeline on any availability.

@ExcaliburVT it is in our backlog however I don't have a timeline that I can provide at the moment.

@jtarquino open source is nice and all but at the same time Microsoft needs to be responsible to the customers, customers pay for products, customers need delivery of products. we are customers.

this is the one area where the migration of Microsoft is not so great. if we as customers can not get the right answers then how long will we keep coming back ?

this same kind of thing is happening in several products, not just this one. why should i advise my managers to license the next release of SQL Server and SSRS if we can't get the updates we need to run the business ?

@jtarquino I have to agree with @figuerres as I literally just got done fighting a 3 month battle to get approval to use SQL over Oracle and come to find out one of my key selling points Isn't natively supported. I was bashing Oracle for not having a .Net Core driver available and they at least had an announced release date. SSRS is your own product and you are fully two generations behind without even a proposed date for resolution.

Using the new VS2017 WCF connector service (Core 2) does allow you to export the reports with parameters to PDF, Word, Excel, CSV... pretty easy if you want any help before this viewer NUGET package is released. Yeah you have to use the ReportExecution2005.asmx that comes with SSRS but so will whatever they create. We just decided to dump the viewer aspect for now and do straight file downloads.

Edit: Only issue is coming to grips with the AppPool permissions I mentioned earlier.

by the way i get reports as a pdf from a web api and i do not use any wcf bits.
just soap/asmx calls and http calls.
in doing them i pass credentails w/o any problems.
my code is asp.net 4.6 / web api 2
if you want to see what i do i can put some code up on a github next week for you to check out.
i am calling report server 2016 but most of what i am doing will work with the older ssrs releases.

Anything new for Core 2 with SSRS (RDLC Designer)?

@figuerres if you have put up any code in github request to please share the link.

@apondu
will post next week, not in office till then. no one asked for code till now.

I'm working on a intranet application Angular5/.NetCore2 MVC5 (current RC stack from MS), we're using SSRS 2012, and need to create timebased report subscriptions for users that are not the logged in windows account.

@figuerres Perhaps you have some ideas?

You can use SSRS and the reporting execution service that's built in to spit out PDFs all day long.

@cgountanis Thank you for such a quick response, you helped me realize I wasn't descriptive/accurate enough when describing what I need to do. I've updated my original comment to say "create timebased report subscriptions"

Hmm think I did something like that by inserting subscription schedule rows directly into the report database (guessed how the subscription service worked based on the table and existing rows).

@ExcaliburVT I've used the SOAP API and a large SP to interact with the DB thus far, and would like to avoid modifying the DB directly. I'm happy to know there is a fallback option.

what do you mean by timebased ?

do you need to run a report at a given time ?
do you need to run a report when a user does something ?

@figuerres time based, meaning on a recurring schedule such as every wednesday at 8am.

Yeah I was not able to find a way to do that without inserting a record manually at least back to SQL 2012. If I remember right you don’t have to modify schema or anything just insert a row in the subscriptions table and I was able to send a report to a distribution group that way.

ok then the report server portal can run a report on a planned scedule, it can save it to a file or send an email when that time happens.
you do not need to have anyone logged in when it runs.

you just create the subscription from the portal.

you can also do that from the soap api but i am not sure of the exact set of api calls to make.

Allow me to give more context before talking about what I've seen from the soapAPI.

I'm writing a webapp that uses the SSRS soapAPI and credentials like "ssrsReportWebAdmin". In development right now the "ssrsReportWebAdmin" has all the security roles, but based on documentation it seems the Content Manager role is the one that is needed. A user will use the webapp to create subscriptions for other people and submit those requests through the soapAPI.

The CreateSubscriptionAsync call returns an error saying that the user does not have permissions.

so calling the api you are passing a cred object for user "ssrsReportWebAdmin" that has all roles but you get an error that it does not have permission ?? interesting....

from what I've read SSRS is setup so the only person who can create standard (recurring, time based) subscriptions is the user themselves. Datadriven subscriptions can be setup by the Content Manager role.

See ContentManagerTasks - Manage All Subscriptions
https://technet.microsoft.com/en-us/library/ms159693(v=sql.105).aspx

See first sentence under header begins "Reporting Services supports two kinds of..."
https://docs.microsoft.com/en-us/sql/reporting-services/subscriptions/subscriptions-and-delivery-reporting-services#bkmk_standard_and_datadriven

@figuerres @ExcaliburVT
I was able to create standard subscriptions to both email and fileshares using an AD account with the Content Manager SSRS role. From what I can see the permissions issue I was running into Friday was a side effect of a blank/malformed MatchData parameter.

Almost 2 years. Core 2.0 is released. SSRS team, wake up.

@codehippie1 dont be so rude. we’re all human beings here. grow up!

It was merely a joke in the developer cave. No offenses meant whatsoever. Jokes apart, ReportViewerForMVC has 72,799 downloads now spanning from early 2014 (https://www.nuget.org/packages/ReportViewerForMvc). SSRS team has ignored ASP.NET MVC for many years, and now ignoring ASP.NET Core for 2 years. Talking of being rude, 72,799 times is a lot.

I would settle for a nice export to PDF library officially supported, no need for the viewer these days with responsive requirements the way they are.

@cgountanis: Generate a HTML template (correct paper size - html-only, images as base64, inline-styles). Fill in the placeholders, and don't forget to set the HTML-encoding to utf8. Send text to StandardInput of wkhtmltopdf - fetch output from StandardOutput of wkhtmltopdf. And then, you have something much better than SSRS.

@cgountanis I've contemplated such an approach, but generating a pixel perfect report with page headers / footers and line breaks in logical places is not easy.

For all those sharing my pain of not having MS RDLC local report viewer on aspnet core; I have tried an alternate approach with the help of pdfJs and ViewerJs from mozilla - pdfJs demo with MS RDLC report viewer to spit out report as bytes. For me, this is the best of both worlds, as I could still use RDLC files, use them to generate reports in server side, and have the powerful firefox built in document viewer to show the output. PdfJs is still not a report viewer, but for my case with page navigation, print preview, search and a bunch of other useful functionalities, it is not any less either.

In case you are interested, Here is a gist to help you how to use it inside aspnet core application(with client side in angular 2 or above, rxJs and Typescript). For me, this simply is the best of both worlds.

How to add pdf.js and viewer.html to angular 2 application.(With Optional aspnet core/webapi/mvc backend report generation using MS Local RDLC report viewer)

I believe, you can very well change angular 2 with react or any other client side library, but the principles remain the same.

Does it work with SSRS directly?

@cgountanis the prior post is RDLC that means that there is no report server, the web server renders the report.

An interesting update from Microsoft...

https://blogs.msdn.microsoft.com/sqlrsteamblog/2018/04/02/microsoft-acquires-report-rendering-technology-from-forerunner-software/

We’re pleased to announce that we’ve acquired technology from Forerunner Softwarehttps://forerunnersw.com/ to accelerate our investments in Reporting Services. This technology includes, among other things, client-side rendering of Reporting Services (*.rdl) reports, responsive UI widgets for viewing reports, and a JavaScript SDK for integrating reports into other apps – a testament to what our partners can achieve building on our open platform.

This is great news for you, as we see opportunities to apply this technology to multiple points of feedback we’ve heard from you:

  • You’re looking for cloud Software-as-a-Service (SaaS) or Platform-as-a-Service (PaaS) that can run SSRS reports. As you might’ve seen in our Spring ’18 Release Noteshttps://aka.ms/businessappsreleasenotes, we’re actively working on bringing SSRS reports to the Power BI cloud service, and we’re building on client-side rendering to make that possible.
  • You want to view SSRS reports on your phone, perhaps using the Power BI app. We believe this technology will help us deliver better, more responsive UI for supplying report parameter values, navigating within reports, and possibly even viewing report content.
  • You love the Report Viewer control… but it’s an ASP.NET Web Forms control. You need something you can integrate into your ASP.NET Core/MVC app or non-ASP.NET app. With this technology, we hope to deliver a client-side/JavaScript-based Report Viewer you can integrate into any modern app.

These are large undertakings and we don’t yet have timeframes to share, but stay tuned over the coming months as we always strive to share our progress with you and hear your feedback as early and often as we can.

Regards

Paul


From: Denny Figuerres [[email protected]]
Sent: Friday, 23 March 2018 2:19 AM
To: aspnet/Home
Cc: Paul Sheldon; Comment
Subject: Re: [aspnet/Home] Asp.Net Core Reporting (SSRS) (#1528)

@cgountanishttps://github.com/cgountanis the prior post is RDLC that means that there is no report server, the web server renders the report.


You are receiving this because you commented.
Reply to this email directly, view it on GitHubhttps://github.com/aspnet/Home/issues/1528#issuecomment-375408680, or mute the threadhttps://github.com/notifications/unsubscribe-auth/AEHciZa6-jjUl8kgdHtuCdH6lSwhoCyyks5tg-s6gaJpZM4IsW_Z.

Oh god, not this jQuery crap again.
Bloatware.
And not just bloatware, but also slowwwwwww ...

If you need a definition of bloatware, this would be a good one.
For perfection, it basically only lacks jQuery UI, but I'm quite sure people who do things like that will still find the time to add it for the datepicker.

Oh wait, I just saw

jquery-ui-1.10.3.forerunner.js

My bad, never mind.
It's definitely a perfect example.
We of course don't just add jQuery-UI, we also roll our own modified version.

God, this looks like crap. Reports on the phone - just the thing we need - right after CrApple iPads and touchscreens on the desktop ...
And I'd still settle for SSRS working with a proxy-server, or for being able to do auth-cookie-sharing (multi-tenant virtual name based hosting - single domain multi-virtual-directories iframe inclusion without overwiting the auth-cookie of another virtual directory). Or if it (in SSRS 2016+) would render table-borders equally on IE and Chrome, and possibly Firefox.
Or just for being able to set the culture manually via query-string, have the parameter-titles translated and just do that datepicker myselfs, because MS won't get it right anyway...

THIS is THE definition of bloatware:

<link href = "~/Forerunner/Common/css/Forerunner-all.css" rel="stylesheet" />
<link href = "~/Forerunner/Lib/jQuery/css/jquery-ui-1.10.3.forerunner.css" rel="stylesheet" />
<link href = "~/Custom/Mobilizer.css" rel="stylesheet" />

<script type = "text/javascript" src="~/Forerunner/Lib/jQuery/js/jquery-1.11.0.min.js"></script>
<script type = "text/javascript" src="~/Forerunner/Lib/Misc/js/jquery.hammer.min.js"></script>
<script type = "text/javascript" src="~/Forerunner/Lib/Misc/js/json2.js"></script>
<script type = "text/javascript" src="~/Forerunner/Lib/Misc/js/scroll-startstop.events.jquery.js"></script>
<script type = "text/javascript" src="~/Forerunner/Lib/Misc/js/jquery.lazyload.min.js"></script>
<script type = "text/javascript" src="~/Forerunner/Lib/jsTree/jstree.js"></script>
<script type = "text/javascript" src="~/Forerunner/Lib/misc/js/jquery.FRmaphilight.js"></script>
<script type = "text/javascript" src="~/Forerunner/Lib/Misc/js/moment.min.js"></script>
<script type = "text/javascript" src="~/Forerunner/Bundles/forerunner.min.js"></script>
<script type = "text/javascript" src="~/Forerunner/Bundles/forerunner-tools.min.js"></script>
<script type = "text/javascript" src="~/Forerunner/Bundles/forerunner-widgets.min.js"></script>
<script type = "text/javascript" src="~/Forerunner/Lib/jQuery/js/jquery.form.js"></script>
<script type = "text/javascript" src="~/Forerunner/Lib/jQuery/js/jquery.watermark.min.js"></script>
<script type = "text/javascript" src="~/Forerunner/Lib/jQuery/js/jquery.validate1.11.1.min.js"></script>
<script type = "text/javascript" src="~/Forerunner/Lib/jQuery/js/jquery-ui-1.10.3.forerunner.js"></script>
<link href = "~/Forerunner/Common/css/Forerunner-all.css" rel="stylesheet" />
<link href = "~/Forerunner/Lib/jQuery/css/jquery-ui-1.10.3.forerunner.css" rel="stylesheet" />
<link href = "~/Custom/Mobilizer.css" rel="stylesheet" />

<script type = "text/javascript" src="~/Forerunner/Lib/jQuery/js/jquery-1.11.0.min.js"></script>
<script type = "text/javascript" src="~/Forerunner/Lib/Misc/js/jquery.hammer.min.js"></script>
<script type = "text/javascript" src="~/Forerunner/Lib/Misc/js/json2.js"></script>
<script type = "text/javascript" src="~/Forerunner/Lib/Misc/js/scroll-startstop.events.jquery.js"></script>
<script type = "text/javascript" src="~/Forerunner/Lib/Misc/js/jquery.lazyload.min.js"></script>
<script type = "text/javascript" src="~/Forerunner/Lib/jsTree/jstree.js"></script>
<script type = "text/javascript" src="~/Forerunner/Lib/misc/js/jquery.FRmaphilight.js"></script>
<script type = "text/javascript" src="~/Forerunner/Lib/Misc/js/moment.min.js"></script>
<script type = "text/javascript" src="~/Forerunner/Bundles/forerunner.min.js"></script>
<script type = "text/javascript" src="~/Forerunner/Bundles/forerunner-tools.min.js"></script>
<script type = "text/javascript" src="~/Forerunner/Bundles/forerunner-widgets.min.js"></script>
<script type = "text/javascript" src="~/Forerunner/Lib/jQuery/js/jquery.form.js"></script>
<script type = "text/javascript" src="~/Forerunner/Lib/jQuery/js/jquery.watermark.min.js"></script>
<script type = "text/javascript" src="~/Forerunner/Lib/jQuery/js/jquery.validate1.11.1.min.js"></script>
<script type = "text/javascript" src="~/Forerunner/Lib/jQuery/js/jquery-ui-1.10.3.forerunner.js"></script>

How about:

<link href = "~/css/CustomerX/3kb_styles.sass" rel="stylesheet" />
<script charset="utf-8" type = "text/javascript" src="~/Scripts/4kb_scripts_with_async.ts.js" async="async"></script>

or even better

<script async="async"  charset="utf-8" src="js/loader.js?v=1"
data-js="[ 'js/HtmlToolsAsync', 'js/mainAsync' ]"
data-js-ie-edge="['js/polyfills/es6-promise-2.0.0.min', 'js/polyfills/classList']" 
data-css="['css/{@customer}/styles']" data-css-ie-edge="['css/fixes_for_crappy_browsers_only']"></script>

Bonus points if it appends a unix-timestamp to each script and stylesheet, so changes/fixes actually take effect. Extended bonus points if it passes a datetime value as unix-timestamp instead of a culture-specific string, and doesn't fail for a date > 2030 or 9999. Or on UTF8 characters. Now as far as for right-to-left language support - we don't want to strech the limit for microsoft too far. They fail long before that. They would already exceed my expectations if it worked for more than one European language simultaneously (e.g. English, German, French and Italian).

Dear Microsoft, maybe I would want to also test if a report has all fields translated, and for that, I'd just like to log-in as different user with different language - without having to alter my browser's language settings every time (or telling a customer how to do this - that's your ultimate achievement to date - an unforgettable [very negative] experience I might add - especially after the switch to windows 8).
If you need something YOU can relate to - maybe sometimes there also exists an English user who works on a computer that's been setup for non-English users. It would therefore be nice if I as a developer could set the display language from my application, not just having it determined by the user-agent language-settings. Maybe you could take at least this into account THIS time.

But if I look at the above crap, I can already tell that you won't.

By the way, the way to set the culture in the current incarnation of SSRS, you need to do the following:

call a report with &in_language=IETF-language-tag

\machinename\Reporting Services\ReportServer\Pages\ReportViewer.aspx


<script type="text/C#" runat="server">

protected override void InitializeCulture()
{
    string language = System.Web.HttpContext.Current.Request.QueryString["in_language"];

    if (string.IsNullOrEmpty(language))
        language = "";

    switch (language.ToLowerInvariant())
    {
        case "de":
            language = "de-CH";
            break;
        case "fr":
            language = "fr-CH";
            break;
        case "it":
            language = "it-CH";
            break;
        case "en":
            language = "en-US";
            break;
        default:
            language = "";
            break;
    }

    // System.Web.HttpContext.Current.Response.Write(language);
    if (!String.IsNullOrEmpty(language))
    {
        System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.CreateSpecificCulture(language);
        System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(language);
    }

    base.InitializeCulture();
}
</script>

Then the language needs to be overwritten in the http request, (custom HTTP Module in SSRS)
(and the P3P policy is for that a form-login-post works when it's on an iframe on a different domain).

Could you see to it that you please don't break this without offering a (DISPLAY) language parameter ?
Your parameter rs:ParameterLanguage only affects the parameters in the URL, not the display of the report. And it shouldn't have to exist in the first place, e.g. if you just passed datetime as unix-timestamp (UTC). And of course, you should always the sameorigin header, or allow-from header (iframe is on different domain than the ReportServer). By the way, setting the request language in the HTTP module is for setting the datepicker with SSRS 2016 to the required language - otherwise the JavaScript fails if it has an en-US datepicker. Great, isn't it ?

How about: &rs:language=IETF/IANA language tag ?


namespace libRequestLanguageChanger
{


    public class RequestLanguageChanger : System.Web.IHttpModule
    {


        void System.Web.IHttpModule.Dispose()
        {
            // throw new NotImplementedException();
        }


        void System.Web.IHttpModule.Init(System.Web.HttpApplication context)
        {
            // https://stackoverflow.com/questions/441421/httpmodule-event-execution-order
            context.BeginRequest += new System.EventHandler(context_BeginRequest);
            context.EndRequest += new System.EventHandler(context_EndRequest);
        }


        void context_BeginRequest(object sender, System.EventArgs e)
        {
            System.Web.HttpApplication application = sender as System.Web.HttpApplication;
            System.Web.HttpContext context = application.Context;

            if (context.Request != null)
            {
                // string language = context.Request.Headers["Accept-Language"];
                string language = null;
                // string url = context.Request.RawUrl;
                // string referrer = null;


                if (context.Request.UrlReferrer != null)
                {
                    // referrer = context.Request.UrlReferrer.OriginalString;

                    string queryString = context.Request.UrlReferrer.Query;
                    System.Collections.Specialized.NameValueCollection queryStrings = System.Web.HttpUtility.ParseQueryString(queryString);
                    language = queryStrings["in_language"];
                }

                if (context.Request.QueryString["in_language"] != null)
                    language = context.Request.QueryString["in_language"];

                if (!string.IsNullOrEmpty(language))
                {
                    language = language.ToLowerInvariant();

                    switch (language)
                    {
                        case "de":
                            language = "de-CH";
                            break;
                        case "fr":
                            language = "fr-CH";
                            break;
                        case "it":
                            language = "it-CH";
                            break;
                        case "en":
                            language = "en-US";
                            break;
                        default:
                            language = "";
                            break;
                    }

                } // End if (!string.IsNullOrEmpty(language)) 

                // SQL.Log(url, referrer, language);


                // Simulate Browser-Language = language 
                if (!string.IsNullOrEmpty(language))
                {
                    // context.Request.Headers["Accept-Language"] = language;

                    System.Globalization.CultureInfo culture = new System.Globalization.CultureInfo(language);
                    System.Threading.Thread.CurrentThread.CurrentCulture = culture;
                    System.Threading.Thread.CurrentThread.CurrentUICulture = culture;

                    for (int i = 0; i < context.Request.UserLanguages.Length; ++i)
                    {
                        // context.Request.UserLanguages[i] = "en-US";
                        context.Request.UserLanguages[i] = language;
                    }

                } // End if (!string.IsNullOrEmpty(language)) 

            } // End if (context.Request != null) 


        } // End Sub context_BeginRequest 



        // https://stackoverflow.com/questions/31870789/check-whether-browser-is-chrome-or-edge
        public class BrowserInfo
        {

            public System.Web.HttpBrowserCapabilities Browser { get; set; }
            public string Name { get; set; }
            public string Version { get; set; }
            public string Platform { get; set; }
            public bool IsMobileDevice { get; set; }
            public string MobileBrand { get; set; }
            public string MobileModel { get; set; }


            public BrowserInfo(System.Web.HttpRequest request)
        {
            if (request.Browser != null)
            {
                if (request.UserAgent.Contains("Edge")
                    && request.Browser.Browser != "Edge")
                {
                    this.Name = "Edge";
                }
                else
                {
                    this.Name = request.Browser.Browser;
                    this.Version = request.Browser.MajorVersion.ToString();
                }
                this.Browser = request.Browser;
                this.Platform = request.Browser.Platform;
                this.IsMobileDevice = request.Browser.IsMobileDevice;
                if (IsMobileDevice)
                {
                    this.Name = request.Browser.Browser;
                }
            }
        }


    }


    void context_EndRequest(object sender, System.EventArgs e)
    {
        if (System.Web.HttpContext.Current != null && System.Web.HttpContext.Current.Response != null)
        {
            System.Web.HttpResponse response = System.Web.HttpContext.Current.Response;

            try
            {
                // response.Headers["P3P"] = "CP=\\\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\\\"":
                // response.Headers.Set("P3P", "CP=\\\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\\\"");
                // response.AddHeader("P3P", "CP=\\\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\\\"");
                response.AppendHeader("P3P", "CP=\\\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\\\"");

                // response.AppendHeader("X-Frame-Options", "DENY");
                // response.AppendHeader("X-Frame-Options", "SAMEORIGIN");
                // response.AppendHeader("X-Frame-Options", "AllowAll");

                if (System.Web.HttpContext.Current.Request.UrlReferrer != null)
                {
                    // "X-Frame-Options": "ALLOW-FROM " Not recognized in Chrome 
                    string host = System.Web.HttpContext.Current.Request.UrlReferrer.Scheme + System.Uri.SchemeDelimiter
                        + System.Web.HttpContext.Current.Request.UrlReferrer.Authority
                        ;

                    string selfAuth = System.Web.HttpContext.Current.Request.Url.Authority;
                    string refAuth = System.Web.HttpContext.Current.Request.UrlReferrer.Authority;

                    // SQL.Log(System.Web.HttpContext.Current.Request.RawUrl, System.Web.HttpContext.Current.Request.UrlReferrer.OriginalString, refAuth);

                    if (IsHostAllowed(refAuth))
                    {
                        BrowserInfo bi = new BrowserInfo(System.Web.HttpContext.Current.Request);

                        // bi.Name = Firefox
                        // bi.Name = InternetExplorer
                        // bi.Name = Chrome

                        // Chrome wants entire path... 
                        if (!System.StringComparer.OrdinalIgnoreCase.Equals(bi.Name, "Chrome"))
                            response.AppendHeader("X-Frame-Options", "ALLOW-FROM " + host);

                        // unsafe-eval: invalid JSON https://github.com/keen/keen-js/issues/394
                        // unsafe-inline: styles
                        // data: url(data:image/png:...)

                        // https://www.owasp.org/index.php/Clickjacking_Defense_Cheat_Sheet
                        // https://www.ietf.org/rfc/rfc7034.txt
                        // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
                        // https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP

                        // https://stackoverflow.com/questions/10205192/x-frame-options-allow-from-multiple-domains
                        // https://content-security-policy.com/
                        // http://rehansaeed.com/content-security-policy-for-asp-net-mvc/

                        // This is for Chrome:
                        // response.AppendHeader("Content-Security-Policy", "default-src 'self' 'unsafe-inline' 'unsafe-eval' data: *.msecnd.net vortex.data.microsoft.com " + selfAuth + " " + refAuth);


                        System.Collections.Generic.List < string > ls = new System.Collections.Generic.List<string>();
                        ls.Add("default-src");
                        ls.Add("'self'");
                        ls.Add("'unsafe-inline'");
                        ls.Add("'unsafe-eval'");
                        ls.Add("data:");

                        // http://az416426.vo.msecnd.net/scripts/a/ai.0.js

                        // ls.Add("*.msecnd.net");
                        // ls.Add("vortex.data.microsoft.com");

                        ls.Add(selfAuth);
                        ls.Add(refAuth);

                        string contentSecurityPolicy = string.Join(" ", ls.ToArray());
                        response.AppendHeader("Content-Security-Policy", contentSecurityPolicy);
                    }
                    else
                    {
                        response.AppendHeader("X-Frame-Options", "SAMEORIGIN");
                    }

                }
                else
                    response.AppendHeader("X-Frame-Options", "SAMEORIGIN");
            }
            catch (System.Exception ex)
            {
                // WTF ? 
                System.Console.WriteLine(ex.Message); // Suppress warning
            }

        } // End if (System.Web.HttpContext.Current != null && System.Web.HttpContext.Current.Response != null)

    } // End Using context_EndRequest


        private static string[] s_allowedHosts = new string[]
    {
        "localhost:49533"
            , "localhost:52257"
            , "www.companyX.com"
            , "companyX.com"
            , "vmcompany1"
            , "vmcompany2"
            , "vmbank1"
            , "vmbank2"
    };


        public static bool IsHostAllowed(string host)
    {
        return Contains(s_allowedHosts, host);
    } // End Function IsHostAllowed 


        public static bool Contains(string[] allowed, string current)
    {
        for (int i = 0; i < allowed.Length; ++i)
        {
            if (System.StringComparer.OrdinalIgnoreCase.Equals(allowed[i], current))
                return true;
        } // Next i 

        return false;
    } // End Function Contains 


} // End Class RequestLanguageChanger 


} // End Namespcae libRequestLanguageChanger 

Microsoft PLEASE do not use that front runner code as is!
modern client side web apps are going away from j query to es modules and such.
we do not need or want to pull in a bunch of j query code.
i'd rather give the client a pdf or the current asp.net control rather than this pile of j query.

make an npm package that plays nice with Angular 2-6 and node and other web client frameworks.
also keep working with SSRS rendering, it has many benefits. just get a set of updated web service api's

Any update on this?

Well, we basically would already have all we need.
What we'd need is an implementation of a REST/JSON-version of
http://localhost/ReportServer/ReportExecution2005.asmx
(Wouldn't hurt if we/anyone could customize the url)
as a nuget package - one that works on Linux/Mac, too.
The only things that needs to be done is to port the .NET code to .NET Core/NetStandard, and remove all the pinvokes to windows dlls. Then, add the capability of outputting PAGED html via the web-service (which is currently lacking - because it's in the asp.net-render-control), of course, and allow to set the download-filename.

The parameters selection we could even do ourselfs - reading out the RDL with XmlDocument.
(some problems with option explicit off, option strict off, option infer with VB-Code will be likely)
Kind of like the current ASP.NET control, just without all the ASP.NET-WebForms stuff.

So I don't think there's even a requirement for a single-line of JavaScript - that will anyway be different from project to project, from company to company, from person to person.
Some like jQuery. Some Like Angular. Some Like Vue. Some Like React. Some like NodeJS with NPM, some like bower, some like TypeScript, some like Babel, some flow, some even use jQuery-UI for the datepicker.

I for example largely hate all those frameworks (especially jquery-ui) with the lifespan of a fruitfly, incompabilities between versions, bloat, non-modularity and a learning-curve of whatever whyever, a community of people who don't know what they are doing (note: I hereby don't want to imply that I always know what I do), and a broken package-manager like npm/bower, that has the unpleasant characteristics of always finding a way to create new joys every time you would have wanted to use them.

So I just use VanillaJS (with ECMA-modules and async - transpiled with babel or typescript - and who cares about the transpiler.

Now of course many people will disagree - and you have the right to disagree, as there are reasons to disagree. In the end, I don't care what you use - use coffeescript and emacs with jquery-ui and vue if you absolutely want to - just don't force me down that road. I don't need/want jquery/angular/vue/react/bower/npm or any of that bloat and unreliability.

Now, that said, if you want to provide a JavaScript library that anyone can put on their site to select the parameters automatically, like in ReportServer (as opposed to RDLC), and unlike the current reportviewer-control, I'm all for it. Just if you do that, make it independent of the report "control". And use a node-like structure to compose ECMA modules, so that people who want to use node can use it with node/npm, and those who do not don't have to.

As a sidenode, if the REST/JSON-version allowed to fetch the filter data from the service as json, just like the rendered files, we wouldn't even need to read the RDL file, and we would have a very UNcomplicated JS library. The VB-code that is currently allowed in parameters would anyway not allow for doing this on the client-side.

Or on a further thought, it would be even better if the service allowed to fetch each dataset in the report as JSON. I guess we'd need to be able to read the default-values for each parameter, too. Then we could even do unit-testing of the correctness of the SQL data used in the report !
(unit-testing reports is currently rather impossible)

One additional stylesheet for the formatting would then finish the trick (SASS please). And a plugin-system for additional/alternative renderers would round that off. ¨

But at the core, we really only need a multi-platform report-rendering library.
Everything else could already be done today by the community.
I guess that if the sources for the existing controls were available, all or most of the work required could even be done completely by the community - wouldn't even cost microsoft a dime.

Is alanjuden MvcReportViewer works with with SSRS 2017 and core 2. Can I use this approach for SSRS 2017 and core 2

No, not without a lot of headache. Easiest solution is to export PDFs directly using the reportexecution2005 directly, imho. Trying to get any of the old viewers in a responsive format especially for phones and tablets is a pain.

@Mahenbisht, I have to build it from source with packages updated to the latest versions in order to make it work in core 2. Haven't tried 2017 yet.

I am using SQL Server 2017 with SSRS 2017 and core 2.
If I can not use alanjuden.MvcReportViewer.NetCore then is there any other approach

@Mahenbisht, I know I haven't been very active on mine in a while...however, you could still use a similar approach. You could always hook up to the Reporting Service api that I'm using (that's built into SSRS) to run your own reports and put them in whichever format you want.

@Mahenbisht: There is a .NET Core nuget package here:
https://www.nuget.org/packages/AspNetCore.ReportViewer/
Unfortunately, there are no sources whatsoever, so you can't see what it does and how to use it.
So I decompiled it here (it compiles) .

It seems to be the classes generated from ReportExecution2005&ReportService2010-WSDL for .NET Core.
So nothing to stop you from writing your own viewer, if you have network access to a running instance of SQL-server with SSRS.
If I remember right, you need to pass deviceinfo to render for that you get paged html output.
That leaves you with doing the parameters manually - which is what I am (theoretically) currently working on.

@alanjuden: The problem with your approach is that it requires an instance of SQL-Server with ReportingServices installed. If you have that, you can just as well put an iframe to /ReportServer, and add a little custom-authentication + W3C-header and language-localizer DLL to reportingservices. Then you don't need your work at all.

The problem with that is that
A) N customers don't always have the same version of SSRS installed (with all cumulative-updates/servicepacks - in my case currently ranging from SSRS-2008R1 to 2016),
and B) that SSRS-Express installations only have access to databases on the local machine. And what really sucks is that there is no ReportViewer control that works on non-windows PCs (Linux, Mac) - so you have to to combine .NET with Java for Birt or Jasper - which breakes xcopy-deployment - not to mention a huge overhead in both 2-3 report formats, and the entire java JVM and the birt/jasper bloatware including tomcat and/or other such crap.
and C) that ReportingService uses integrated windows authentication. So even if you use Windows, you need to add custom-authentication for outside the intranet, which means you need to have modify-access to ReportingServices, and your modifications might break other software, so any sane-customer must install a new instance of SSRS/SQL-Server (which costs money).
also D) that ReportingService parameters are not localizable without modifying ReportViewer.aspx, see C)
and also E) that any version of SSRS < 2016 Renders quirks-html (and while 2016+ is better, it is far from perfect in that regard, btw)
However, since old versions from 2008 are still around in 2018, it might take another 5 to 10 years for anything below 2016 to die out. By that time, SSRS 2016 will be hopelessly outdated anyway. If Microsoft is still around by then, that is.

Docker to the rescue - fortunately. But it's still crap.

and add a little custom-authentication + W3C-header and language-localizer DLL to reportingservices.

@ststeiger any online sample for puting SSRS viewer in iframe whit passing custom-autentification from main site and W3C headers ?

@adopilot: Here's an approximate howto:

Add custom authenication to SSRS

https://github.com/Microsoft/Reporting-Services/tree/master/CustomSecuritySample

(you'll need to modify it a little so that it uses ONE user per database.
You don't want to start to synchronize SSRS users and permissions with your forms-users!
Give this user rights on the folder for this database only.
)

Add a http-module to SSRS, which sets the p3p header, and overwrite context.Request.UserLanguages[i] with your language of choice (otherwise the datepicker doesn't work)

Modify the logon page of ReportServer, to react to get and post parameters, and set the login_cookie, then redirect to the report that was posted to.

Code in Page_Load in class FormsAuthentication_RS2012.LogOn in Assembly FormsAuthentication_RS2012

Post the data PGP/RSA-encrypted with a unix-timestamp (so it cannot be replayed) encrypted with the public key in your forms, decrypt the post-data in FormsAuthentication_RS2012 on page_load.

(cannot give you the FormsAuthentication_RS2012 code, because it contains the private key and the administrator password hard-coded)


<%@ Page Language="C#" AutoEventWireup="true" Inherits="FormsAuthentication_RS2012.LogOn, FormsAuthentication_RS2012" %>

<!DOCTYPE html PUBliC "-//W3C//DTD Xhtml 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1" /> 
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <title>SSRS Login</title>

    <style type="text/css" media="all">

        html, body
        {
            width: 100%;
            height: 100%;
            margin: 0px;
            padding: 0px;
            overflow: auto;
        }


        .divLayout 
        {
            float: left;
            height: 100%;
            background-color: #d4d4d4;
        }


        .spnTitle 
        {
            color: #0060a6;
            font-size: 45px;
            margin: 0;
            font-weight: normal;
            padding-top: 10%;
        }


        .spnLogin 
        {
            font-family: '?Segoe', 'Segoe UI', Segoe, Arial, sans-serif;
            font-size: 26px;
            vertical-align: middle;
            padding-left: 10px;
        }


        .btnLogin 
        {
            border: none;
            width: 204px;
            height: 64px;
            background-color: #d4d4d4;
            vertical-align: middle;
            text-align: center;
            color: #525252;
        }


        .btnLogin:hover
        {
            color: #FFFFFF;   
        }


        .btnLogin:hover .spnLoginSymbol 
        {
            /* http://stackoverflow.com/questions/7217244/style-child-element-when-hover-on-parent */
            background-image: url('<%=FormsAuthentication_RS2012.LogonHelper.GetPageName() %>?image=whiteForward_37x36.png');
        }


        .spnLoginSymbol
        {
            display: inline-block;
            width: 37px;
            height: 36px;
            background-image: url('<%=FormsAuthentication_RS2012.LogonHelper.GetPageName() %>?image=82Forward_37x36.png');
            background-repeat: no-repeat;
            background-size: 100% auto;
            vertical-align: middle;

            color: #525252;
        }


        .spnLoginSymbol:hover
        {
            background-image: url('whiteForward_37x36.png');
        }


        .lblCaption 
        {
            font-family: '☺Segoe', "Segoe UI", Segoe, Arial, sans-serif;
            font-size: .9em;
            display: block;
        }


        input[type=text]
        {
            border: 2px solid rgb(187, 187, 187);
            <asp:Literal Id="litUserNameStyle" runat="server" />
        }


        input[type=password] 
        {
            border: 2px solid rgb(187, 187, 187);
            <asp:Literal Id="litPWStyle" runat="server" />
        }


        input[type=text]:hover, input[type=password]:hover 
        {
            border: 2px solid rgb(237, 206, 0);
        }


        .CorLink
        {
            color: #BF0A1E; 
        }


        .CorLink:hover
        {
            color: rgb(103, 12, 12);
        }

    </style>

</head>
<body>

    <div style="position: absolute; top: 0px; width: 100%; height: 1.5cm; line-height: 1.5cm; vertical-align: middle; text-transform: uppercase; font-weight: bold; background-color: #000000; color: #FFFFFF; text-align: center; font-size: 13px; font-family: '☺Segoe', 'Segoe UI', Segoe, Arial, sans-serif; ">
        <asp:Literal Id="litAuthentication" Text="Forms-Authentication" runat="server" />
    </div>


    <div class="divLayout" style="background-color: #0060A6; width: 30%; text-align: center;">
        <img src="<%=FormsAuthentication_RS2012.LogonHelper.GetPageName() %>?image=mydb3.png" style="margin-top: 40%; margin-left: -50px;" alt="logo" />

        <!-- 

        <img src="accountsicon.png" style="margin-top: 30%;" alt="logo" />
        <img src="mydb3.png" style="margin-top: 30%;" alt="logo" />
        <img src="reportsicon.png" style="margin-top: 30%; width: 20%;" alt="logo" />

        <img src="hap-logo-128.png" style="margin-top: 30%;" alt="logo" />
        -->
    </div>

    <div class="divLayout" style="background-color: #F3F3F3; width: 70%;">





        <div class="greenBorder" style="display: table; width: 100%; height: 100%; #position: relative; overflow: hidden;">

            <div style=" #position: absolute; #top: 50%;display: table-cell; vertical-align: middle;">
                <div style=" #position: relative; #top: -50%">


                    <div style="display: table; margin-right: auto; margin-left: auto;padding-left: 1cm; padding-right: 1cm;">
                        <!--
                        <b>TEST environment</b>
                        -->

                        <span class="spnTitle">
                            SQL Server Reporting Services 2012
                        </span>

                        <div style="display: block; height: 30px;"></div>

                          <form id="form1" target="_self" method="post" runat="server">

                            <div>
                                <label for="txtUserName" class="lblCaption"><asp:Literal Id="litlblUserName" runat="server" />:</label>
                                <input id="txtUserName" name="txtUserName" type="text" style="width: 300px;" />
                            </div>


                            <div>
                                <label for="txtPassword" class="lblCaption"><asp:Literal Id="litlblPassword" runat="server" />: </label>
                                <input id="txtPassword" name="txtPassword" type="password" style="width:300px;" />
                            </div>

                            <div style="display: block; height: 30px; clear: both;"></div>


                            <button type="submit" class="btnLogin" style="">
                                <!--
                                <img src="82Forward_37x36.png" alt="arrow" style="vertical-align: middle; margin-top: 0px;" />
                                -->
                                <span class="spnLoginSymbol"></span>
                                <span class="spnLogin">Login</span>
                            </button>

                        </form>

                    </div>

                </div>
            </div>
        </div>



    </div>
    <!-- End divLayout -->


    <div style="position: absolute; bottom: 0px; width: 100%; height: 1.5cm; line-height: 1.5cm; vertical-align: middle; background-color: #000000; color: #FFFFFF; text-align: center; font-family: '☺Segoe', "Segoe UI", Segoe, Arial, sans-serif; font-size: 13px;">
        Copyright &copy; 2013 

        <a href="http://www.cor-management.ch" target="_blank" class="CorLink" onclick="$('html, body').animate({ scrollTop: 0 }); return false;">
            COR Managementsysteme GmbH
        </a>

    </div>

</body>
</html>

</body>
</html>

Add to ReportViewer.aspx


<script type="text/C#" runat="server">

    protected override void InitializeCulture()
    {
        string sprache = System.Web.HttpContext.Current.Request.QueryString["in_sprache"];

        if(string.IsNullOrEmpty(sprache))
            sprache = "";

        switch(sprache.ToLowerInvariant())
        {
            case "de":
                sprache = "de-CH";
                break;
            case "fr":
                sprache = "fr-CH";
                break;
            case "it":
                sprache = "it-CH";
                break;
            case "en":
                sprache = "en-US";
                break;
            default:
                sprache = "";
                break;
        }

        // System.Web.HttpContext.Current.Response.Write(sprache);
        if(!String.IsNullOrEmpty(sprache))
        {
            System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.CreateSpecificCulture(sprache);
            System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(sprache);
        }

        base.InitializeCulture();
    }

</script>

Add parameter-translation functionality to reportviewer.aspx:
(
Parameter has been written as German / French / Italian / English
)
split on / and default to German (you might want to use English)
add a parameter in_language (in_sprache) to the report-url, and you're kindof done, if you understood the idea.


function initLanguage()
{
    var language = null;
    var StyleSheetSet = null;
    var BrowserLanguage = <%= System.Web.HttpContext.Current.Request.UserLanguages != null ? "\"" + System.Convert.ToString(System.Web.HttpContext.Current.Request.UserLanguages[0]) + "\"" : "null" %>;

    if(BrowserLanguage == null)
        BrowserLanguage = window.navigator.userLanguage || window.navigator.language;

    if(BrowserLanguage != null)
        BrowserLanguage = BrowserLanguage.substr(0,2).toLowerCase();



    var dictParameters = getUrlVars(this.location.href);

    if (dictParameters != null && dictParameters.contains("rc:Stylesheet"))
        StyleSheetSet = true;

    if (dictParameters != null && dictParameters.contains("in_sprache"))
        language = dictParameters["in_sprache"];

    if(language == null)
        language = BrowserLanguage;

    if(language == null)
        language = "de";

    language = language.toLowerCase();

    return language;
} // End function initLanguage


function TranslateParameterPrompts(iLanguageIndex)
{
    var eles = document.getElementsByTagName("table");
    var strParamTableId = "ParametersGridReportViewerControl";
    var tblParameters = null;
    var ParamLabels = null;


    for(var j = 0; j < eles.length; ++j)
    {
        // console.log(eles[j]);

        if(eles[j] != null && eles[j].id != null)
        {
            if(eles[j].id.slice(0, strParamTableId.length) == strParamTableId) // if startswith str
            {
                // console.log(eles[j].id);
                tblParameters = eles[j];
                break;
            }
            // else console.log(eles[j].id);
        } // End if(eles[j] != null && eles[j].id != null)

    } // Next j


    if(tblParameters != null)
        ParamLabels = tblParameters.getElementsByTagName("span");

    // var ParamLabels = document.querySelectorAll("table[id^='ParametersGridReportViewerControl'] span");
    if(ParamLabels != null)
    {
        for(var i = 0; i < ParamLabels.length; ++i)
        {
            var strText = ParamLabels[i].innerHTML;

            if (strText != null && strText.indexOf('/') != -1 && strText.indexOf('<input') == -1 ) 
            {
                strText = strText.split('/');
                if (iLanguageIndex < strText.length)
                    strText = strText[iLanguageIndex];
                else 
                { 
                    if(strText.length > 0)
                        strText = strText[0];
                }

                ParamLabels[i].innerHTML = strText;
            } // End if (strText != null && strText.indexOf('/') != -1) 

        } // Next i

    } // End if(ParamLabels != null)

}


function fixReportingServices(container)
{
    var language = initLanguage();

    switch (language)
    {
        case "fr":
            iLanguageIndex = 1;
            break;
        case "it":
            iLanguageIndex = 2;
            break;
        case "en":
            iLanguageIndex = 3;
            break;
        default: // "DE" 
            iLanguageIndex = 0;
    } // End Switch

    TranslateParameterPrompts(iLanguageIndex);
}


// needed when AsyncEnabled=true. 
Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(function () { fixReportingServices('rpt-container'); });

  </script>

Now, to use this on some web-page, create an iframe called ifrmSSRS_Login (or adjust to your liking) and do a form-post on link-click:

var data = 
{
    "issued" : datetime 
   ,"databaseName" : "foo" // name of SSRS-user 
   ,parameters : [{ "name":"forms_userid", value: 123},{ "name": "parameter1", "value": "uid1,uid2,uid3" }]
}


var valueToPost = rsa(data, public_key)

post this value with JavaScript to the cross-domain SSRS-url 



    _postSSRS: function(o){
        this._Trace('_postSSRS');

        try{
            if(!!o.SSRS_Link){
                var tF = document.body.appendChild(document.createElement('form'));
                tF.setAttribute('id', 'frm_' + Date.now());
                tF.setAttribute('method', 'post');
                tF.setAttribute('action', o.SSRS_Link + 'logon.aspx');
                tF.setAttribute('style', 'display: none;');
                tF.setAttribute('target', 'ifrmSSRS_Login');

                var HttpPostVariables = {
                     'data': o.SSRS_Data 
                    ,'SSO': 'FMS'
                };

                for(var k in HttpPostVariables){
                    var tH = tF.appendChild(document.createElement('input'));
                    tH.setAttribute('name', k);
                    tH.setAttribute('value', HttpPostVariables[k])
                };

                tF.submit()
            }
        }
        catch(err){this._Log(err, '_postSSRS')}
    },

that way you can bridge authentication with SSRS, plus users from each customer (database-name) see only their reports (permissions on ssrs by database-name).

Note that uids must be passed in lowercase, because else SSRS refuses to work right/explodes like the crappy piece of software that it is.

Note:
That code accumulated over a longer period of time, for multiple versions of SSRS, and maybe overriding page-initialize-culture is no longer necessary if the http-module overrides the user-agent language (which i only figured out after realizing that overriding page-initialize-culture is not good enough for the SSRS datepicker).
Also, the use of the slash as separator for translation was unfortunate. try using a character that you don't ever need, such as £ or ¦.

The P3P header is necessary so IE 11 on non-windows-10 comptuers doesn't refuse the auth-cookie (since ssrs runs in a cross-domain iframe, it's a handled as a 3rd party cookie by IE).

Also, use SSRS 2016+, because otherwise, you need to quirks-mode features, such as border-widths, heights, margins, hide the print-function, and all kind of other "exciting IE8-specific stuff" etc.

As the assembly name says, this was done for our production server (SSRS 2012) and it all evolved from ugly SSRS 2005 hacks.

Save links in a field in your navigation table, e.g. as field NA_Link in T_Navigation
'{@report}Budget_SNB&in_user={@user}&in_sprache={@language}&rc:Stylesheet=COR_RS2012_v7'
use placeholders for the baseLink, user and language, and set the stylesheet (if you have black background, you need to tell ssrs to use your modification of their stylesheet)

SELECT 
    REPLACE(
    REPLACE( 
    REPLACE(NA_Link, '{@report}', @reportServerBaseUrl) 
    , '{@user}', @user_id)
    , '{@language}', @user_language)
FROM T_Navigation 

And note that the .NET-Framework has problems if it needs to redirect a link with a colon inside.
You can copy working code for url-redirection from the mono-project.

Also, note that you can't just pass the userid as string/number - it needs to be encrypted (private/public) so nobody can just guess the user-id. But for a start, the md5-hash of the userid might do the trick.

@ststeiger @all
AspNetCore.ReportViewer has been replaced with AspNetCore.Reporting
that's includes LocalReport and ServerReport

@amh1979: Nice work - I'll take a look at it.
I take it from it's dependency AspNetCore.ReportingServices.dll needing WindowsBase and pinvoke advapi32.dll/kernel32.dll/ReportingServicesService.exe that this only works on Windows with .NET with Framwork 4 installed ?

PS: correct english is "AspNetCore.ReportViewer has been >replaced with< AspNetCore.Reporting", not "insteaded", but I get what you mean ;)
Or you can also say "has been superseeded by", which might be the word/phrase you are looking for ;)

@amh1979: Nicely done, had to do some work because I don't have framwork 4.7.1 installed.
I get it, MainStream is result/html and SecondaryStream is CSS.
But got it up and running.
That the HTML is paged is nice too.
Do you know: Is there any way to loop though all results or get one huge HTML file without calling the render function for every page ?

@ALL: While this runs under full .net, I can't get this to run under .NET Core under Windows.
Problems with System.Drawing.Color ToKnownColor, IsSystemColor and not present KnownColor.
Fixed that, but now it's complaining about could not load assembly System.Drawing.Graphics with signature...

Is there even a way to run full FULL .net assemblies in a .NET Core project on Windows ?

@ststeiger I will update and fixed these questions in the next version.

@amh1979:

While you are at it, if you search and replace System.Array.Empty<T> with ArrayExtension.Empty<T>, then you're 90% of the way of getting it to work with .NET 4.0.

    internal static class ArrayExtension
    {

        public static T[] Empty<T>()
        {
            return new T[0];
        }

    }

@amh1979:

It uses the following

System.Drawing.Color c; 
c.IsKnownColor
c.IsSystemColor 
c.ToKnownColor()
System.Drawing.KnownColor enum

which .NET Core's System.Drawing.Common does not implement.
Here's a System.Drawing.KnownColor.cs replacement
(it's not perfect due to ambiguity, but in the absence of access to internal values of System.Drawing.Color. this is the best I could do - maybe use #ifs to make full .net framework call the actual properties if it's full .net framework ... )


namespace AspNetCore.Reporting.Helpers
{

    // System.Drawing.KnownColor.cs replacement 
    internal class ReportColor
    {


        private static System.Collections.Generic.Dictionary<System.Drawing.Color
                    , AspNetCore.Reporting.Helpers.AllKnownColors> SetupKnownColorDictionary()
        {
            System.Collections.Generic.Dictionary<System.Drawing.Color
                , AspNetCore.Reporting.Helpers.AllKnownColors>
                dict = new System.Collections.Generic.Dictionary
                <System.Drawing.Color, AspNetCore.Reporting.Helpers.AllKnownColors>();

            dict.Add(System.Drawing.Color.FromArgb(255, 180, 180, 180), AllKnownColors.ActiveBorder);
            dict.Add(System.Drawing.Color.FromArgb(255, 153, 180, 209), AllKnownColors.ActiveCaption);
            dict.Add(System.Drawing.Color.FromArgb(255, 0, 0, 0), AllKnownColors.ActiveCaptionText);
            dict.Add(System.Drawing.Color.FromArgb(255, 171, 171, 171), AllKnownColors.AppWorkspace);
            dict.Add(System.Drawing.Color.FromArgb(255, 240, 240, 240), AllKnownColors.Control);
            dict.Add(System.Drawing.Color.FromArgb(255, 160, 160, 160), AllKnownColors.ControlDark);
            dict.Add(System.Drawing.Color.FromArgb(255, 105, 105, 105), AllKnownColors.ControlDarkDark);
            dict.Add(System.Drawing.Color.FromArgb(255, 227, 227, 227), AllKnownColors.ControlLight);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 255, 255), AllKnownColors.ControlLightLight);
            dict.Add(System.Drawing.Color.FromArgb(255, 109, 109, 109), AllKnownColors.GrayText);
            dict.Add(System.Drawing.Color.FromArgb(255, 0, 120, 215), AllKnownColors.Highlight);
            dict.Add(System.Drawing.Color.FromArgb(255, 0, 102, 204), AllKnownColors.HotTrack);
            dict.Add(System.Drawing.Color.FromArgb(255, 244, 247, 252), AllKnownColors.InactiveBorder);
            dict.Add(System.Drawing.Color.FromArgb(255, 191, 205, 219), AllKnownColors.InactiveCaption);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 255, 225), AllKnownColors.Info);
            dict.Add(System.Drawing.Color.FromArgb(255, 200, 200, 200), AllKnownColors.ScrollBar);
            dict.Add(System.Drawing.Color.FromArgb(255, 100, 100, 100), AllKnownColors.WindowFrame);
            dict.Add(System.Drawing.Color.FromArgb(0, 255, 255, 255), AllKnownColors.Transparent);
            dict.Add(System.Drawing.Color.FromArgb(255, 240, 248, 255), AllKnownColors.AliceBlue);
            dict.Add(System.Drawing.Color.FromArgb(255, 250, 235, 215), AllKnownColors.AntiqueWhite);
            dict.Add(System.Drawing.Color.FromArgb(255, 0, 255, 255), AllKnownColors.Aqua);
            dict.Add(System.Drawing.Color.FromArgb(255, 127, 255, 212), AllKnownColors.Aquamarine);
            dict.Add(System.Drawing.Color.FromArgb(255, 240, 255, 255), AllKnownColors.Azure);
            dict.Add(System.Drawing.Color.FromArgb(255, 245, 245, 220), AllKnownColors.Beige);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 228, 196), AllKnownColors.Bisque);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 235, 205), AllKnownColors.BlanchedAlmond);
            dict.Add(System.Drawing.Color.FromArgb(255, 0, 0, 255), AllKnownColors.Blue);
            dict.Add(System.Drawing.Color.FromArgb(255, 138, 43, 226), AllKnownColors.BlueViolet);
            dict.Add(System.Drawing.Color.FromArgb(255, 165, 42, 42), AllKnownColors.Brown);
            dict.Add(System.Drawing.Color.FromArgb(255, 222, 184, 135), AllKnownColors.BurlyWood);
            dict.Add(System.Drawing.Color.FromArgb(255, 95, 158, 160), AllKnownColors.CadetBlue);
            dict.Add(System.Drawing.Color.FromArgb(255, 127, 255, 0), AllKnownColors.Chartreuse);
            dict.Add(System.Drawing.Color.FromArgb(255, 210, 105, 30), AllKnownColors.Chocolate);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 127, 80), AllKnownColors.Coral);
            dict.Add(System.Drawing.Color.FromArgb(255, 100, 149, 237), AllKnownColors.CornflowerBlue);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 248, 220), AllKnownColors.Cornsilk);
            dict.Add(System.Drawing.Color.FromArgb(255, 220, 20, 60), AllKnownColors.Crimson);
            dict.Add(System.Drawing.Color.FromArgb(255, 0, 0, 139), AllKnownColors.DarkBlue);
            dict.Add(System.Drawing.Color.FromArgb(255, 0, 139, 139), AllKnownColors.DarkCyan);
            dict.Add(System.Drawing.Color.FromArgb(255, 184, 134, 11), AllKnownColors.DarkGoldenrod);
            dict.Add(System.Drawing.Color.FromArgb(255, 169, 169, 169), AllKnownColors.DarkGray);
            dict.Add(System.Drawing.Color.FromArgb(255, 0, 100, 0), AllKnownColors.DarkGreen);
            dict.Add(System.Drawing.Color.FromArgb(255, 189, 183, 107), AllKnownColors.DarkKhaki);
            dict.Add(System.Drawing.Color.FromArgb(255, 139, 0, 139), AllKnownColors.DarkMagenta);
            dict.Add(System.Drawing.Color.FromArgb(255, 85, 107, 47), AllKnownColors.DarkOliveGreen);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 140, 0), AllKnownColors.DarkOrange);
            dict.Add(System.Drawing.Color.FromArgb(255, 153, 50, 204), AllKnownColors.DarkOrchid);
            dict.Add(System.Drawing.Color.FromArgb(255, 139, 0, 0), AllKnownColors.DarkRed);
            dict.Add(System.Drawing.Color.FromArgb(255, 233, 150, 122), AllKnownColors.DarkSalmon);
            dict.Add(System.Drawing.Color.FromArgb(255, 143, 188, 139), AllKnownColors.DarkSeaGreen);
            dict.Add(System.Drawing.Color.FromArgb(255, 72, 61, 139), AllKnownColors.DarkSlateBlue);
            dict.Add(System.Drawing.Color.FromArgb(255, 47, 79, 79), AllKnownColors.DarkSlateGray);
            dict.Add(System.Drawing.Color.FromArgb(255, 0, 206, 209), AllKnownColors.DarkTurquoise);
            dict.Add(System.Drawing.Color.FromArgb(255, 148, 0, 211), AllKnownColors.DarkViolet);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 20, 147), AllKnownColors.DeepPink);
            dict.Add(System.Drawing.Color.FromArgb(255, 0, 191, 255), AllKnownColors.DeepSkyBlue);
            dict.Add(System.Drawing.Color.FromArgb(255, 30, 144, 255), AllKnownColors.DodgerBlue);
            dict.Add(System.Drawing.Color.FromArgb(255, 178, 34, 34), AllKnownColors.Firebrick);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 250, 240), AllKnownColors.FloralWhite);
            dict.Add(System.Drawing.Color.FromArgb(255, 34, 139, 34), AllKnownColors.ForestGreen);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 0, 255), AllKnownColors.Fuchsia);
            dict.Add(System.Drawing.Color.FromArgb(255, 220, 220, 220), AllKnownColors.Gainsboro);
            dict.Add(System.Drawing.Color.FromArgb(255, 248, 248, 255), AllKnownColors.GhostWhite);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 215, 0), AllKnownColors.Gold);
            dict.Add(System.Drawing.Color.FromArgb(255, 218, 165, 32), AllKnownColors.Goldenrod);
            dict.Add(System.Drawing.Color.FromArgb(255, 128, 128, 128), AllKnownColors.Gray);
            dict.Add(System.Drawing.Color.FromArgb(255, 0, 128, 0), AllKnownColors.Green);
            dict.Add(System.Drawing.Color.FromArgb(255, 173, 255, 47), AllKnownColors.GreenYellow);
            dict.Add(System.Drawing.Color.FromArgb(255, 240, 255, 240), AllKnownColors.Honeydew);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 105, 180), AllKnownColors.HotPink);
            dict.Add(System.Drawing.Color.FromArgb(255, 205, 92, 92), AllKnownColors.IndianRed);
            dict.Add(System.Drawing.Color.FromArgb(255, 75, 0, 130), AllKnownColors.Indigo);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 255, 240), AllKnownColors.Ivory);
            dict.Add(System.Drawing.Color.FromArgb(255, 240, 230, 140), AllKnownColors.Khaki);
            dict.Add(System.Drawing.Color.FromArgb(255, 230, 230, 250), AllKnownColors.Lavender);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 240, 245), AllKnownColors.LavenderBlush);
            dict.Add(System.Drawing.Color.FromArgb(255, 124, 252, 0), AllKnownColors.LawnGreen);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 250, 205), AllKnownColors.LemonChiffon);
            dict.Add(System.Drawing.Color.FromArgb(255, 173, 216, 230), AllKnownColors.LightBlue);
            dict.Add(System.Drawing.Color.FromArgb(255, 240, 128, 128), AllKnownColors.LightCoral);
            dict.Add(System.Drawing.Color.FromArgb(255, 224, 255, 255), AllKnownColors.LightCyan);
            dict.Add(System.Drawing.Color.FromArgb(255, 250, 250, 210), AllKnownColors.LightGoldenrodYellow);
            dict.Add(System.Drawing.Color.FromArgb(255, 211, 211, 211), AllKnownColors.LightGray);
            dict.Add(System.Drawing.Color.FromArgb(255, 144, 238, 144), AllKnownColors.LightGreen);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 182, 193), AllKnownColors.LightPink);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 160, 122), AllKnownColors.LightSalmon);
            dict.Add(System.Drawing.Color.FromArgb(255, 32, 178, 170), AllKnownColors.LightSeaGreen);
            dict.Add(System.Drawing.Color.FromArgb(255, 135, 206, 250), AllKnownColors.LightSkyBlue);
            dict.Add(System.Drawing.Color.FromArgb(255, 119, 136, 153), AllKnownColors.LightSlateGray);
            dict.Add(System.Drawing.Color.FromArgb(255, 176, 196, 222), AllKnownColors.LightSteelBlue);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 255, 224), AllKnownColors.LightYellow);
            dict.Add(System.Drawing.Color.FromArgb(255, 0, 255, 0), AllKnownColors.Lime);
            dict.Add(System.Drawing.Color.FromArgb(255, 50, 205, 50), AllKnownColors.LimeGreen);
            dict.Add(System.Drawing.Color.FromArgb(255, 250, 240, 230), AllKnownColors.Linen);
            dict.Add(System.Drawing.Color.FromArgb(255, 128, 0, 0), AllKnownColors.Maroon);
            dict.Add(System.Drawing.Color.FromArgb(255, 102, 205, 170), AllKnownColors.MediumAquamarine);
            dict.Add(System.Drawing.Color.FromArgb(255, 0, 0, 205), AllKnownColors.MediumBlue);
            dict.Add(System.Drawing.Color.FromArgb(255, 186, 85, 211), AllKnownColors.MediumOrchid);
            dict.Add(System.Drawing.Color.FromArgb(255, 147, 112, 219), AllKnownColors.MediumPurple);
            dict.Add(System.Drawing.Color.FromArgb(255, 60, 179, 113), AllKnownColors.MediumSeaGreen);
            dict.Add(System.Drawing.Color.FromArgb(255, 123, 104, 238), AllKnownColors.MediumSlateBlue);
            dict.Add(System.Drawing.Color.FromArgb(255, 0, 250, 154), AllKnownColors.MediumSpringGreen);
            dict.Add(System.Drawing.Color.FromArgb(255, 72, 209, 204), AllKnownColors.MediumTurquoise);
            dict.Add(System.Drawing.Color.FromArgb(255, 199, 21, 133), AllKnownColors.MediumVioletRed);
            dict.Add(System.Drawing.Color.FromArgb(255, 25, 25, 112), AllKnownColors.MidnightBlue);
            dict.Add(System.Drawing.Color.FromArgb(255, 245, 255, 250), AllKnownColors.MintCream);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 228, 225), AllKnownColors.MistyRose);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 228, 181), AllKnownColors.Moccasin);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 222, 173), AllKnownColors.NavajoWhite);
            dict.Add(System.Drawing.Color.FromArgb(255, 0, 0, 128), AllKnownColors.Navy);
            dict.Add(System.Drawing.Color.FromArgb(255, 253, 245, 230), AllKnownColors.OldLace);
            dict.Add(System.Drawing.Color.FromArgb(255, 128, 128, 0), AllKnownColors.Olive);
            dict.Add(System.Drawing.Color.FromArgb(255, 107, 142, 35), AllKnownColors.OliveDrab);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 165, 0), AllKnownColors.Orange);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 69, 0), AllKnownColors.OrangeRed);
            dict.Add(System.Drawing.Color.FromArgb(255, 218, 112, 214), AllKnownColors.Orchid);
            dict.Add(System.Drawing.Color.FromArgb(255, 238, 232, 170), AllKnownColors.PaleGoldenrod);
            dict.Add(System.Drawing.Color.FromArgb(255, 152, 251, 152), AllKnownColors.PaleGreen);
            dict.Add(System.Drawing.Color.FromArgb(255, 175, 238, 238), AllKnownColors.PaleTurquoise);
            dict.Add(System.Drawing.Color.FromArgb(255, 219, 112, 147), AllKnownColors.PaleVioletRed);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 239, 213), AllKnownColors.PapayaWhip);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 218, 185), AllKnownColors.PeachPuff);
            dict.Add(System.Drawing.Color.FromArgb(255, 205, 133, 63), AllKnownColors.Peru);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 192, 203), AllKnownColors.Pink);
            dict.Add(System.Drawing.Color.FromArgb(255, 221, 160, 221), AllKnownColors.Plum);
            dict.Add(System.Drawing.Color.FromArgb(255, 176, 224, 230), AllKnownColors.PowderBlue);
            dict.Add(System.Drawing.Color.FromArgb(255, 128, 0, 128), AllKnownColors.Purple);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 0, 0), AllKnownColors.Red);
            dict.Add(System.Drawing.Color.FromArgb(255, 188, 143, 143), AllKnownColors.RosyBrown);
            dict.Add(System.Drawing.Color.FromArgb(255, 65, 105, 225), AllKnownColors.RoyalBlue);
            dict.Add(System.Drawing.Color.FromArgb(255, 139, 69, 19), AllKnownColors.SaddleBrown);
            dict.Add(System.Drawing.Color.FromArgb(255, 250, 128, 114), AllKnownColors.Salmon);
            dict.Add(System.Drawing.Color.FromArgb(255, 244, 164, 96), AllKnownColors.SandyBrown);
            dict.Add(System.Drawing.Color.FromArgb(255, 46, 139, 87), AllKnownColors.SeaGreen);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 245, 238), AllKnownColors.SeaShell);
            dict.Add(System.Drawing.Color.FromArgb(255, 160, 82, 45), AllKnownColors.Sienna);
            dict.Add(System.Drawing.Color.FromArgb(255, 192, 192, 192), AllKnownColors.Silver);
            dict.Add(System.Drawing.Color.FromArgb(255, 135, 206, 235), AllKnownColors.SkyBlue);
            dict.Add(System.Drawing.Color.FromArgb(255, 106, 90, 205), AllKnownColors.SlateBlue);
            dict.Add(System.Drawing.Color.FromArgb(255, 112, 128, 144), AllKnownColors.SlateGray);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 250, 250), AllKnownColors.Snow);
            dict.Add(System.Drawing.Color.FromArgb(255, 0, 255, 127), AllKnownColors.SpringGreen);
            dict.Add(System.Drawing.Color.FromArgb(255, 70, 130, 180), AllKnownColors.SteelBlue);
            dict.Add(System.Drawing.Color.FromArgb(255, 210, 180, 140), AllKnownColors.Tan);
            dict.Add(System.Drawing.Color.FromArgb(255, 0, 128, 128), AllKnownColors.Teal);
            dict.Add(System.Drawing.Color.FromArgb(255, 216, 191, 216), AllKnownColors.Thistle);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 99, 71), AllKnownColors.Tomato);
            dict.Add(System.Drawing.Color.FromArgb(255, 64, 224, 208), AllKnownColors.Turquoise);
            dict.Add(System.Drawing.Color.FromArgb(255, 238, 130, 238), AllKnownColors.Violet);
            dict.Add(System.Drawing.Color.FromArgb(255, 245, 222, 179), AllKnownColors.Wheat);
            dict.Add(System.Drawing.Color.FromArgb(255, 245, 245, 245), AllKnownColors.WhiteSmoke);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 255, 0), AllKnownColors.Yellow);
            dict.Add(System.Drawing.Color.FromArgb(255, 154, 205, 50), AllKnownColors.YellowGreen);
            dict.Add(System.Drawing.Color.FromArgb(255, 185, 209, 234), AllKnownColors.GradientActiveCaption);
            dict.Add(System.Drawing.Color.FromArgb(255, 215, 228, 242), AllKnownColors.GradientInactiveCaption);

            return dict;
        } // End Function SetupKnownColorDictionary 


        private static System.Collections.Generic.HashSet<System.Drawing.Color> SetupSystemColorHashMap()
        {
            System.Collections.Generic.HashSet<System.Drawing.Color> hash =
                new System.Collections.Generic.HashSet<System.Drawing.Color>(
                    new System.Drawing.Color[] {
                        System.Drawing.Color.FromArgb(255, 180, 180, 180),
                        System.Drawing.Color.FromArgb(255, 153, 180, 209),
                        System.Drawing.Color.FromArgb(255, 0, 0, 0),
                        System.Drawing.Color.FromArgb(255, 171, 171, 171),
                        System.Drawing.Color.FromArgb(255, 240, 240, 240),
                        System.Drawing.Color.FromArgb(255, 160, 160, 160),
                        System.Drawing.Color.FromArgb(255, 105, 105, 105),
                        System.Drawing.Color.FromArgb(255, 227, 227, 227),
                        System.Drawing.Color.FromArgb(255, 255, 255, 255),
                        System.Drawing.Color.FromArgb(255, 109, 109, 109),
                        System.Drawing.Color.FromArgb(255, 0, 120, 215),
                        System.Drawing.Color.FromArgb(255, 0, 102, 204),
                        System.Drawing.Color.FromArgb(255, 244, 247, 252),
                        System.Drawing.Color.FromArgb(255, 191, 205, 219),
                        System.Drawing.Color.FromArgb(255, 255, 255, 225),
                        System.Drawing.Color.FromArgb(255, 200, 200, 200),
                        System.Drawing.Color.FromArgb(255, 100, 100, 100),
                        System.Drawing.Color.FromArgb(255, 185, 209, 234),
                        System.Drawing.Color.FromArgb(255, 215, 228, 242)
                    }
            );

            return hash;
        } // End Function SetupSystemColorHashMap 


        private static System.Collections.Generic.HashSet<string> SetupKnownColorHashMap()
        {
            System.Collections.Generic.HashSet<string> map =
                new System.Collections.Generic.HashSet<string>(new string[] {
 "ActiveBorder"
,"ActiveCaption"
,"ActiveCaptionText"
,"AppWorkspace"
,"Control"
,"ControlDark"
,"ControlDarkDark"
,"ControlLight"
,"ControlLightLight"
,"ControlText"
,"Desktop"
,"GrayText"
,"Highlight"
,"HighlightText"
,"HotTrack"
,"InactiveBorder"
,"InactiveCaption"
,"InactiveCaptionText"
,"Info"
,"InfoText"
,"Menu"
,"MenuText"
,"ScrollBar"
,"Window"
,"WindowFrame"
,"WindowText"
,"Transparent"
,"AliceBlue"
,"AntiqueWhite"
,"Aqua"
,"Aquamarine"
,"Azure"
,"Beige"
,"Bisque"
,"Black"
,"BlanchedAlmond"
,"Blue"
,"BlueViolet"
,"Brown"
,"BurlyWood"
,"CadetBlue"
,"Chartreuse"
,"Chocolate"
,"Coral"
,"CornflowerBlue"
,"Cornsilk"
,"Crimson"
,"Cyan"
,"DarkBlue"
,"DarkCyan"
,"DarkGoldenrod"
,"DarkGray"
,"DarkGreen"
,"DarkKhaki"
,"DarkMagenta"
,"DarkOliveGreen"
,"DarkOrange"
,"DarkOrchid"
,"DarkRed"
,"DarkSalmon"
,"DarkSeaGreen"
,"DarkSlateBlue"
,"DarkSlateGray"
,"DarkTurquoise"
,"DarkViolet"
,"DeepPink"
,"DeepSkyBlue"
,"DimGray"
,"DodgerBlue"
,"Firebrick"
,"FloralWhite"
,"ForestGreen"
,"Fuchsia"
,"Gainsboro"
,"GhostWhite"
,"Gold"
,"Goldenrod"
,"Gray"
,"Green"
,"GreenYellow"
,"Honeydew"
,"HotPink"
,"IndianRed"
,"Indigo"
,"Ivory"
,"Khaki"
,"Lavender"
,"LavenderBlush"
,"LawnGreen"
,"LemonChiffon"
,"LightBlue"
,"LightCoral"
,"LightCyan"
,"LightGoldenrodYellow"
,"LightGray"
,"LightGrey"
,"LightGreen"
,"LightPink"
,"LightSalmon"
,"LightSeaGreen"
,"LightSkyBlue"
,"LightSlateGray"
,"LightSteelBlue"
,"LightYellow"
,"Lime"
,"LimeGreen"
,"Linen"
,"Magenta"
,"Maroon"
,"MediumAquamarine"
,"MediumBlue"
,"MediumOrchid"
,"MediumPurple"
,"MediumSeaGreen"
,"MediumSlateBlue"
,"MediumSpringGreen"
,"MediumTurquoise"
,"MediumVioletRed"
,"MidnightBlue"
,"MintCream"
,"MistyRose"
,"Moccasin"
,"NavajoWhite"
,"Navy"
,"OldLace"
,"Olive"
,"OliveDrab"
,"Orange"
,"OrangeRed"
,"Orchid"
,"PaleGoldenrod"
,"PaleGreen"
,"PaleTurquoise"
,"PaleVioletRed"
,"PapayaWhip"
,"PeachPuff"
,"Peru"
,"Pink"
,"Plum"
,"PowderBlue"
,"Purple"
,"Red"
,"RosyBrown"
,"RoyalBlue"
,"SaddleBrown"
,"Salmon"
,"SandyBrown"
,"SeaGreen"
,"SeaShell"
,"Sienna"
,"Silver"
,"SkyBlue"
,"SlateBlue"
,"SlateGray"
,"Snow"
,"SpringGreen"
,"SteelBlue"
,"Tan"
,"Teal"
,"Thistle"
,"Tomato"
,"Turquoise"
,"Violet"
,"Wheat"
,"White"
,"WhiteSmoke"
,"Yellow"
,"YellowGreen"
,"ButtonFace"
,"ButtonHighlight"
,"ButtonShadow"
,"GradientActiveCaption"
,"GradientInactiveCaption"
,"MenuBar"
,"MenuHighlight"

}, System.StringComparer.OrdinalIgnoreCase);

            return map;
        } // End Function SetupKnownColorHashMap 


        private static System.Collections.Generic.HashSet<string> m_knownColors = SetupKnownColorHashMap();
        private static System.Collections.Generic.HashSet<System.Drawing.Color> m_systemColors = SetupSystemColorHashMap();

        private static System.Collections.Generic.Dictionary<System.Drawing.Color
                , AspNetCore.Reporting.Helpers.AllKnownColors> m_knownColorDictionary = SetupKnownColorDictionary();


        // System.Drawing.Color c; c.IsKnownColor
        public static bool IsKnownColor(string color)
        {
            return m_knownColors.Contains(color);
        } // End Function IsKnownColor


        // System.Drawing.Color c; c.ToKnownColor()
        // AspNetCore.Reporting.Helpers.ReportColor.ToKnownColor(c);
        public static AspNetCore.Reporting.Helpers.AllKnownColors ToKnownColor(System.Drawing.Color c)
        {
            //System.Drawing.KnownColor knownColor = c.ToKnownColor();
            if (m_knownColorDictionary.ContainsKey(c))
                return m_knownColorDictionary[c];

            return AspNetCore.Reporting.Helpers.AllKnownColors.Unknown;
        } // End Function ToKnownColor 


        // System.Drawing.Color c; c.IsSystemColor 

        /// <include file='doc\Color.uex' path='docs/doc[@for="Color.IsSystemColor"]/*' />
        /// <devdoc>
        ///     Determines if this color is a system color.
        /// </devdoc>
        public static bool IsSystemColor(System.Drawing.Color color)
        {
            if (m_systemColors.Contains(color))
                return true;

            // return color.IsKnownColor;
            // return IsKnownColor && ((((KnownColor)knownColor) <= KnownColor.WindowText) || (((KnownColor)knownColor) > KnownColor.YellowGreen));
            return false;
        } // End Function IsSystemColor 


    } // End Class ReportColor 



    // https://raw.githubusercontent.com/mono/sysdrawing-coregraphics/master/System.Drawing/KnownColor.cs
    public enum AllKnownColors
    {
        Unknown = 0,

        ActiveBorder = 1,
        ActiveCaption = 2,
        ActiveCaptionText = 3,
        AppWorkspace = 4,
        Control = 5,
        ControlDark = 6,
        ControlDarkDark = 7,
        ControlLight = 8,
        ControlLightLight = 9,
        ControlText = 10,
        Desktop = 11,
        GrayText = 12,
        Highlight = 13,
        HighlightText = 14,
        HotTrack = 15,
        InactiveBorder = 16,
        InactiveCaption = 17,
        InactiveCaptionText = 18,
        Info = 19,
        InfoText = 20,
        Menu = 21,
        MenuText = 22,
        ScrollBar = 23,
        Window = 24,
        WindowFrame = 25,
        WindowText = 26,
        Transparent = 27,
        AliceBlue = 28,
        AntiqueWhite = 29,
        Aqua = 30,
        Aquamarine = 31,
        Azure = 32,
        Beige = 33,
        Bisque = 34,
        Black = 35,
        BlanchedAlmond = 36,
        Blue = 37,
        BlueViolet = 38,
        Brown = 39,
        BurlyWood = 40,
        CadetBlue = 41,
        Chartreuse = 42,
        Chocolate = 43,
        Coral = 44,
        CornflowerBlue = 45,
        Cornsilk = 46,
        Crimson = 47,
        Cyan = 48,
        DarkBlue = 49,
        DarkCyan = 50,
        DarkGoldenrod = 51,
        DarkGray = 52,
        DarkGreen = 53,
        DarkKhaki = 54,
        DarkMagenta = 55,
        DarkOliveGreen = 56,
        DarkOrange = 57,
        DarkOrchid = 58,
        DarkRed = 59,
        DarkSalmon = 60,
        DarkSeaGreen = 61,
        DarkSlateBlue = 62,
        DarkSlateGray = 63,
        DarkTurquoise = 64,
        DarkViolet = 65,
        DeepPink = 66,
        DeepSkyBlue = 67,
        DimGray = 68,
        DodgerBlue = 69,
        Firebrick = 70,
        FloralWhite = 71,
        ForestGreen = 72,
        Fuchsia = 73,
        Gainsboro = 74,
        GhostWhite = 75,
        Gold = 76,
        Goldenrod = 77,
        Gray = 78,
        Green = 79,
        GreenYellow = 80,
        Honeydew = 81,
        HotPink = 82,
        IndianRed = 83,
        Indigo = 84,
        Ivory = 85,
        Khaki = 86,
        Lavender = 87,
        LavenderBlush = 88,
        LawnGreen = 89,
        LemonChiffon = 90,
        LightBlue = 91,
        LightCoral = 92,
        LightCyan = 93,
        LightGoldenrodYellow = 94,
        LightGray = 95,
        LightGreen = 96,
        LightPink = 97,
        LightSalmon = 98,
        LightSeaGreen = 99,
        LightSkyBlue = 100,
        LightSlateGray = 101,
        LightSteelBlue = 102,
        LightYellow = 103,
        Lime = 104,
        LimeGreen = 105,
        Linen = 106,
        Magenta = 107,
        Maroon = 108,
        MediumAquamarine = 109,
        MediumBlue = 110,
        MediumOrchid = 111,
        MediumPurple = 112,
        MediumSeaGreen = 113,
        MediumSlateBlue = 114,
        MediumSpringGreen = 115,
        MediumTurquoise = 116,
        MediumVioletRed = 117,
        MidnightBlue = 118,
        MintCream = 119,
        MistyRose = 120,
        Moccasin = 121,
        NavajoWhite = 122,
        Navy = 123,
        OldLace = 124,
        Olive = 125,
        OliveDrab = 126,
        Orange = 127,
        OrangeRed = 128,
        Orchid = 129,
        PaleGoldenrod = 130,
        PaleGreen = 131,
        PaleTurquoise = 132,
        PaleVioletRed = 133,
        PapayaWhip = 134,
        PeachPuff = 135,
        Peru = 136,
        Pink = 137,
        Plum = 138,
        PowderBlue = 139,
        Purple = 140,
        Red = 141,
        RosyBrown = 142,
        RoyalBlue = 143,
        SaddleBrown = 144,
        Salmon = 145,
        SandyBrown = 146,
        SeaGreen = 147,
        SeaShell = 148,
        Sienna = 149,
        Silver = 150,
        SkyBlue = 151,
        SlateBlue = 152,
        SlateGray = 153,
        Snow = 154,
        SpringGreen = 155,
        SteelBlue = 156,
        Tan = 157,
        Teal = 158,
        Thistle = 159,
        Tomato = 160,
        Turquoise = 161,
        Violet = 162,
        Wheat = 163,
        White = 164,
        WhiteSmoke = 165,
        Yellow = 166,
        YellowGreen = 167,
        ButtonFace = 168,
        ButtonHighlight = 169,
        ButtonShadow = 170,
        GradientActiveCaption = 171,
        GradientInactiveCaption = 172,
        MenuBar = 173,
        MenuHighlight = 174
    } // End enum AllKnownColors 


}

I have it compiling under NetStandard 2.0

HOWTO:
Take System.CoreFX.Forms and convert it to NetStandard 2.0. Then add System.Drawing.Common and System.Reflection.Emit.

Take AspNetCore.ReportingServices and add

Microsoft.Win32.Registry
System.CodeDom
System.ComponentModel
System.ComponentModel.TypeConverter
System.Configuration.ConfigurationManager
System.Data.Common
System.Data.SqlClient
System.Drawing.Common 
System.IO.Packaging
System.Runtime.Serialization.Primitives
System.Security.Permissions

Add a reference to System.CoreFX.Forms (NetStandard)

Get the following files from mono/corefx

AssemblyRef.cs (corefx System.Drawing)
ColorConverter.cs (corefx System.Drawing)
ColorConverterCommon.cs (corefx System.Drawing)
ColorTable.cs (corefx System.Drawing)
FontConverter.cs (mono System.Drawing.FontConverter.cs)
ImageFormatConverter.cs (mono System.Drawing.ImageFormatConverter.cs)
PaintValueEventArgs.cs (corefx System.Drawing.Design)
PointConverter.cs (corefx System.Drawing.Design)
SizeConverter.cs (corefx System.Drawing.Design)
UITypeEditor.cs  (corefx System.Drawing.Design "Primitives")
UITypeEditorEditStyle.cs  (corefx System.Drawing.Design "Primitives")

And add a wrapper-class for System.Web


namespace System.Web
{

    public class HttpRequest
    {
        public System.Collections.Specialized.NameValueCollection Headers { get; set; }
    }

    public class HttpResponse
    {
        public string ContentType { get; set; }
        public int StatusCode { get; set; }
    }

    public class HttpContext
    {
        // public HttpRequest Request;
        // public HttpRequest Response;

        public HttpRequest Request { get; set; }
        public HttpResponse Response { get; set; }


        public static HttpContext Current;
    }
}

And allow unsafe code in the new netstandard 2.0 project.

Now add AssemblyInfo.cs with

[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("AspNetCore.Reporting, PublicKey=00240000048000009400000006020000002400005253413100040000010001003736e45ce2a56cd06bc9ab2e7eeeeffd2533eaafbc1abc68561da0f512412bf1c7d2bd0c4422565a4f35818a205b4d54af1d0fef14fb8d7249bc37913e53a3313c2f26ca838849c5ef766082ed02db74e6459e77840dfe5eb01574aa0722876b2a9f714c5d03fbcea6e88345ccf55a87d57d9653a5913a826008b1d3ac557aab", AllInternalsVisible = true)]
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("AspNetCore.Reporting", AllInternalsVisible = true)]

And now it compiles on NetStandard 2.0.

Hey @All amazing news:

I have it working with .NET Core on Windows !
100% NetStandard, 0% NetFramework

Html, Pdf, Excel, Excel2007+, Word, Word2007+ and tiff all worked fine on a 57 page tabular report with varchars, ints, tinyint2, bits, and computed columns.
All output formats work, except RDL, which is kindof funny, but who cares.
We'll find the problem eventually, won't we ?

AspNetCore.Reporting.LocalReport lr = new AspNetCore.Reporting.LocalReport(fn);
lr.AddDataSource("DataSet1", dt);

var rr = lr.Execute(AspNetCore.Reporting.RenderType.WordOpenXml, 1, null, "");

// var rr = lr.Execute(AspNetCore.Reporting.RenderType.Rpl, 1, null, ""); // Kaboom 
// var rr = lr.Execute(AspNetCore.Reporting.RenderType.Html, 2, null, "");
// var rr = lr.Execute(AspNetCore.Reporting.RenderType.Pdf, 1, null, "");
// var rr = lr.Execute(AspNetCore.Reporting.RenderType.Excel, 1, null, "");
// var rr = lr.Execute(AspNetCore.Reporting.RenderType.ExcelOpenXml, 1, null, "");
// var rr = lr.Execute(AspNetCore.Reporting.RenderType.Word, 1, null, "");
// var rr = lr.Execute(AspNetCore.Reporting.RenderType.WordOpenXml, 1, null, "");

System.Console.WriteLine(rr.TotalPages);

// System.IO.File.WriteAllBytes(@"d:\foo.htm", rr.MainStream);
// System.IO.File.WriteAllBytes(@"d:\foo.css", rr.SecondaryStream);
// System.IO.File.WriteAllBytes(@"d:\foo.pdf", rr.MainStream);
// System.IO.File.WriteAllBytes(@"d:\foo.xls", rr.MainStream);
// System.IO.File.WriteAllBytes(@"d:\foo.xlsx", rr.MainStream);
// System.IO.File.WriteAllBytes(@"d:\foo.doc", rr.MainStream);
// System.IO.File.WriteAllBytes(@"d:\foo.docx", rr.MainStream);
// System.IO.File.WriteAllBytes(@"d:\foo.tiff", rr.MainStream);

// System.IO.File.WriteAllBytes(@"d:\foo.rpl", rr.MainStream); // BOOM 

And there's more good news:
WindowsBase (aka WPF) was only used for System.IO.Packaging, which is available in .NET Core.
Now that means that if we can get rid of the pinvokes, there are no major roadblocks to get this to work on Linux/Mac, too !

Now somebody quickly start writing a web-based RDL editor !
Then we could have "dynamic" (user-generated) reports as well.
PostgreSQL-ReportingServices for Linux is coming ;)
(ok, there is a legal sword of Damocles on such a thing, but if we could just publish it from China, which has "more relaxed" intellectual property rights ... ) :)

OK, maybe that's too evil.
Think Microsoft ReportingServices for Oracle/SAP instead !
Or ReportingServices for Cassandra/Spark :grin:

@amh1979:
Is there no PowerPoint-renderer in there ?
Did you build it from the latest version of reportviewer ? (SSRS 2017)
The latest version I know on nuget:
https://www.nuget.org/packages/Microsoft.ReportingServices.ReportViewerControl.WebForms
(140.1000.523, 10 months ago)
https://www.nuget.org/packages/Microsoft.ReportingServices.ReportViewerControl.WinForms
(140.1000.523)
https://www.nuget.org/packages/Microsoft.SqlServer.Types
(14.0.314.76)

Here's the CoreFX WinForms implementation for NetStandard:
https://github.com/ststeiger/System.CoreFX.Forms

Mind the gap, since I added an additional NetCore project, and renamed System.CoreFX.Forms to System.NetStandard.Forms, it might have difficulties loading the embedded resources, if it does so.

The files can be found here:

AssemblyRef.cs
ColorConverter.cs
ColorConverterCommon.cs
ColorTable.cs
FontConverter.cs
ImageFormatConverter.cs
PaintValueEventArgs.cs
PointConverter.cs
SizeConverter.cs
UITypeEditor.cs
UITypeEditorEditStyle.cs

@amh1979:
Ah, I see, that's not in Microsoft.ReportViewer.Common.dll.
But it's in the ReportServer directory:
Microsoft.ReportingServices.PowerPointRendering.dll
and for CSV/XML/Atom:
Microsoft.ReportingServices.DataRendering.dll

C:\Program Files\Microsoft SQL Server Reporting Services\SSRS\ReportServer\bin

@ALL: Ladies, the HTML-renderer is working on Linux on .NET Core / NetStandard 2.0 !
And so is the WordOpenXML and the ExcelOpenXML renderer !
(not tested with pictures/graphics - text and code only)

The PDF-renderer has problems with font-embedding pinvokes.
(Word/Excel-2003 renderer is using pinvokes and therefore doesn't work.)
If you use Aspose Cells/Words eval version, you can convert the xlsx to xls, and the docx to doc.
You can also generate the PDF from the word-file:
soffice --headless --convert-to pdf filename.docx
(or again, with aspose eval)
Thinking about it, the PPTX renderer should be easy todo, too, because all it does is taking the pictures from the TIFF file and put each tiff page image as jpg/png onto a pptx slide.
Looks like the image-renderer is the hardest thing todo.
Or you can take wkhtmltoX and render each HTML page into a image/pdf.
That would probably be a little on the slow side, though.

Amazing !

HTML for report

@ALL: Atom/CSV/XML working. So is the NULL-renderer.
On Linux, too.

The PowerPoint render works on Windows only - pinvokes

Fun fact: There seems to be a JSON-renderer in there.
But for some reason, that crap only works in a useSharedDataSetTableHandler case , whatever that means

ParseDeviceInfo(deviceInfo);

if (!useSharedDataSetTableHandler)
{
    throw new ReportRenderingException(StringResources.rrJsonRenderOutputNotSupported);
}

Anybody by hazard knows how to use the JSON-renderer ?

@amh1979 I tried using the server report but it looks like the parameters I added for the report do not get persisted to the server in LoadReport. Is there any chance you could set it so those are sent to the server in your next build?

Hi @ststeiger and @amh1979, Great work on this, are there any tutorials on how to use this library out there? I'm trying to figure out how to/if it currently supports multi value parameters and whether drilldowns are supported.
I keep trying to get to the site linked in the nuget package description (http://www.amhx.org/) to see, but it keeps timing out on me.

@DavidHayesCoding:
Here my test-code for AspNetCore.Reporting.LocalReport, which is all I'm interested in:
Note:
The render-types Rpl, RGDI, Atom, Xml, Json, Csv, null, pptx
will not be available to you, as they are not in amh1979's assembly.
(they are part of SSRS, but not present in the ReportViewer redistributable)

Also note, that the the shared datasource (*.rds) needs to be in the same directory as the *.rdl, otherwise you'll get a null-reference exception on LocalReport.Execute.

For further questions:
https://github.com/icsharpcode/ILSpy/releases/tag/v4.0-beta2
(Note: in proper code, you need to dispose the datatable after finishing using it)

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;

namespace NetCoreReporting
{


    public class Program
    {


        public static void Main(string[] args)
        {
            System.Data.SqlClient.SqlConnectionStringBuilder csb = new System.Data.SqlClient.SqlConnectionStringBuilder();
            csb.InitialCatalog = "TestDB";

            if ("COMPANY_NAME".Equals(System.Environment.UserDomainName, System.StringComparison.InvariantCultureIgnoreCase))
                csb.DataSource = System.Environment.MachineName + @"\SQLEXPRESS";
            else
                csb.DataSource = System.Environment.MachineName;

            if(System.Environment.OSVersion.Platform == System.PlatformID.Unix)
                csb.IntegratedSecurity = false;
            else
                csb.IntegratedSecurity = true;

            if (!csb.IntegratedSecurity)
            {
                csb.UserID = TestPlotly.SecretManager.GetSecret<string>("DefaultDbUser");
                csb.Password = TestPlotly.SecretManager.GetSecret<string>("DefaultDbPassword");
            }



            string sql = "SELECT * FROM T_Sites";
            // sql = "SELECT * FROM T_Users";

            System.Data.DataTable dt = new System.Data.DataTable();

            using (System.Data.Common.DbDataAdapter da = new System.Data.SqlClient.SqlDataAdapter(sql, csb.ConnectionString))
            {
                da.Fill(dt);
            }

            string fn = "wwwroot/Report1.rdl";
            fn = "wwwroot/Report2.rdl";

            AspNetCore.Reporting.LocalReport lr = new AspNetCore.Reporting.LocalReport(fn);


            System.Collections.Generic.Dictionary<string, string> parameters = 
                new System.Collections.Generic.Dictionary<string, string>();

            // parameters.Add("in_logo", "base64");

            lr.AddDataSource("DataSet1", dt); // DataSet1 is the name of the DataSet in the report




            // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Html, 1, null, "");

            // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Rpl, 1, null, ""); // Kaboom 
            // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Html, 2, null, "");
            // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Pdf, 1, null, "");
            // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Excel, 1, null, "");
            // var rr = lr.Execute(AspNetCore.Reporting.RenderType.ExcelOpenXml, 1, null, "");
            // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Word, 1, null, "");
            // var rr = lr.Execute(AspNetCore.Reporting.RenderType.WordOpenXml, 1, null, "");
            // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Atom, 1, null, "");
            // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Xml, 1, null, "");
            // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Json, 1, null, "");// KABOOM 
            // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Csv, 1, null, "");

            var rr = lr.Execute(AspNetCore.Reporting.RenderType.Pptx, 1, parameters, "");

            System.Console.WriteLine(rr.TotalPages);


            string dir = @"d:\";
            if (System.Environment.OSVersion.Platform == System.PlatformID.Unix)
                dir = "/opt/";

            // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.htm"), rr.MainStream);
            // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.css"), rr.SecondaryStream);
            // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.pdf"), rr.MainStream);
            // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.xls"), rr.MainStream);
            // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.xlsx"), rr.MainStream);
            // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.doc"), rr.MainStream);
            // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.docx"), rr.MainStream);
            // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.tiff"), rr.MainStream);

            // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.atom.xml"), rr.MainStream);
            // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.xml"), rr.MainStream);
            // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.json"), rr.MainStream);
            // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.csv"), rr.MainStream);

            // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.rpl"), rr.MainStream); // BOOM 
            // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.htm"), rr.MainStream);
            System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.pptx"), rr.MainStream);

            BuildWebHost(args).Run();
        }


        public static IWebHost BuildWebHost(string[] args)
        { 
            return WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .Build();
        }


    }


}

Could I suggest that posting masses of code and length comments is a really difficult-to-digest-and-read way of tracking this issue?

I can see a lot of activity, a lot of code, but really am none the wiser as to what the recent (seemingly excellent) developments have been.

Could I suggest keeping things neat & tidy here, and using another repo / appropriate tools for sharing code? Is there a plain & simple status update that might be shared here?

like @kierenj i think the code listings as a post make it hard to follow. put up a github and then share a link. see if the admins of this repo want to make some branches etc...

@kierenj @figuerres : I would be fine with that, but if you publish larger amounts of decompiled Microsoft code without asking for permission first, you probably risk crossing the line to where they might want to do something about it ...

iii. Distribution Restrictions. You may not
• distribute Distributable Code to run on a platform other than the Windows platform;
• the code be disclosed or distributed in source code form; or
• others have the right to modify it.

@ststeiger
and you can work with the repo right here to make a branch and put code in that branch.
then they have it and know about it etc...

@figuerres: I made the repo on gitlab, where a private repository is free.

@MaximRouiller:
I would have a version of ReportViewer (local reports) roughly working under ASP.NET Core.
About 75% of it would even work under Linux, for which Microsoft has published SQL-Server.
The parts that work under Linux most likely work under MacOS, too.

However this version of ReportViewer is based on code of
https://www.nuget.org/packages/AspNetCore.Reporting
which seems to be based on code from
https://www.nuget.org/packages/Microsoft.ReportingServices.ReportViewerControl.WebForms
which comes under this license
http://go.microsoft.com/fwlink/?LinkId=826162

This license does not allow to
• distribute Distributable Code to run on a platform other than the Windows platform;
• the code be disclosed or distributed in source code form; or
• others have the right to modify it.
• work around any technical limitations in the software;
• > no reverse-engineering allowed <

I would like to (publicly) share that code with the community here on github, at a yet to be determined location, for the purpose of improving on the code and to work out any possible remaining bugs, to bring ReportViewer to .NET Core.
However, I would not like to take such a step unilaterally considering the current license of ReportViewerControl.WebForms.

I think a lot has changed since that license was first written / last-updated.
For example, it would make little sense to publish a ReportViewer for .NET Core when the result would only work on the windows platform - also considering that Microsoft has released SQL-Server for Linux, which means at some point in time, SSRS has to follow anyway.

And given that ASP.NET-Core does not implement WebForms, the change from ReportViewer-WebForms to ReportViewer-NetCore would be a breaking change anyway.

Could you discretely ask the powers that be, if, considering the circumstances, they give green light to such an endeavour - which incidentally would save THEM time and manpower, too - and align nicely with the open-source nature of .NET-Core / NetStandard 2.0.

It's been over 2 YEARS since .NET-Core was released, and there is still no solution for reports wide and far. It's time this is rectified.
If we do it together, we'll all be faster and better off.

http://go.microsoft.com/fwlink/?LinkId=826162
What I'm worried about.
If not, I will unlisted the packages from NuGet.

@ALL: Greate news: Removed the COM-InterOP-calls for XLS/DOC and replaced it with OpenMcdf.
XLS/DOC-Renderer is therefore now working on both Linux and Windows.
Now 85% working on Linux.

It looks like we are down to 3 WinAPI-calls for PDFWriter, and 13 WinAPI-Calls for ImageRenderer/Graphics.
I think the PdfWriter itselfs might be fairly easy.

Hi @ststeiger I cannot run AspNetCore.Reporting on Azure Function with Consumption Plan because it has blocked GDI+ function. Do you have any solutions for it ? Thanks.

Not quite yet - it makes several calls to GDI+ and usp10.dll, mainly to get font information.
Also it's passing GDI+ pointers around, and there's no simple replacement, because mono libgdi+ chose to do things differently (for good reason).

I've been able to re-write the function GetFontData in C# by reading the C source of Wine, but I need freetype to get to the TrueType font information (wine uses FreeType as well).
SixLabors.Fonts and LayoutFarm just aren't there yet (by a wide margin).
Here:
https://gist.github.com/ststeiger/273341aebd29009f2b272b822b69563f

Also, I replaced the text-measurements with freetype

Now I need to replace every GDI device handle with a custom class.
That class must then contain font/graphics/freetype-face/handle information, etc. so I don't need to re-write the renderer.

When that is done, I need to look at wine again, for the paper-to-world and world-to-paper transforms.
And then it should be done.
I think the paper-to-world and world-to-paper transforms might already be in System.Drawing.Graphics.
Looks like part of the code was once written using .NET Framwork 1.0.

Also, I still need to map between .NET font and freetype font somehow.

hey folks @ALL and @ststeiger
regards to:

@ALL: Greate news: Removed the COM-InterOP-calls for XLS/DOC and replaced it with OpenMcdf.
XLS/DOC-Renderer is therefore now working on both Linux and Windows.
Now 85% working on Linux.

Office Open XML

honestly i think it would be better to use the newer XML doc stuff, then no form of OLE needed at all.
Ok so if someone was still using really really old Office apps not so good for back compat. but Office Open XML has been around since about 2002-2006 so anyone using word or excel from the last 10 years will be able to use docx and xlsx file format just fine.
just my thought on that...

Just so we don't misunderstand us:
Of course the OpenXml Excel renderer works as well.

I'm just saying XLS/DOC works as well, if it has to.
Now as to whether XLS/DOC should be exposed or not, or whether that could be safely deleted is another question. There might still be some old programs out there that can't work with XLSX.

UBS for example still uses COBOL programs.
And there are various others.
So it's probably better to let XLS functionality in for a little longer, just in case.

@RaymondHuy:
If Azure has blocked GDI+ function, does System.Drawing.Common work at all ?
Or does this only apply to framework-external DllImport calls ?

Hmm, just googled it.
Looks like the System.Drawing libraries are available in Azure Cloud Service (basically just a VM), but not in Azure Web App (basically shared hosting?).
This could be a problem.
So once this is runnign on Linux, we'd need to replace anything System.Drawing with SixLabors.ImageSharp later, to get it running on Azure Web App.

This is gonna cost time and effort.
@RaymondHuy:
Could you check if FreeType (SharpFont wrapper) works on Azure ?
https://github.com/Robmaister/SharpFont

Note:
On x64-Windows, you need to replace the using clause for FT_Long and FT_ULong with this

#if WINDOWS
    using FT_Long = System.Int32;
    using FT_ULong = System.UInt32;    
#else // Linux, MacOS
    using FT_Long = System.IntPtr;
    using FT_ULong = System.UIntPtr;
#endif

because the patched freetype dlls don't work on x64-Windows.

Here's how I did that:
https://gist.github.com/ststeiger/9e2eb98e29a3c987aca739045af1d2ce

(Note: define WINDOWS in the build-options)

with some test code:

SharpFont.Native.Init();

SharpFont.Library lib = new SharpFont.Library();

string font = @"C:\Windows\Fonts\tahoma.ttf";
if(System.Environment.OSVersion.Platform == System.PlatformID.Unix)
    font = "/usr/share/wine/fonts/tahoma.ttf";

SharpFont.Face fontFace = new SharpFont.Face(lib, font);


float size = 12;
if (fontFace!= null)
    // fontFace.SetCharSize(0, size, 0, 96);
    fontFace.SetCharSize(size, size, 96, 96);

System.Console.WriteLine(fontFace.Size.Metrics.Ascender.ToDouble());

fontFace.Size.Metrics.Ascender will produce an exception if that if WINDOWS correction isn't applied.

when i am trying with .rdlc file i am getting exception
AspNetCore.ReportingServices.RdlExpressions.ExpressionHostObjectModel.DataRegionExprHost(Of TMemberType, TCellType).m_memberTreeHostsRemotable' is not accessible in this context because it is 'Friend'.’.' in localreport.Execute()
please help me

        string sql = "SELECT * FROM employee";
        // sql = "SELECT * FROM T_Users";

        System.Data.DataTable dt = new System.Data.DataTable();

        using (System.Data.Common.DbDataAdapter da = new System.Data.SqlClient.SqlDataAdapter(sql, csb.ConnectionString))
        {
            da.Fill(dt);
        }

        string fn = "wwwroot/Report1.rdl";
        fn = "wwwroot/InOutTab31.rdlc";

        AspNetCore.Reporting.LocalReport lr = new AspNetCore.Reporting.LocalReport(fn);


        System.Collections.Generic.Dictionary<string, string> parameters =
            new System.Collections.Generic.Dictionary<string, string>();
        parameters["TEN_ID"]="45";
        parameters["START_DATE"]="2018";
        parameters["END_DATE"]= "2018";

        // parameters.Add("in_logo", "base64");

        lr.AddDataSource("DsDayStatusTab31", dt); // DataSet1 is the name of the DataSet in the report




        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Html, 1, null, "");

        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Rpl, 1, null, ""); // Kaboom 
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Html, 2, null, "");
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Pdf, 1, null, "");
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Excel, 1, null, "");
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.ExcelOpenXml, 1, null, "");
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Word, 1, null, "");
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.WordOpenXml, 1, null, "");
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Atom, 1, null, "");
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Xml, 1, null, "");
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Json, 1, null, "");// KABOOM 
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Csv, 1, null, "");

        var rr = lr.Execute(AspNetCore.Reporting.RenderType.Excel, 1, parameters, "");

        System.Console.WriteLine(rr.TotalPages);


        string dir = @"d:\";
        if (System.Environment.OSVersion.Platform == System.PlatformID.Unix)
            dir = "/opt/";

        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.htm"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.css"), rr.SecondaryStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.pdf"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.xls"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.xlsx"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.doc"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.docx"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.tiff"), rr.MainStream);

        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.atom.xml"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.xml"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.json"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.csv"), rr.MainStream);

        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.rpl"), rr.MainStream); // BOOM 
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.htm"), rr.MainStream);
        System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.pptx"), rr.MainStream);

        BuildWebHost(args).Run();

It would seem you have a problem with embedded VB expressions.
There are anyway multiple problems.

In Microsoft.VisualBasic1\VBCodeGenerator.cs
UseShellExecute needs to be set to false.

System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo(cmd)
{
    WorkingDirectory = currentDir,
    RedirectStandardOutput = true,
    RedirectStandardInput = true,
    UseShellExecute = false  // <== or else it can't redirect output
};

And FromFileBatch needs to be replaced with roslyn if compiled for netstandard (CodeDom provider can't compile for netstandard - funny exceptions if VB-expressions are used, e.g. in parameters)


        protected override System.CodeDom.Compiler.CompilerResults FromFileBatch(System.CodeDom.Compiler.CompilerParameters options, string[] fileNames)
        {

#if NETSTANDARD2_0
            return NetStandardFromFileBatch(options, fileNames);
#else
            return OldFromFileBatch(options, fileNames);
#endif
        }




#if NETSTANDARD2_0         



        protected System.CodeDom.Compiler.CompilerResults NetStandardFromFileBatch(System.CodeDom.Compiler.CompilerParameters options, string[] fileNames)
        {
            //// C:\Program Files\dotnet\sdk\2.0.0\Roslyn

            //string sysver = System.Runtime.InteropServices.RuntimeEnvironment.GetSystemVersion();
            //System.Console.WriteLine(sysver);


            //string pf64 = System.Environment.ExpandEnvironmentVariables("%ProgramW6432%");
            //string pf32 = System.Environment.ExpandEnvironmentVariables("%ProgramFiles(x86)%");
            //string pf = pf32;

            //if (System.IntPtr.Size * 8 == 64)
            //    pf = pf64;

            //// compilerDirectory = System.Environment.GetFolderPath(System.Environment.SpecialFolder.ProgramFiles);
            ////compilerDirectory = System.IO.Path.Combine(compilerDirectory, "dotnet", "sdk", "2.0.0", "Roslyn");
            //compilerDirectory = System.IO.Path.Combine(pf32, "MSBuild", "14.0", "Bin");
            //if (System.IntPtr.Size * 8 == 64)
            //    compilerDirectory = System.IO.Path.Combine(compilerDirectory, "amd64");

            string assemblyName = System.IO.Path.GetFileNameWithoutExtension(options.OutputAssembly);

            Microsoft.CodeAnalysis.SyntaxTree[] syntaxTrees = new Microsoft.CodeAnalysis.SyntaxTree[fileNames.Length];

            for (int i = 0; i < fileNames.Length; ++i)
            {
                string fileContent = System.IO.File.ReadAllText(fileNames[i], System.Text.Encoding.UTF8);

                Microsoft.CodeAnalysis.VisualBasic.VisualBasicParseOptions op = null;

                // ERR_EncodinglessSyntaxTree = 37236 - Encoding must be specified... 
                syntaxTrees[i] = Microsoft.CodeAnalysis.VisualBasic.VisualBasicSyntaxTree.ParseText(
                    fileContent, op, fileNames[i], System.Text.Encoding.UTF8
                );

            }

            Microsoft.CodeAnalysis.MetadataReference[] references =
                new Microsoft.CodeAnalysis.MetadataReference[options.ReferencedAssemblies.Count];

            for (int i = 0; i < references.Length; ++i)
            {
                references[i] = Microsoft.CodeAnalysis.MetadataReference.CreateFromFile(
                    options.ReferencedAssemblies[i]
                );
            }



            Microsoft.CodeAnalysis.VisualBasic.VisualBasicCompilationOptions co =
                new Microsoft.CodeAnalysis.VisualBasic.VisualBasicCompilationOptions
            (
                Microsoft.CodeAnalysis.OutputKind.DynamicallyLinkedLibrary
            );

            co.WithOptionStrict(Microsoft.CodeAnalysis.VisualBasic.OptionStrict.Off);
            co.WithOptionExplicit(false);
            co.WithOptionInfer(true);

            Microsoft.CodeAnalysis.Compilation compilation = Microsoft.CodeAnalysis.VisualBasic.VisualBasicCompilation.Create(
                assemblyName,
                syntaxTrees,
                references,
                co
            );


            System.CodeDom.Compiler.CompilerResults compilerResults = new System.CodeDom.Compiler.CompilerResults(options.TempFiles);

            compilerResults.NativeCompilerReturnValue = -1;

            // using (var dllStream = new System.IO.MemoryStream())
            using (System.IO.FileStream dllStream = System.IO.File.Create(options.OutputAssembly))
            {
                using (System.IO.MemoryStream pdbStream = new System.IO.MemoryStream())
                {
                    Microsoft.CodeAnalysis.Emit.EmitResult emitResult = compilation.Emit(dllStream, pdbStream);
                    if (!emitResult.Success)
                    {

                        foreach (Microsoft.CodeAnalysis.Diagnostic diagnostic in emitResult.Diagnostics)
                        {
                            // options.TreatWarningsAsErrors
                            if (diagnostic.IsWarningAsError || diagnostic.Severity == Microsoft.CodeAnalysis.DiagnosticSeverity.Error)
                            {
                                string errorNumber = diagnostic.Id;
                                string errorMessage = diagnostic.GetMessage();

                                string message = $"{errorNumber}: {errorMessage};";
                                string fileName = diagnostic.Location.SourceTree.FilePath;

                                Microsoft.CodeAnalysis.FileLinePositionSpan lineSpan = diagnostic.Location.GetLineSpan();
                                string codeInQuestion = lineSpan.Path;
                                int line = lineSpan.StartLinePosition.Line;
                                int col = lineSpan.StartLinePosition.Character;

                                compilerResults.Errors.Add(
                                    new System.CodeDom.Compiler.CompilerError(fileName, line, col, errorNumber, errorMessage)
                                );
                            } // End if 

                        } // Next diagnostic 

                        // emitResult.Diagnostics
                        // CheckCompilationResult(emitResult);
                    }
                    else
                    {
                        compilerResults.PathToAssembly = options.OutputAssembly;
                        compilerResults.NativeCompilerReturnValue = 0;
                    }
                }
            }

            // compilerResults.CompiledAssembly = System.Reflection.Assembly.Load(array3, null);

            return compilerResults;
        }
#endif

There are RoslynCodeDomProviders in https://github.com/aspnet/RoslynCodeDomProvider, but they anyway use Roslyn behind the scenes. And compiling relatively hardcoded with "C:\WINDOWS\Microsoft.NET\Framework\\vbc.exe" is anyway a bad idea.

Now I got the full HTML4, HTML5 and MHTML-renderer working.
Not just the paginated one.

Hi I'm using [https://www.nuget.org/packages/AspNetCore.Reporting] and it works perfectly in local IIS.
But once i deploy it in the windows server 2012 R2 I encounter a problem.

Error Logs.

fail: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[1]
An unhandled exception has occurred while executing the request.
AspNetCore.Reporting.LocalProcessingException: An error occurred during local report processing.;The definition of the report 'D:\Apps\BillingApproval\ReportFiles\ReleaseProcess.rdl' is invalid.
An unexpected error occurred while compiling expressions. Native compiler return value: -1073741819'. ---> AspNetCore.Reporting.DefinitionInvalidException: The definition of the report 'D:\Apps\BillingApproval\ReportFiles\ReleaseProcess.rdl' is invalid. An unexpected error occurred while compiling expressions. Native compiler return value:-1073741819'. ---> AspNetCore.ReportingServices.ReportProcessing.ReportPublishingException: An unexpected error occurred while compiling expressions. Native compiler return value: -1073741819'. at AspNetCore.ReportingServices.ReportPublishing.ReportPublishing.InternalCreateIntermediateFormat(Stream definitionStream, String& description, String& language, ParameterInfoCollection& parameters, DataSourceInfoCollection& dataSources, DataSetInfoCollection& sharedDataSetReferences, UserLocationFlags& userReferenceLocation, ArrayList& dataSetsName, Boolean& hasExternalImages, Boolean& hasHyperlinks, Byte[]& dataSetsHash) at AspNetCore.ReportingServices.ReportPublishing.ReportPublishing.CreateIntermediateFormat(Byte[] definition, String& description, String& language, ParameterInfoCollection& parameters, DataSourceInfoCollection& dataSources, DataSetInfoCollection& sharedDataSetReferences, UserLocationFlags& userReferenceLocation, ArrayList& dataSetsName, Boolean& hasExternalImages, Boolean& hasHyperlinks, Byte[]& dataSetsHash) at AspNetCore.ReportingServices.ReportProcessing.ReportProcessing.CompileOdpReport(PublishingContext reportPublishingContext, PublishingErrorContext errorContext, String& reportDescription, String& reportLanguage, ParameterInfoCollection& parameters, DataSourceInfoCollection& dataSources, DataSetInfoCollection& sharedDataSetReferences, UserLocationFlags& userReferenceLocation, ArrayList& dataSetsName, Boolean& hasExternalImages, Boolean& hasHyperlinks, Byte[]& dataSetsHash) at AspNetCore.ReportingServices.ReportProcessing.ReportProcessing.CreateIntermediateFormat(PublishingContext reportPublishingContext) at AspNetCore.Reporting.ReportCompiler.CompileReport(ICatalogItemContext context, Byte[] reportDefinition, Boolean generateExpressionHostWithRefusedPermissions, ControlSnapshot& snapshot) --- End of inner exception stack trace --- at AspNetCore.Reporting.ReportCompiler.CompileReport(ICatalogItemContext context, Byte[] reportDefinition, Boolean generateExpressionHostWithRefusedPermissions, ControlSnapshot& snapshot) at AspNetCore.Reporting.LocalService.GetCompiledReport(PreviewItemContext itemContext, Boolean rebuild, ControlSnapshot& snapshot) at AspNetCore.Reporting.LocalService.CompileReport() at AspNetCore.Reporting.LocalService.AspNetCore.Reporting.ILocalProcessingHost.CompileReport() at AspNetCore.Reporting.InternalLocalReport.EnsureExecutionSession() --- End of inner exception stack trace --- at AspNetCore.Reporting.InternalLocalReport.EnsureExecutionSession() at AspNetCore.Reporting.InternalLocalReport.SetParameters(IEnumerable1 parameters)
at AspNetCore.Reporting.Report.SetParameters(ReportParameter parameter)
at AspNetCore.Reporting.LocalReport.Execute(RenderType renderType, Int32 pageIndex, Dictionary2 parameters, String findString) at BA.UI.WebV2.Extension.AspNetCoreReportingExtension.ExecuteToMemoryStreamResult(LocalReport localreport, RenderType rendertype, Int32 index, Dictionary2 parameters, String searchString) in D:\Projects\Approval\Main\BA.UI.WebV2\Extension\AspNetCoreReportingExtension.cs:line 27
at BA.UI.WebV2.Controllers.ReportsController.ReleaseProcessToPDF(DateTime from, DateTime to) in D:\Projects\Approval\Main\BA.UI.WebV2\Controllers\ReportsController.cs:line 65
at lambda_method(Closure , Object , Object[] )
at Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.SyncActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeActionMethodAsync()
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeNextActionFilterAsync()
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()
at Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.Invoke(HttpContext context)

@jfmjason: It's caused when CodeDom Code Compiler (.NET 4.0) tries to compile a few files in a temporary path in ExprHostCompiler. It wants to compile NetStandard/NetCore assemblies with the .NET 4.0 provider. That doesn't work. When it tries to compile those files, csc.exe silently fails with return value -1073741819.
Since you can't compile .NET Core code with the .NET 4.0 compiler, you need to use the RoslynCompilers, which aren't in System.CodeDom. My above NetStandardFromFileBatch fixes exactly that issue (and uses CodeDom if it compiles for NetFramework 4).

However, note that the VB runtime in .NET Core is seriously limited.
Basically, .NET Core doesn't really support VB.NET..

If you look at basic VB stuff, such as the 50 or so VB string functions, like Replace, Trim, AscW, ChrW, LCase, Len, Mid, in Microsoft.VisualBasic.Strings - .NET Core 2.0 supports exactly 2 of them, AscW and ChrW ...

If you look at the current source on github, you'll see that right now, they're there - but are all stubs which throw null.
https://github.com/dotnet/corefx/blob/master/src/Microsoft.VisualBasic/ref/Microsoft.VisualBasic.cs

So in addition to that, you might have to edit your VB code in your reports a little - to support both .NET Core and NetFramework.

So @ALL: here's an idea:
If you want your report with code running on .NET Core without modifications, start implementing the string-functions in Microsoft.VisualBasic.cs.
Or remove VB-runtime specific stuff, and try to use the classes and member functions provided with C#, such as string.Length instead of Len, IndexOf instead of InStr, Subtring instead of Mid, "BLA".ToLower() instead of LCase("BLA") etc..

Also, the VB-Code in general, not just in .NET Core, has problems with the nullable syntax ?.
So use System.Nullable(Of Double) instead of Double?, if you need to declare for example a function return value.

NuGets:
Microsoft.CodeAnalysis.Common, Microsoft.CodeAnalysis.CSharp, Microsoft.CodeAnalysis.VisualBasic

Also, you need to change the assembly references in ExprHostCompiler.cs:
(AspNetCore.ReportingServices.RdlExpressions\ExprHostCompiler.cs)

   private static System.Reflection.Assembly GetNetStdAssembly()
        {
            System.Reflection.Assembly nsAssembly = null;

            System.Reflection.AssemblyName[] asms = typeof(Microsoft.VisualBasic.Constants).Assembly.GetReferencedAssemblies();


            foreach (System.Reflection.AssemblyName asm in asms)
            {
                if (asm.FullName.StartsWith("netstandard,", System.StringComparison.OrdinalIgnoreCase))
                {
                    nsAssembly = System.Reflection.Assembly.Load(asm.FullName);
                    break;
                }
            }

            return nsAssembly;


            //System.Reflection.Assembly[] asms = System.AppDomain.CurrentDomain.GetAssemblies();
            //
            //foreach (System.Reflection.Assembly asm in asms)
            //{
            //    if (asm.FullName.StartsWith("netstandard,", System.StringComparison.OrdinalIgnoreCase))
            //    {
            //        nsAssembly = asm;
            //        break;
            //    }
            //}

            // return nsAssembly;
        }



        private byte[] InternalCompile(System.AppDomain compilationTempAppDomain, bool refusePermissions)
        {
            if (m_builder.HasExpressions)
            {
                System.CodeDom.Compiler.CompilerParameters compilerParameters = new System.CodeDom.Compiler.CompilerParameters();
                compilerParameters.OutputAssembly = System.IO.Path.Combine(System.IO.Path.GetTempPath(), m_expressionHostAssemblyHolder.ExprHostAssemblyName, "ExpressionHost.dll");
                compilerParameters.TempFiles = new System.CodeDom.Compiler.TempFileCollection(System.IO.Path.GetDirectoryName(compilerParameters.OutputAssembly));
                compilerParameters.GenerateExecutable = false;
                compilerParameters.GenerateInMemory = false;
                compilerParameters.IncludeDebugInformation = false;

                compilerParameters.ReferencedAssemblies.Add(typeof(AspNetCore.Reporting.InternalLocalReport).Assembly.Location);

                // Real reportServer
                // compilerParameters.ReferencedAssemblies.Add("System.dll");
                // compilerParameters.ReferencedAssemblies.Add(typeof(AspNetCore.ReportingServices.RdlExpressions.ExpressionHostObjectModel.ReportObjectModelProxy).Assembly.Location);
                // compilerParameters.ReferencedAssemblies.Add(typeof(Microsoft.SqlServer.Types.SqlGeography).Assembly.Location);

#if NETSTANDARD2_0

                // Assemblies: mscorlib.dll, netstandard.dll, System.Threading.Thread.dll
                // System.Threading.Thread.dll, not netstandard.dll ...
                //// compilerParameters.ReferencedAssemblies.Add(typeof(System.LocalDataStoreSlot).Assembly.Location);

                // compilerParameters.ReferencedAssemblies.Add(System.Linq.Enumerable.FirstOrDefault(System.Linq.Enumerable.Where(System.AppDomain.CurrentDomain.GetAssemblies(), (System.Reflection.Assembly t) => t.FullName.Contains("netstandard,"))).Location);

                // netstandard.dll
                compilerParameters.ReferencedAssemblies.Add(GetNetStdAssembly().Location);

                // System.Private.CoreLib.dll
                compilerParameters.ReferencedAssemblies.Add(typeof(System.MarshalByRefObject).Assembly.Location);

                // System.Runtime.dll
                compilerParameters.ReferencedAssemblies.Add(typeof(System.IO.FileAttributes).Assembly.Location);

                // Microsoft.VisualBasic.dll
                compilerParameters.ReferencedAssemblies.Add(typeof(Microsoft.VisualBasic.Constants).Assembly.Location);

                //compilerParameters.ReferencedAssemblies.Add(typeof(string).Assembly.Location);
                //compilerParameters.ReferencedAssemblies.Add(typeof(System.Uri).Assembly.Location);

                //compilerParameters.ReferencedAssemblies.Add(typeof(System.Drawing.RectangleF).Assembly.Location);
                //compilerParameters.ReferencedAssemblies.Add(typeof(System.Drawing.Graphics).Assembly.Location);

                //compilerParameters.ReferencedAssemblies.Add(typeof(System.Data.Common.DbCommand).Assembly.Location);
                //compilerParameters.ReferencedAssemblies.Add(typeof(System.Data.SqlClient.SqlCommand).Assembly.Location);

                //// compilerParameters.ReferencedAssemblies.Add(typeof(System.LocalDataStoreSlot).Assembly.Location);
#else

                // mscorlib
                compilerParameters.ReferencedAssemblies.Add(typeof(string).Assembly.Location); 

                // System.Core
                // Already contains reference to System.Core
                // compilerParameters.ReferencedAssemblies.Add(typeof(System.IO.Pipes.PipeSecurity).Assembly.Location);

                // Microsoft.CSharp
                // compilerParameters.ReferencedAssemblies.Add(typeof(Microsoft.CSharp.RuntimeBinder.RuntimeBinderException).Assembly.Location); 

                // Microsoft.VisualBasic.Constants
                compilerParameters.ReferencedAssemblies.Add(typeof(Microsoft.VisualBasic.Constants).Assembly.Location); 

                // System
                // Already contains reference to System
                // compilerParameters.ReferencedAssemblies.Add(typeof(System.Uri).Assembly.Location); 
                // Already contains reference to System.Drawing
                // compilerParameters.ReferencedAssemblies.Add(typeof(System.Drawing.Graphics).Assembly.Location);
                // Already contains reference to System.Data 
                // compilerParameters.ReferencedAssemblies.Add(typeof(System.Data.DataTable).Assembly.Location);
#endif

                compilerParameters.CompilerOptions += m_langParser.GetCompilerArguments();

@amh1979: I haven't yet looked at it, but in the paged version of the Viewer, do images in a report appear in the paged HTML rendering ?
Because when I took the html4 & 5 complete renderer from ReportServer, images seem to be delegated to an axd or ashx handler of ReportingServices. They appeared in the MHT version, however.

They should probably be changed to url("data:image/png;base64,SOME_BASE64_IMAGE"); instead, so that they are inline in the HTML.
That is to say, if they are going to a non-external link.
Didn't test if that affects the viewer as well.

@ststeiger

Thank you for the response. I wonder why it works perfectly when i publish a release version of my web application (.net core 2.1) in local IIS.

It might be that it works locally because you have the .NET Framework installed locally.
Or because your local web-server is not in integrated mode, runs under another user, or it hits another logic path, application pool settings, security settings, assembly redirects, etc..
Also, ServicePacks, CumulativeUpdates and other exciting "features".

Made a small test application.
After adding System.Drawing.Common under Win10, it works fine.
Running on Ubuntu 16.04 leads to an error.
AspNetCore.Reporting.LocalProcessingException: An error occurred during local report processing.;The definition of the report '/opt/testReportViewer/bin/Debug/netcoreapp2.1/Reports/Report1.rdlc' is invalid.
An unexpected error occurred in Report Processing.
Unable to load shared library 'kernel32.dll' or one of its dependencies. In order to help diagnose loading problems, consider setting the LD_DEBUG environment variable: libkernel32.dll: cannot open shared object file: No such file or directory ---> AspNetCore.Reporting.DefinitionInvalidException: The definition of the report '/opt/testReportViewer/bin/Debug/netcoreapp2.1/Reports/Report1.rdlc' is invalid.
An unexpected error occurred in Report Processing.
Unable to load shared library 'kernel32.dll' or one of its dependencies. In order to help diagnose loading problems, consider setting the LD_DEBUG environment variable: libkernel32.dll: cannot open shared object file: No such file or directory ---> AspNetCore.ReportingServices.ReportProcessing.ReportProcessingException: An unexpected error occurred in Report Processing.
Unable to load shared library 'kernel32.dll' or one of its dependencies. In order to help diagnose loading problems, consider setting the LD_DEBUG environment variable: libkernel32.dll: cannot open shared object file: No such file or directory ---> System.DllNotFoundException: Unable to load shared library 'kernel32.dll' or one of its dependencies. In order to help diagnose loading problems, consider setting the LD_DEBUG environment variable: libkernel32.dll: cannot open shared object file: No such file or directory
at AspNetCore.ReportingServices.ReportPublishing.ReportPublishing.InternalCreateIntermediateFormat(Stream definitionStream, String& description, String& language, ParameterInfoCollection& parameters, DataSourceInfoCollection& dataSources, DataSetInfoCollection& sharedDataSetReferences, UserLocationFlags& userReferenceLocation, ArrayList& dataSetsName, Boolean& hasExternalImages, Boolean& hasHyperlinks, Byte[]& dataSetsHash)
at AspNetCore.ReportingServices.ReportPublishing.ReportPublishing.CreateIntermediateFormat(Byte[] definition, String& description, String& language, ParameterInfoCollection& parameters, DataSourceInfoCollection& dataSources, DataSetInfoCollection& sharedDataSetReferences, UserLocationFlags& userReferenceLocation, ArrayList& dataSetsName, Boolean& hasExternalImages, Boolean& hasHyperlinks, Byte[]& dataSetsHash)
at AspNetCore.ReportingServices.ReportProcessing.ReportProcessing.CompileOdpReport(PublishingContext reportPublishingContext, PublishingErrorContext errorContext, String& reportDescription, String& reportLanguage, ParameterInfoCollection& parameters, DataSourceInfoCollection& dataSources, DataSetInfoCollection& sharedDataSetReferences, UserLocationFlags& userReferenceLocation, ArrayList& dataSetsName, Boolean& hasExternalImages, Boolean& hasHyperlinks, Byte[]& dataSetsHash)
at AspNetCore.ReportingServices.ReportProcessing.ReportProcessing.CreateIntermediateFormat(PublishingContext reportPublishingContext)
--- End of inner exception stack trace ---
at AspNetCore.ReportingServices.ReportProcessing.ReportProcessing.CreateIntermediateFormat(PublishingContext reportPublishingContext)
at AspNetCore.Reporting.ReportCompiler.CompileReport(ICatalogItemContext context, Byte[] reportDefinition, Boolean generateExpressionHostWithRefusedPermissions, ControlSnapshot& snapshot)
--- End of inner exception stack trace ---
at AspNetCore.Reporting.ReportCompiler.CompileReport(ICatalogItemContext context, Byte[] reportDefinition, Boolean generateExpressionHostWithRefusedPermissions, ControlSnapshot& snapshot)
at AspNetCore.Reporting.LocalService.GetCompiledReport(PreviewItemContext itemContext, Boolean rebuild, ControlSnapshot& snapshot)
at AspNetCore.Reporting.LocalService.CompileReport()
at AspNetCore.Reporting.LocalService.AspNetCore.Reporting.ILocalProcessingHost.CompileReport()
at AspNetCore.Reporting.InternalLocalReport.EnsureExecutionSession()
--- End of inner exception stack trace ---

@ststeiger any news on the AspNetCore.Reporting library? I've been looking for a solution for creating PDFs from RDL file on .NET Core since days and the only solution I found was AspNetCore.Reporting, which I later discovered only works on Windows and the modifications you made and reported here are very appealing, also because I'm having quite some troubles using subreports and I cannot debug the AspNetCore.Reporting without the source, which you have :) ... I'd be very interested in helping you with that library to improve the missing bits (and to finally be able to debug it...)

@OkunevPY: It's possible this is caused by one of the memory-management functions that are used to store the data-source data securely. On Linux, I just switched that off - store data unencrypted. Then it works, although it's unsafe. You have to do that in the ReportViewer-code, though. Production-grade code would have to implement an encrypt/decrypt method, which is not difficult - but I'd rather just get all the features working first,

@zillemarco;
PDF-creation doesn't work, yet (works only on Windows).
Also, if you create any application that you deploy with that reverse-engineered dll, technically you're doing something illegal.

If you need a generated a PDF on Linux, I recommend to generate it from HTML with wkHtmlToPdf.
Here's a .NET-Core variant:
https://github.com/ststeiger/libWkHtml2X
Use only the executable variant (wkhtmltopdf.exe, wkhtmltoimage.exe via input/output-stream)
libWkHtmlToX.ProcessManager(opts)
because wkhtmltox.dll doesn't work in multi-threading scenarios, plus my C# interface isn't entirely bugfree just yet.

Some usage examples (converter.telerik.com to convert to C#):

  • SVG to PDF:
Dim pngBytes As Byte() = Nothing
Dim paper_maxWidth As Double = 1024 ' pixel
Dim paper_maxHeight As Double = 768 ' pixel
Dim svgInfo As cSvgInfo = Portal_Convert.wkHtmlHelper.SvgToPaperSize(svg, paper_maxWidth, paper_maxHeight, False)

Dim opts As New libWkHtmlToX.WkHtmlToImageCommandLineOptions()
opts.ExecutableDirectory = Portal_Convert.wkHtmlHelper.GetWkHtmlToXPath()

opts.DisableSmartWidth = True
opts.ScreenWidth = System.Math.Ceiling(svgInfo.NewWidth)
opts.ScreenHeight = System.Math.Ceiling(svgInfo.NewHeight)

' svgInfo.HTML = System.IO.File.ReadAllText(System.Web.Hosting.HostingEnvironment.MapPath("~/External/1506414857353.svg"), System.Text.Encoding.UTF8)

Using p As New libWkHtmlToX.ProcessManager(opts)
    p.Start()
    p.WriteStandardInput(svgInfo.HTML)
    pngBytes = p.ReadOutputStream()

    Dim b As Boolean = p.WaitForExit(5000)
End Using ' p 
  • HTML to PDF:
        Dim opts As New libWkHtmlToX.WkHtmlToPdfCommandLineOptions()
        opts.ExecutableDirectory = Portal_Convert.wkHtmlHelper.GetWkHtmlToXPath()

        ' Dim measure As String = value.Replace(Number.ToString(), "")

        'Dim dblWidth As Double = Double.Parse(System.Text.RegularExpressions.Regex.Match(width, "[\d.]+").Value)
        'Dim dblHeight As Double = Double.Parse(System.Text.RegularExpressions.Regex.Match(height, "[\d.]+").Value)

        'If dblHeight > dblWidth Then
        '    opts.Orientation = libWkHtmlToX.Orientation_t.Portrait
        'Else
        '    opts.Orientation = libWkHtmlToX.Orientation_t.Landscape
        '    Dim x As String = width
        '    width = height
        '    height = x
        'End If

        opts.Width = width
        opts.Height = height
        opts.DisableSmartShrinking = True

        ' dpi is not working in wkhtmltopdf version 0.12.4
        ' opts.DPI = 300
        ' zoom setting with value 96/300 = 0.32
        ' opts.ZoomFactor = 96.0 / opts.DPI
        ' opts.ZoomFactor = 1.0 - 96.0 / opts.DPI
        ' opts.ZoomFactor = (1.0 / opts.DPI) / (1.0 / 96.0)
        opts.DPI = 96

        Dim pdfBytes As Byte() = Nothing

        Using p As New libWkHtmlToX.ProcessManager(opts)
            p.Start()
            p.WriteStandardInput(html)
            pdfBytes = p.ReadOutputStream()

            Dim b As Boolean = p.WaitForExit(5000)
        End Using ' p 

        Return pdfBytes

Alternatively, you can use PdfSharp for .NET-Core
https://github.com/ststeiger/PdfSharpCore

I've also ported the full PDF-library to NetStandard, which can be found here:
https://github.com/ststeiger/PdfSharpNetStandard
(if you don't need Azure-hosting, I recommend you pick PdfSharpNetStandard)

As far as ReportViewer-PDF on Linux is concerned:
You'll need to implement a lot of pinvokes first (Linux doesn't implement the Windows-API, and you can't just forward all dll-calls to wine).

I've only done GetFontData just yet, as this is the most important (font-embedding).
If you can give me your gitlab (not hub) account-name, I can give you read-access to the repository.

@ststeiger I know that deploying an app with that library would be illegal and I don't intend to do it, but with the source code I could at least be able to debug it understand why I'm not able to load a subreport and pass data to it (I've tried with resharper but it's a nightmare). If you would like to give me read access to the repo I'd love it :) My gitlab username is zillemarco (just like here on github)

@zillemarco: Added you.
You should have gotten an email from gitlab, presumably with the link to the repo.

Try ILSpy 4.0 Beta 2 instead of Resharper:
https://github.com/icsharpcode/ILSpy/releases

If you need to debug inside the .NET Framework, try live-decompile&debug with Rider, the EAP is free:
https://www.jetbrains.com/rider/eap/

@ststeiger got the email thanks :) Thanks for the tip too!

@ststeiger You can give access to the repository AspNetCore.Reporting for okunevpy?

@OkunevPY: You've been added. See mail.

@ststeiger Thanks.

        string sql = "SELECT * FROM employee";
        // sql = "SELECT * FROM T_Users";

        System.Data.DataTable dt = new System.Data.DataTable();

        using (System.Data.Common.DbDataAdapter da = new System.Data.SqlClient.SqlDataAdapter(sql, csb.ConnectionString))
        {
            da.Fill(dt);
        }

        string fn = "wwwroot/Report1.rdl";
        fn = "wwwroot/InOutTab31.rdlc";

        AspNetCore.Reporting.LocalReport lr = new AspNetCore.Reporting.LocalReport(fn);


        System.Collections.Generic.Dictionary<string, string> parameters =
            new System.Collections.Generic.Dictionary<string, string>();
        parameters["TEN_ID"]="45";
        parameters["START_DATE"]="2018";
        parameters["END_DATE"]= "2018";

        // parameters.Add("in_logo", "base64");

        lr.AddDataSource("DsDayStatusTab31", dt); // DataSet1 is the name of the DataSet in the report




        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Html, 1, null, "");

        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Rpl, 1, null, ""); // Kaboom 
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Html, 2, null, "");
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Pdf, 1, null, "");
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Excel, 1, null, "");
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.ExcelOpenXml, 1, null, "");
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Word, 1, null, "");
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.WordOpenXml, 1, null, "");
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Atom, 1, null, "");
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Xml, 1, null, "");
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Json, 1, null, "");// KABOOM 
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Csv, 1, null, "");

        var rr = lr.Execute(AspNetCore.Reporting.RenderType.Excel, 1, parameters, "");

        System.Console.WriteLine(rr.TotalPages);


        string dir = @"d:\";
        if (System.Environment.OSVersion.Platform == System.PlatformID.Unix)
            dir = "/opt/";

        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.htm"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.css"), rr.SecondaryStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.pdf"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.xls"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.xlsx"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.doc"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.docx"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.tiff"), rr.MainStream);

        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.atom.xml"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.xml"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.json"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.csv"), rr.MainStream);

        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.rpl"), rr.MainStream); // BOOM 
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.htm"), rr.MainStream);
        System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.pptx"), rr.MainStream);

        BuildWebHost(args).Run();

AspNetCore.Reporting.LocalProcessingException: 'An error occurred during local report processing.;No data is available for encoding 1252. For information on defining a custom encoding, see the documentation for the Encoding.RegisterProvider method.'

@Jhonnybmx: There's a website, called google.com, where you put in the error message, and the solution is the first link...

https://stackoverflow.com/questions/49215791/vs-code-c-sharp-system-notsupportedexception-no-data-is-available-for-encodin

System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);

Hi, I'm interesting about LocalReport on .NET Core to export rdlc report to PDF.
For me Windows only version is fine for now.

I came across NuGet package AspNetCore.ReportingServices by @amh1979 which is exactly what i need.
Problem is that InternalLocalReport class in this package is internal and I need to access whole API (like in original MS LocalReport implementation) for eq. to use SubreportProcessing event, call LoadSubreportDefinition() or GetParameters() methods.

These methods are not implemented in AspNetCore.Reporting.LocalReport class (in AspNetCore.Reporting NuGet) so I need to call them directly.

The assembly AspNetCore.ReportingServices.dll has set InternalsVisibleTo for AspNetCore.Reporting.dll assembly.
Can I somehow use that like it is in https://github.com/amh1979/Reporting/tree/master/AspNetCore.Reporting with Reporting.pfx certificate (to which I do not have a password).

Please can you help me? What is the solution for this?

@ststeiger You can give me access to the GitLab repository AspNetCore.Reporting too. My GitLab username is holajan.
Thanks

The AspNetCore.ReportingServices under this license
http://go.microsoft.com/fwlink/?LinkId=826162
I has closed it

Can someone please provide documentation/clues or hints on how to use/implement this package? Thank you very much.

@ststeiger Could you please give me access to AspNetCore.Reporting repository? I'm trying to make it work on Linux with PDF.

@holajan, @skivsoft:
Sorry, was on holidays - was a nice trip to Singapore and Thailand.
Access granted, you should have gotten an email to the address provided to gitlab.

@azharuddinsayed:

when i am trying with .rdlc file i am getting exception
AspNetCore.ReportingServices.RdlExpressions.ExpressionHostObjectModel.DataRegionExprHost(Of TMemberType, TCellType).m_memberTreeHostsRemotable' is not accessible in this context because it is 'Friend'.’.' in localreport.Execute()
please help me

I managed to reproduce that error.
The following changes are required:


ReportingServices/AspNetCore.ReportingServices.RdlExpressions.ExpressionHostObjectModel/CustomCodeProxyBase.cs

internal AspNetCore.ReportingServices.RdlExpressions.ExpressionHostObjectModel.IReportObjectModelProxyForCustomCode Report => m_reportObjectModel;
==>
internal protected AspNetCore.ReportingServices.RdlExpressions.ExpressionHostObjectModel.IReportObjectModelProxyForCustomCode Report => m_reportObjectModel;



internal CustomCodeProxyBase(AspNetCore.ReportingServices.RdlExpressions.ExpressionHostObjectModel.IReportObjectModelProxyForCustomCode reportObjectModel)
==> 
internal protected CustomCodeProxyBase(AspNetCore.ReportingServices.RdlExpressions.ExpressionHostObjectModel.IReportObjectModelProxyForCustomCode reportObjectModel)

and

ReportingServices/AspNetCore.ReportingServices.RdlExpressions.ExpressionHostObjectModel/IReportObjectModelProxyForCustomCode.cs
internal interface IReportObjectModelProxyForCustomCode
==> 
public interface IReportObjectModelProxyForCustomCode

In addition to that, the following correction in
AnyWebReporting\ReportingServices\Microsoft.VisualBasic1\VBCodeGenerator.cs

System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo("cmd.exe", "/c " + cmd)
==>
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo("cmd.exe", "/c \"" + cmd + "\"")

Then the custom code works, at least in my case.
Updated in master.

@ststeiger Thanks for the access. Do you have any idea how to render PDF on Linux? There are too much pinvokes to replace.

@skivsoft: There isn't any, yet.
You'll need to replace all the pinvokes with a freetype equivalent, which is a lot of work.

If you just need to create a PDF on Linux, you can try PdfSharpCore or PdfSharpNetStandard:
https://github.com/ststeiger/PdfSharpCore
https://github.com/ststeiger/PdfSharpNetStandard
I use both of them on Linux.
PdfSharpNetStandard is more complete, but also uses GDI+/libGDIplus, while PdfSharpCore steers clear of System.Drawing.

@ststeiger Thanks for the access to repo.

I was able to get my report working (export to PDF) in my .NET core 2.2 windows app.
I made it on copy of your ReportViewer_NetStandard project, because I removed LocalReports and changed InternalLocalReport to LocalReport and make class public (I needed access to original LocalReport API).

For my report, I fixed two problems:
Some Visual Basic expressions:
IIf - I added Import to Microsoft.VisualBasic.Interaction in _ExprHostBuilder_, Changed to netcoreapp2.2 where Microsoft.VisualBasic.Interaction class in _Microsoft.VisualBasic.dll_ is internal and added my Microsoft.VisualBasic.Interaction class to Microsoft.VisualBasic1.

Format - added Import to Microsoft.VisualBasic.StringsEx in _ExprHostBuilder_, added class Microsoft.VisualBasic.StringsEx to Microsoft.VisualBasic1 (because original class Microsoft.VisualBasic.Strings is public but without Format function)

System.Environment.NewLine - added Reference to System.Runtime.Extensions.dll in _ExprHostCompiler_.

This is these changes in code:

In AspNetCore.ReportingServices.RdlExpressions\ExprHostBuilder.cs:
AspNetCore.ReportingServices.RdlExpressions.ExprHostBuilder.GetExprHost(AspNetCore.ReportingServices.ReportIntermediateFormat.ProcessingIntermediateFormatVersion version, bool refusePermissions)
+                codeNamespace.Imports.Add(new System.CodeDom.CodeNamespaceImport("Microsoft.VisualBasic.StringsEx"));
+                codeNamespace.Imports.Add(new System.CodeDom.CodeNamespaceImport("Microsoft.VisualBasic.Interaction"));

In AspNetCore.ReportingServices.ReportProcessing\ExprHostBuilder.cs:
AspNetCore.ReportingServices.ReportProcessing.ExprHostBuilder.GetExprHost(AspNetCore.ReportingServices.ReportProcessing.IntermediateFormatVersion version, bool refusePermissions)
+                codeNamespace.Imports.Add(new System.CodeDom.CodeNamespaceImport("Microsoft.VisualBasic.StringsEx"));
+                codeNamespace.Imports.Add(new System.CodeDom.CodeNamespaceImport("Microsoft.VisualBasic.Interaction"));

In AspNetCore.ReportingServices.RdlExpressions\ExprHostCompiler.cs:
AspNetCore.ReportingServices.RdlExpressions.ExprHostCompiler.InternalCompile(System.AppDomain compilationTempAppDomain, bool refusePermissions)
+                // System.Runtime.Extensions.dll
+                compilerParameters.ReferencedAssemblies.Add(typeof(System.Environment).Assembly.Location);

Added file Microsoft.VisualBasic1\Interaction.cs:
using Microsoft.VisualBasic.CompilerServices;

namespace Microsoft.VisualBasic
{
    /// <summary>The <see langword="Interaction" /> module contains procedures used to interact with objects, applications, and systems. </summary>
    [StandardModule]
    public sealed class Interaction
    {
        public static T IIf<T>(bool condition, T truePart, T falsePart)
        {
            return !condition ? falsePart : truePart;
        }
    }
}






Added file Microsoft.VisualBasic1\StringsEx.cs in (StringsEx.zip)
Added file Microsoft.VisualBasic1\UtilsEx.cs in (StringsEx.zip)
Added file Microsoft.VisualBasic1\Information.cs in (StringsEx.zip)
Added file Microsoft.VisualBasic1\Symbols.cs in (StringsEx.zip)
Added file Microsoft.VisualBasic1\ExceptionUtils.cs in (StringsEx.zip)

StringsEx.zip

Fix Subreports with expressions:
I noticed that Subreport elements was using ReportExprHost from main report not ReportExprHost for specific subreport, so expressions on subreports was not working. I was able to find error in ReportRuntime.LoadExprHostAssembly, where ExpressionHost.dll assemblies was cached by name, but the name for all reports and subreports is always the same "_ExpressionHost_". I removed this caching.
Changes in code:

In AspNetCore.ReportingServices.RdlExpressions\ReportRuntime.cs:
-                private static readonly System.Collections.Hashtable ExpressionHosts = new System.Collections.Hashtable();

AspNetCore.ReportingServices.RdlExpressions.ReportRuntime.LoadExprHostIntoCurrentAppDomain(byte[] exprHostBytes, string exprHostAssemblyName, System.Security.Policy.Evidence evidence, bool includeParameters, bool parametersOnly, AspNetCore.ReportingServices.ReportProcessing.OnDemandReportObjectModel.OnDemandObjectModel objectModel, System.Collections.Generic.List<string> codeModules)
-                System.Reflection.Assembly assembly = LoadExprHostAssembly(exprHostBytes, exprHostAssemblyName, evidence);
+                System.Reflection.Assembly assembly = LoadExprHostAssembly(exprHostBytes);

            private static System.Reflection.Assembly LoadExprHostAssembly(byte[] exprHostBytes)
            {
                try
                {
                    new System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityPermissionFlag.ControlEvidence).Assert();
                    return System.Reflection.Assembly.Load(exprHostBytes);
                }
                finally
                {
                    System.Security.CodeAccessPermission.RevertAssert();
                }
            }

Please review these changes and if this make sense for you make those changes in you repo too.

Thank you.

@holajan: If I add System.String to the namespaces, i get:
Ambigous call to Replace - cannot resolve call
and if I add the Microsoft.VisualBasic.Interaction class, i get:
ambigous call to Microsoft.VisualBasic.Interaction
when I run it in either NetCore or .NET Framework 4.
Maybe this works only in .NET Core 2.2.

If it's caching incorrectly, then it better doesn't cache.
Agree with that change.
I put the old code into #ifdef false (instead of removing it) though.

@ststeiger I edited my comment, using for System.String was wrong, I now implemented Microsoft.VisualBasic.StringsEx instead for Format and other functions. Sorry for that.

Yes Microsoft.VisualBasic.Interaction works only in .NET Core 2.2., because class Microsoft.VisualBasic.Interaction is in Microsoft.VisualBasic.dll for .NETCoreApp v2.2 internal, in Microsoft.VisualBasic.dll for .NETCoreApp v2.09 is public but with internal method IIf.
I do not know how to solve this better, but with .NET core 3.0 it will probably be changed anyway.

@holajan: So long, let's wait 'till 3.0
I made InternalLocalReport public.
Strange name now regarding its public-ness ;)

@holajan: Added Microsoft.VisualBasic.StringsEx, now it works
Had to add IReadOnlyDictionary for .NET 4, but that just as minor remark.
Could you test if that works with you.

@ststeiger I tested it.
I must change #if false to #if true in Microsoft.VisualBasic1._Interaction.cs for IIf expression to work.
Otherwise it work fine.
Thanx

@holajan: OK, that's as it should be. maybe a define in the solution would be better.

Everyone in this thread should vote for this to be added, here: https://feedback.azure.com/forums/908035-sql-server/suggestions/33241936-develop-a-ssrs-reportviewer-for-asp-net-core

As of 2019/03 its 7th from the top most wanted Feature: https://feedback.azure.com/forums/908035-sql-server?category_id=325159

Edit: As of 2019/05 its 5th from the top

Edit: As of 2019/07 its 4th from the top

        string sql = "SELECT * FROM employee";
        // sql = "SELECT * FROM T_Users";

        System.Data.DataTable dt = new System.Data.DataTable();

        using (System.Data.Common.DbDataAdapter da = new System.Data.SqlClient.SqlDataAdapter(sql, csb.ConnectionString))
        {
            da.Fill(dt);
        }

        string fn = "wwwroot/Report1.rdl";
        fn = "wwwroot/InOutTab31.rdlc";

        AspNetCore.Reporting.LocalReport lr = new AspNetCore.Reporting.LocalReport(fn);


        System.Collections.Generic.Dictionary<string, string> parameters =
            new System.Collections.Generic.Dictionary<string, string>();
        parameters["TEN_ID"]="45";
        parameters["START_DATE"]="2018";
        parameters["END_DATE"]= "2018";

        // parameters.Add("in_logo", "base64");

        lr.AddDataSource("DsDayStatusTab31", dt); // DataSet1 is the name of the DataSet in the report




        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Html, 1, null, "");

        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Rpl, 1, null, ""); // Kaboom 
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Html, 2, null, "");
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Pdf, 1, null, "");
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Excel, 1, null, "");
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.ExcelOpenXml, 1, null, "");
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Word, 1, null, "");
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.WordOpenXml, 1, null, "");
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Atom, 1, null, "");
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Xml, 1, null, "");
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Json, 1, null, "");// KABOOM 
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Csv, 1, null, "");

        var rr = lr.Execute(AspNetCore.Reporting.RenderType.Excel, 1, parameters, "");

        System.Console.WriteLine(rr.TotalPages);


        string dir = @"d:\";
        if (System.Environment.OSVersion.Platform == System.PlatformID.Unix)
            dir = "/opt/";

        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.htm"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.css"), rr.SecondaryStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.pdf"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.xls"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.xlsx"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.doc"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.docx"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.tiff"), rr.MainStream);

        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.atom.xml"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.xml"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.json"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.csv"), rr.MainStream);

        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.rpl"), rr.MainStream); // BOOM 
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.htm"), rr.MainStream);
        System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.pptx"), rr.MainStream);

        BuildWebHost(args).Run();

AspNetCore.Reporting.LocalProcessingException: 'An error occurred during local report processing.;No data is available for encoding 1252. For information on defining a custom encoding, see the documentation for the Encoding.RegisterProvider method.'

Add below code:
System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
It solve my problem

Hi,

I have try to export report in Html using below code but it is not rendering properly.

.rdl file contains chart

I have attached screen shot of Html

Highly appreciate if you can help on us to resolve this issue.

thanks

PlatForm: ASP.NET Core

public string _reportPath = @"..\RenderReportAPI\employeeChart.rdl";

string mimtype ="";
int extension = 1;

       LocalReport localReport = new LocalReport(_reportPath);

    _dataSourceName = "DataSet1";
    _dataSourceList = Employee.GetEmployees();                                   
    localReport.AddDataSource(_dataSourceName, _dataSourceList);



    System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
    var result = localReport.Execute(RenderType.Html, extension, null, findString: mimtype);

Chart_html

@chinturathod: What does the URL of "report chart"-element show ?
The html-renderer has a secondary outputstream for CSS.
Does it contain a base64-encoded image ? Or is it just a link to an image handler ?

@ststeiger
Hi Please Find HTML and CSS below
HTML :





 
\"Report
19-03-2019 12:08:25



CSS:

"#rsoReportDiv .A97993c8d452f40d4910a317776d607f616xBc{
border:1pt none Black;
background-color:Transparent;
}

rsoReportDiv .A97993c8d452f40d4910a317776d607f616xB{

border:1pt none Black;
background-color:Transparent;

}

rsoReportDiv .A97993c8d452f40d4910a317776d607f69{

word-wrap:break-word;
word-break:break-word;
white-space:pre-wrap;
min-width:139.70mm;
overflow:hidden;
width:139.70mm;
border:1pt none Black;
background-color:Transparent;
font-style:normal;
font-family:'Segoe UI Light';
font-size:28pt;
font-weight:400;
text-decoration:none;
unicode-bidi:normal;
color:Black;
vertical-align:top;
text-align:left;

}

rsoReportDiv .A97993c8d452f40d4910a317776d607f614{

border:1pt none #d3d3d3;
background-color:White;

}

rsoReportDiv .A97993c8d452f40d4910a317776d607f65c{

border:1pt none Black;
background-color:Transparent;

}

rsoReportDiv .A97993c8d452f40d4910a317776d607f65{

min-width:152.40mm;
min-height:65.14mm;
width:152.40mm;
border:1pt none Black;
background-color:Transparent;

}

rsoReportDiv .A97993c8d452f40d4910a317776d607f63{

word-wrap:break-word;
word-break:break-word;
white-space:pre-wrap;
padding-left:2pt;
padding-top:2pt;
padding-right:2pt;
padding-bottom:2pt;
border:1pt none Black;
background-color:Transparent;
font-style:normal;
font-family:'Segoe UI';
font-size:10pt;
font-weight:400;
text-decoration:none;
unicode-bidi:normal;
color:Black;
vertical-align:top;
text-align:right;

}

rsoReportDiv .rsr1{

height:100%;
width:100%

}

rsoReportDiv .rsr2{

height:100%;
width:100%;
overflow:hidden

}

rsoReportDiv .rsr3{

height:100%

}

rsoReportDiv .rsr4{

border-style:none

}

rsoReportDiv .rsr5{

border-left-style:none

}

rsoReportDiv .rsr6{

border-right-style:none

}

rsoReportDiv .rsr7{

border-top-style:none

}

rsoReportDiv .rsr8{

border-bottom-style:none

}

rsoReportDiv .rsr10{

border-collapse:collapse

}

rsoReportDiv .rsr9{

border-collapse:collapse;
table-layout:fixed

}

rsoReportDiv .rsr11{

width:100%;
overflow-x:hidden

}

rsoReportDiv .rsr12{

position:absolute;
display:none;
background-color:white;
border:1px solid black;

}

rsoReportDiv .rsr13{

text-decoration:none;
color:black;
cursor:pointer;

}

rsoReportDiv .rsr14{

font-size:0pt

}

rsoReportDiv .rsr15{

direction:RTL;
unicode-bidi:embed

}

rsoReportDiv .rsr16{

margin-top:0pt;
margin-bottom:0pt

}

rsoReportDiv .rsr17{

height:100%;
width:100%;
display:inline-table

}

rsoReportDiv .rsr18{

height:100%;
display:inline-table

}

rsoReportDiv * {

 box-sizing: border-box;

}

Report chart element
Report chart
i think this error causes the problem

Thanks..

@ststeiger

Hi Any Update?

@chinturathod:
I'm currently working CEF-pdf as wkhtml2X replacement, and on SwissRe Reports.

I'll have time to look into this project in over two week, at the earliest.

Is there a repository (private or otherwise) for the AspNetCore.ReportingServices package that I could be granted access to?

@clintb: I need your gitLAB accountname, so I can grant you access.
You'll then receive an e-mail to the email address of the gitlab account containing the repo access .

Hey Stefan, my gitLab is c_l_i_n_t. Thanks!

On Fri, Apr 26, 2019 at 12:18 PM Stefan Steiger notifications@github.com
wrote:

@clintb https://github.com/clintb: I need your gitLAB accountname, so
I can grant you access.
You'll then receive an e-mail to the email address of the gitlab
account containing the repo access .


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/aspnet/AspNetCore/issues/1528#issuecomment-487133308,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ABURO5ILQUEGMZARNW2HNALPSM2M5ANCNFSM4CFRN7MQ
.

@clintb: You've been added.

Hi @ststeiger, if you will, please grant repo access to lotsatrees. Thanks for your work and help.

@lotsatrees: You've been added.

Thanks Stefan, glad to buy you a good beer any time.

Hi @ststeiger , my gitlab is edgardoreyes. Thanks so much.

@ststeiger
My gitlab is ikourfaln
Thank you

@ikourfaln, @edgardoreyes: Added you two; you should have received an email to the mail account you registered with gitlab.

@ststeiger, would it be possible to also add myself (Mhirji on gitlab)?

Thanks!!

@Mhirji: Done.

Thanks!!!

Why not just creating a Report Server Project and use that as a service for whatever project type?
Your ASP.NET Core project will only need the URL of the report service to show reports.
Any problem with that approach?

@ststeiger can i get access as well? (ConstantDisaster on gitlab) thanks in advance

@ConstantDisaster: Added.
@mshwf: No, actually that's exactly what I want to do - so we can run reports in our own application, and no reportserver needed (always a problem with windows authentication - for some reasons IT departments are incapable of adding new users to a group - plus always a problem with uninstalled service packs, unwilling to update to latest SQL-server version because customers want to skip a version, rendering inconsistencies between ReportViewer and ReportServer, our own sysadmin too lazy to install anything, etc. ). Just lacking time, as always. Plus it's the first sunny days of summer, here in North-Western Europe, and I don't want to miss them.

@ststeiger Is there better alternatives? (I tried reading this thread, but it's very long!)
also could you grant me access to the GitLab repo (mshwf)?
thanks

Please support this request, hopefully Microsoft listen to us!

Hey @ststeiger would you add me as well?
My gitlab username is k3flo
Thank you so much
Vielen Dank 😊

@ststeiger thanks for adding, so how do i start using this again? in an asp net core project? thought it had a readme or something, thanks again.

@ConstantDisaster: There is an "example", in AnyWebReporting\Any_TestCode\TestReport.cs.
It shows how to render a report with parameters and datasets into a PDF.

In a nutshell:
1) Create a dictionary for report parameters:

System.Collections.Generic.Dictionary<string, string> parameters =
                new System.Collections.Generic.Dictionary<string, string>();

2) Add all parameters that you have in your report to the dictionary, e.g.

parameters.Add("in_language", "DE");
parameters.Add("in_something_uid", "9A892D4B-B4E3-4804-AAB6-97EAB37B7849");

3) Create a new LocalReport based and load report

string fn = "/full/path/to/SomeReport.rdl";
AspNetCore.Reporting.LocalReport lr = new AspNetCore.Reporting.LocalReport(fn);

Then, for all datasets that are only used in parameters, you can add an empty datatable (not NULL)
lr.AddDataSource("SEL_Standort", new System.Data.DataTable());

And for every dataset that is used, you need to fill a datatable with the result of the query for that dataset, and add the dataset to the datasources:

lr.AddDataSource("DATA_Schluesselbestandeskontrolle", dt);

Then, you can execute the report, fetch the result, and write it somewhere, e.g. drive d:

var rr = lr.Execute(AspNetCore.Reporting.RenderType.Pdf, 1, parameters, "");
System.IO.File.WriteAllBytes(System.IO.Path.Combine(@"d:\", "Bestandeskontrolle.pdf"), rr.MainStream);

I've added an example HTML page which mimics the design of the ReportViewer 2014&2017 report interface, that I had in a draft-version. If you fetch again from git, you'll find it in:

AnyWebReporting\AnyWebReporting\wwwroot
AnyWebReporting/AnyWebReporting/wwwroot/index.htm
AnyWebReporting/AnyWebReporting/wwwroot/index2014.htm
AnyWebReporting/AnyWebReporting/wwwroot/logon.htm

And that's it.
If you need to display the report in the web, you can render to html by passing the respective Enum to in lr.Execute (RenderType.HTML5_0 or HTML4_0 or Mhtml), and pass the correct page number. The result (HTML) is in MainStream, and the CSS is in SecondaryStream.

However, connecting the index.htm of ReportViewer with lr.Execute by JavaScript, you need to do yourself, for the moment. Didn't get around to doing that just yet. For now, I need it for generating PDFs to append to emails.

@k3flo @mshwf: Added.

@mshwf:

@ststeiger Is there better alternatives? (I tried reading this thread, but it's very long!)

Not to my knowledge, otherwise I'd be using it.
Maybe we will see something in this regard after the .NET Core 3.1 release (LTS), because then the road would be free to create a windows-only ReportViewer based on .NET Core.

However, such a thing would be just as much a bricolage as this project, so maybe they'll take the time to remove all the System.Drawing (and WinAPI calls to GDI+) code, and do it properly, that is to say, cross-platform. Though in my opinion, this is unlikely. Not unhappy to be positively surprised though (cough).

The thing is that Reports can contain VB-code, and VB support in .NET Core (<3) is, at present, questionable - at best. This will be (=should theoretically be) rectified by .NET Core 3, and if they make a ReportViewer, they'll most likely wait until the LTS release, at least.

@mshwf:
You don't need to read this entire thread.
All you need to do is git-clone the project and see the example report (you won't have the database to run it, though).

Could you add me on gitlab please?
dcga

@dcga: Added.

Hi, Could you add me on your gitlab? I am converting report to ASP.net Core project now.

@ericyu67: I suppose your gitlab account name is ericyu ? In that case you were added.

That's correct, thank you.

@ststeiger could you add me please?
rodrigorrl

@rodrigorrl: added.

@ststeiger could you add me please ?

@myersBR: Done.

@ststeiger can you add me please?

@acofalc: Added @aco.mit

Hi, @ststeiger please add me: oblin228, thanks.

Any news on this? I am using ASP.NET Core and I refuse going back to webforms. I have a reports project and i feed the url from report server to my application to download the file. The problem is that it constantly asks for windows authentication and i would like to avoid this...

@oblin: Added.

@jfcaldeira: As long as you run the application on Windows, the reportviewer on gitlab should work, more or less (open problem with images in HTML-output, so far). Run it on Linux, and it should work as long as you don't use PDF, TIFF or PowerPoint as output format (don't know about word), but Excel, html, xml, and json worked on Linux, too (in my 1-report test - can't say whether nothing explodes if you use the full feature-set).

But if your problem is Windows-authentication on SSRS, why don't you use custom-security (aka. SSRS forms authentication).

For that, see here:
https://www.codeproject.com/Articles/675943/SSRS-2012-Forms-Authentication
https://github.com/ststeiger/SSRS-Localizer
https://github.com/ststeiger/CustomHttpHeaders
https://github.com/microsoft/Reporting-Services/tree/master/CustomSecuritySample

You might need to log the user in with a Form-Post in JavaScript, and set a P3P-policy (in SSRS via http module) in order for the SSRS-auth-cookie to persist in IE accross domains... (note: if you use virtual directories, and have 2 applications on one SSRS, the auth-cookie from application1 [which is on the SSRS-domain] will overwrite the auth-cookie of application2, which is also on the SSRS-domain)

@oblin: Added.

@jfcaldeira: As long as you run the application on Windows, the reportviewer on gitlab should work, more or less (open problem with images in HTML-output, so far). Run it on Linux, and it should work as long as you don't use PDF, TIFF or PowerPoint as output format (don't know about word), but Excel, html, xml, and json worked on Linux, too (in my 1-report test - can't say whether nothing explodes if you use the full feature-set).

But if your problem is Windows-authentication on SSRS, why don't you use custom-security (aka. SSRS forms authentication).

For that, see here:
https://www.codeproject.com/Articles/675943/SSRS-2012-Forms-Authentication
https://github.com/ststeiger/SSRS-Localizer
https://github.com/ststeiger/CustomHttpHeaders
https://github.com/microsoft/Reporting-Services/tree/master/CustomSecuritySample

You might need to log the user in with a Form-Post in JavaScript, and set a P3P-policy (in SSRS via http module) in order for the SSRS-auth-cookie to persist in IE accross domains... (note: if you use virtual directories, and have 2 applications on one SSRS, the auth-cookie from application1 [which is on the SSRS-domain] will overwrite the auth-cookie of application2, which is also on the SSRS-domain)

Hello, thank you for replying about my issue. I haven't heard of this reportviewer on gitlab, can you show me an anchor to it?

And about the windows authentication, the problem is that I have the user authenticated using cookie authentication on my applications in ASP.NET Core and the workaround to get users to access the report is basically pass the direct URL with parameters to the href of an anchor and choose PDF as format on it as well. I was trying to find a way to not ask authentication to the user because it is annoying to the end-user having to authenticate twice. i am already using a specific account just for datasource access, that's one down.

Hi, @ststeiger - my gitlab is arunputhran. Can you grant me access please? many thanks!

Reposting this because its gotten buried in all the "give me access to gitlab" requests.

Everyone coming across this thread should vote for .NET Core SSRS this to be added, here: https://feedback.azure.com/forums/908035-sql-server/suggestions/33241936-develop-a-ssrs-reportviewer-for-asp-net-core

Started 7th from the top, and it has risen to 4th from the top, most requested SQL Server feature (https://feedback.azure.com/forums/908035-sql-server?category_id=325159)

Edit: Because of this post its up to 3rd place now

Not sure if it even helps though...

@arunputhrankyc: Added.

@k290: Nah, as you can see, a Dark Theme for SQL Server Management Studio 2017 is clearly more important :scream: :man_facepalming: :woman_facepalming:
Apparently, they have not yet heard about SQL-ops-studio/AzureDataStudio.

I think, in that spirit, somebody should add flat design to that wish list, just as a joke.
Sadly, it's not April 1st just yet :wink:

by the way i get reports as a pdf from a web api and i do not use any wcf bits.
just soap/asmx calls and http calls.
in doing them i pass credentails w/o any problems.
my code is asp.net 4.6 / web api 2
if you want to see what i do i can put some code up on a github next week for you to check out.
i am calling report server 2016 but most of what i am doing will work with the older ssrs releases.

Hello, I read this comment of yours how you are handling SSRS. I'm doing something similar as well, I have an anchor in an ASP.NET Core application that has the URL directly to the report with parameters included and the format extension. However the issue is that it asks for windows authentication. Is there a way to stop asking this since users already logged on my app using cookie authentication? I don't even care about showing the report as long it is downloaded but would be nice to skip authentication

@arunputhrankyc: Added.

@k290: Nah, as you can see, a Dark Theme for SQL Server Management Studio 2017 is clearly more important 😱 🤦‍♂ 🤦‍♀
Apparently, they have not yet heard about SQL-ops-studio/AzureDataStudio.

I think, in that spirit, somebody should add flat design to that wish list, just as a joke.
Sadly, it's not April 1st just yet 😉

Well i would kill for a dark theme for SSMS for sure but i would eat my bare hands for that SSRS. The amount of work saved by rendering grouped data on it directly from SQL is amazing.

Great solution, please add me in gitlab: @kholossok, thanks

Please add me too in gitlab: @EMaderbacher

@kholossok, @EMaderbacher: Added.

Add me too please @jfcaldeira

@jfcaldeira: You need to give me a gitlab account.
This is a github account.
It's free. https://gitlab.com
Private repositories weren't free on github at the time.

@ststeiger
Private repositories are free now on GitHub, the limitation is on the number of collaborators.

@jfcaldeira: You need to give me a gitlab account.
This is a github account.
It's free. https://gitlab.com
Private repositories weren't free on github at the time.

I have created an account with same username

@jfcaldeira: Added. You should have gotten an email with the access information.
@ikourfaln: I know. Didn't know there was a limitation to 3 collaborators in github private repos, though. Good to know that, thanks.

Gitlab limitations:

To celebrate today's good news we've permanently raised our storage limit per repository on GitLab.com from 5GB to 10GB. As before, public and private repositories on GitLab.com are unlimited, don't have a transfer limit and they include unlimited collaborators.

May I please be added too? My GitLab account is barryjsilver. Thanks!

Can I please be added please? @jyanosu Thank you!

@BarryJSilver: Added.

@jyanosu: i need the gitlab.com account, not github.

@ststeiger Whoops, just set it up.. same username @jyanosu

@jyanosu: Added.

@ststeiger can you add my gitlab account @kanichi123
Thank you!

@kanichi123: Added.

@ststeiger please my account too sheryever

@sheryever: Added.

@ststeiger please can you add my gitlab account @PentaTech
Thank you!

@ststeiger could you add me as well? @glebteterin
Thank you!

@PentaTech, @g-rad: added.

@ststeiger good effort on this, could you please add gitlab account brad0000?

@brad0000: Done.

Hi @ststeiger , could you add me as well? gitlab account: wyepez. thanks

@wyepez: Added.

@ststeiger Can you please add me as well?

Gitlab username: choudeshell

@choudeshell: Added.

Can you please add me? Thanks!

Does your solution work with .rdlc (as well as server side .rld)? Thanks

Does your solution work with .rdlc (as well as server side .rld)? Thanks

@mpirritano: Yes, in fact, there's not much difference between RDL and RDLC.
But it's web only. No Windows-Forms.
I need a gitlab account to add you, not github.

@ststeiger Thanks - I've created a GitLab account now :@mdpirrit

That's great - I only need it for ASP .NET Core targeting .NET Core. Thanks!

@mpirritano: Added, you should have gotten an email to the email account you used to register gitlab.

Got it; thanks!

@ststeiger it works great except it can't render Charts. - it renders the chart area with the error :"Could not load file or assembly "System.Windows.Forms, Version=4.0.0.0"

Is this a known limitation or am I missing something?

Thanks

@ststeiger Also, it doesn't appear as if subreports are supported. i.e. there doesn't appear to be a subreport processing eventhandler to add data sources to the subreport instance

Thanks

Can you please add me? Thanks! @ashabyralieva

Работает ли ваше решение с .rdlc (а также со стороны сервера .rld)? Спасибо

@mpirritano : Да, на самом деле, между RDL и RDLC нет большой разницы.
Но это только сеть. Нет Windows-форм.
Мне нужна учетная запись Git Lab, чтобы добавить вас, а не GitHub.

Можете ли вы добавить меня? Спасибо! @ashabyralieva

@azikaa: Done. Добавлено;)

@mpirritano:

Is this a known limitation or am I missing something?

Yea, one limitation I was aware of that it could exist.
And also, it has a problem with image output in HTML.
Open points.
I didn't even think of subreports just yet.
Sadly, we have a few of them, too, so this will be my problem as well.
Speaking of it, I don't even know how subreports are handled in the normal ReportViewer on the full framework, specially as they can be recursive.

Probably it has a problem somewhere, because "System.Windows.Forms, Version=4.0.0.0" doesn't exist in that version in .NET Core, and also, the assembly is called System.NetStandard.Forms instead in the ReportViewer for .NET Core. Might work on full framework, because there System.Windows.Forms, Version=4.0.0.0 does exists.

The problem with System.Windows.Forms can probably be rectified as easily as putting the assembly-name and version (wherever it hides in the sourcecode) into an ifdef, the subreports rather not I guess.

I still have to finish a report-sending service this week, so I might be able to look at the System.Windows.Forms issue some time next week.

As far as subreports go: they are a bad idea anyway, tend to create problems with PDF and Excel, and in case you have just 1 report, I'd recommend to see if it isn't somehow possible to eliminate the subreport altogether somehow, and make everything contained in one report.

Добавлено
How to get database COR_Basic_SwissLife_UAT?

:rofl: Haha, good one, you don't, that DB is confidential.
But you can make your own example report, using your own database.
You should see from the example how to use it.

@ststeiger Thanks. Actually, I see that there is SubreportProcessing event defined in AsNetCore.Reporting.InternalLocalReport. I may try creating a public interface for this and see if I can pass data sources to subreport intances. I may not get to this until next week as well...

I try to avoid Subreports as well, but I've found them necessary in cases were you need a repeating section within a repeating section. With regards to Excel, it's possible to render each subreport instance as a worksheet in excel with rdlc/rdl

Reposting this for newcomers.

Everyone in this thread should vote for this to be added, here: https://feedback.azure.com/forums/908035-sql-server/suggestions/33241936-develop-a-ssrs-reportviewer-for-asp-net-core

In March of this year it was 7th from the top.

Now, we've got it up to 2nd from the top of the SQL Server suggestions: https://feedback.azure.com/forums/908035-sql-server?category_id=325159

Can we beat Dark Mode?

@ststeiger I actually had a little time today and was able to successfully render reports with subreports in .docx, .xlsx, and .pdf.

As a quick test on my local copy - I changed the access modifier of the "localReport" property of the "LocalReport" class from "internal" to "public". Then I could write a handler for the "SubreportProcessing" event as I always would (where I would read the value of the parameter to the subreport instance and use it to filter a dataset that I would pass into the datasource of the subreport instance)

I have no idea how to fix the chart rendering issue with .NET Core; so if you ever able to reach a solution that would be amazing. But other than that, I think your solution does everything I need it to do (I personally never render reports in HTML format)

Thanks

export- word, excel not woking ?
FormatException: The header contains invalid values at index 0: ''

the service is very slow. what can be done? Please help....

Hey everyone, I just finished writing a custom port of the report viewer control using the ReportExecutionService.asmx that's built into SSRS and I was targeting ASP.NET MVC. I had someone suggest porting it to .NetCore & MVC so I have completed that. Give it a try and let me know what you guys think: https://github.com/alanjuden/MvcReportViewer

Alan

export- word, excel not woking ?
FormatException: The header contains invalid values at index 0: ''

the service is very slow. what can be done? Please help....

@azikaa: Are you using MvcReportViewer, or AspNetCore.ReportViewer ?

We're closing this issue as it's not directly relevant to this repo and based on the comments here the SSRS team is already aware of this feedback. Given the amount of comments this has got it's now unmanageable.

@k290 's response is the most actionable one here, so please follow his suggestion here:

Reposting this for newcomers.

Everyone in this thread should vote for this to be added, here: https://feedback.azure.com/forums/908035-sql-server/suggestions/33241936-develop-a-ssrs-reportviewer-for-asp-net-core

In March of this year it was 7th from the top.

Now, we've got it up to 2nd from the top of the SQL Server suggestions: https://feedback.azure.com/forums/908035-sql-server?category_id=325159

Can we beat Dark Mode?

Was this page helpful?
0 / 5 - 0 ratings