Asp.Net Core Reporting (SSRS)
KerolosMalak opened this issue · 269 comments
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
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 ilich/MvcReportViewer#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
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
@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: aspnet/Mvc#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 ?
Yes the forum is
https://social.msdn.microsoft.com/Forums/sqlserver/en-US/home?forum=sqlreportingservices
also you can check our blog
https://blogs.msdn.microsoft.com/sqlrsteamblog/
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:
#1528 (comment)
@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. alanjuden/MvcReportViewer#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.
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.
Please vote for this issue at https://feedback.azure.com/forums/908035-sql-server/suggestions/33241936-develop-a-ssrs-reportviewer-for-asp-net-core
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.
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.
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.