My app is a blazor Web assembly hosted app.
I created a component, DisplayReport, which can access to the server project, and get an HTML which is displayed by the component.
Here is the razor page of the component:
#inject HttpClient HttpClient
<div style="#Style" class="#Class">
#HTMLText
</div>
Here is the method which calls the server:
protected override async Task OnParametersSetAsync()
{
if (!IsSet && Speciality != null)
{
IsSet = true;
IsLoading = true;
Dashboard.Refresh();
URL = $"?%2fSSRS%2f{Report}&rc:Section={Section}&rs:Command=Embed&rs:Format=MHTML&HospitalParam={{{Speciality.Service.Site.Hospital.Id.ToString().ToUpper()}}}&SiteParam={{{Speciality.Service.Site.Id.ToString().ToUpper()}}}&ServiceParam={{{Speciality.Service.Id.ToString().ToUpper()}}}&SpecialityParam={{{Speciality.Id.ToString().ToUpper()}}}&Cohort={Cohort}";
HttpResponseMessage response = await HttpClient.PostAsJsonAsync("Dashboard/GetReport", URL);
if (response.IsSuccessStatusCode)
{
byte[] byteArray = response.Content.ReadAsByteArrayAsync().Result;
string result_string = Encoding.UTF8.GetString(byteArray, 0, byteArray.Length);
HTMLText = (MarkupString)result_string;
}
IsLoading = false;
if (!IsLoaded)
Dashboard.NumberDisplayReportsLoaded += 1;
IsLoaded = true;
Dashboard.Refresh();
}
}
No need to expplain it a lot, it does a POST Http request, and stores the HTML in the variable HTMLText, as a MarkupString.
There are in the main razor page a lot of DisplayReports, which display the HTML got from SSRS(the calls to SSRS are performed by the controller in the server, method GetReport).
Individually, each DisplayReport is displayed right, but I noticed that when they are all in the page, there is bugs in the display, like this:
The blue color is added when an other DisplayReport is displayed: with the second DisplayReport(DR) there is the bug, without there isn't.
Many reports are in the same case: there are bugs in the display when an other is displayed.
I made some tests, and saw that if the other DR is only loaded but not displayed(with Style="display:none"), the bug remains. When the first DR, the one that has bugs, is in the first in the page, the problem remains(it seems independant of the order).
Here is an other bug in an other DR(same problem):
The world 'TRANSFUSION' should be like 'PRATIQUES POST-OPERATOIRES'.
Here is the DR tag, for the GHM table:
<DisplayReport Dashboard="this" #ref="SyntheseGHM" Report="GHM" Section="1" Speciality="#LocalizationBanner.SelectedSpeciality" Cohort="#Tools.Snapshot" Style="width: 640px; height: 600px"/>
There are 24 DR loaded at the same time, but obviously each DR has its own HTMLText.
I can't see why there are such issues.
thank you.
EDIT
Here is the HTMLText value of a DR:
'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
>\n<html>\r\n<head><title>KPIs</title>\r\n<META http-equiv="Content-Type" content="text/html; charset=utf-8"/><META http-equiv="Content-Style-Type" content="text/css"/><META http-equiv="Content-Script-Type" content="text/javascript"/><META HTTP-EQUIV="Location" CONTENT="http://my-pc:80/reports?%2FSSRS%2FKPIs"/><META HTTP-EQUIV="Uri" CONTENT="http://my-pc:80/reports?%2FSSRS%2FKPIs"/><META HTTP-EQUIV="Last-Modified" …OLSPAN="12" style="WIDTH:71.12mm;min-width: 71.12mm;"></TD><TD COLSPAN="17" style="WIDTH:104.10mm;min-width: 104.10mm;"><TABLE CELLSPACING="0" CELLPADDING="0" BORDER="0" style="WIDTH:104.28mm;min-width:
104.28mm;HEIGHT:0.26mm;" class="a46"><TR><TD style="HEIGHT:0.26mm;WIDTH:104.28mm;min-width:
104.28mm;font-size:1pt"> </TD></TR></TABLE></TD></TR></TABLE></TD></TR></TABLE></TD><TD WIDTH="100%" HEIGHT="0"></TD></TR><TR><TD WIDTH="0" HEIGHT="100%"></TD></TR></TABLE></DIV></DIV></body></html>'
I think the problem should be the HTML from SSRS inserted "directly" in the page.
For this kind of situation, when you have some HTML code with a full declaration (like the piece of code you reported), I think it's better to use an iframe tag in order to isolate this HTML inside your page.
You can use the iframe syntax like:
<iframe src="some HTTP Url">...
or the HTML 5 srcdoc:
<iframe srcdoc='<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
...
srcdoc is fully compatible with latest browsers.
For a complete compatibility reference look at:
https://caniuse.com/mdn-html_elements_iframe_srcdoc
Related
I have a PDF file as a bytes array and I want to display it into <object element in .NET MAUI hybrid application.
I tried it on windows and it works fine, but on Android it doesn't work, it shows blank white content. I didn't try on iOS because it doesn't available for me right now.
I tried to display the PDF file from URL in <iframe but it also works on Windows only, but it shows blank content on android
My code:
<div style="border:1px solid red;padding:10px;">
<iframe style="width:100%;height:600px;" src="#bookPath"></iframe>
</div>
<div style="border:1px solid orange;padding:10px;">
<object data="#bytesText" width="900" height="600" type="application/pdf"></object>
</div>
#code{
string bytesText = string.Empty;
private string bookPath= "https://my-url/book_1.pdf";
protected override async Task OnInitializedAsync()
{
var bytes = await (await Http.GetStreamAsync("api/book/bytes")).ToByteArrayAsync();
bytesText = $"data:application/pdf;base64,{Convert.ToBase64String(bytes)}";
}
}
So, any ideas about this problem?
Thank you
I have several pages on a website that use the same header for each page. I was wondering if there was some way to simply reference a file with the html for the header sort of like in this pseudo code:
<!-- Main Page -->
<body>
<html_import_element src = "myheadertemplate.html">
<body>
Then in a separate file:
<!-- my header template html -->
<div>
<h1>This is my header</h1>
<div id = "navbar">
<div class = "Tab">Home</div>
<div class = "Tab">Contact</div>
</div>
</div>
This way I could write the header html once and just import it in each of my pages where I need it by writing one simple tag. Is this possible? Can I do this with XML?
You could do it in this fashion below.
<head>
<link rel="import" href="myheadertemplate.html">
</head>
where you could have your myheadertemplate.html
<div>
<h1>This is my header</h1>
<div id = "navbar">
<div class = "Tab">Home</div>
<div class = "Tab">Contact</div>
</div>
</div>
You can then use it with JS below
var content = document.querySelector('link[rel="import"]').import;
So, after a long time I actually found a way to do this using AJAX. HTML Imports are a great solution, but the support across browsers is severely lacking as of 04/2017, so I came up with a better solution. Here's my source code:
function HTMLImporter() {}
HTMLImporter.import = function (url) {
var error, http_request, load, script;
script =
document.currentScript || document.scripts[document.scripts.length - 1];
load = function (event) {
var attribute, index, index1, new_script, old_script, scripts, wrapper;
wrapper = document.createElement("div");
wrapper.innerHTML = this.responseText;
scripts = wrapper.getElementsByTagName("SCRIPT");
for (index = scripts.length - 1; index > -1; --index) {
old_script = scripts[index];
new_script = document.createElement("script");
new_script.innerHTML = old_script.innerHTML;
for (index1 = old_script.attributes.length - 1; index1 > -1; --index1) {
attribute = old_script.attributes[index1];
new_script.setAttribute(attribute.name, attribute.value);
}
old_script.parentNode.replaceChild(new_script, old_script);
}
while (wrapper.firstChild) {
script.parentNode.insertBefore(
wrapper.removeChild(wrapper.firstChild),
script
);
}
script.parentNode.removeChild(script);
this.removeEventListener("error", error);
this.removeEventListener("load", load);
};
error = function (event) {
this.removeEventListener("error", error);
this.removeEventListener("load", load);
alert("there was an error!");
};
http_request = new XMLHttpRequest();
http_request.addEventListener("error", error);
http_request.addEventListener("load", load);
http_request.open("GET", url);
http_request.send();
};
Now when I want to import HTML into another document, all I have to do is add a script tag like this:
<script>HTMLImporter.import("my-template.html");</script>
My function will actually replace the script tag used to call the import with the contents of my-template.html and it will execute any scripts found in the template. No special format is required for the template, just write the HTML you want to appear in your code.
As far as I know it's not possible. You can load the header as a webpage in a iframe element though. In the past webpages were built with frame elements to load seperate parts of a webpage, this is not recommended and support in current browsers is due to legacy.
In most cases this is done with server side languages like php with as example include("header.php");.
I have a svg.html file where the svg content are defined within a element.
I've been combing the Internet for 3 days now, have not found a solution as to why the icons I use don't show up on the rendered .aspx web pages. svg.html looks like this:
<div class="svg-icons">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" class="svg-icons">
<symbol id="icon-menu" viewBox="0 0 18 18">
<path d="##path value##"></path>
</symbol>
</svg>
</div>
I have tried the following:
using the <object></object> tags referring to svg.html.
<use> tags.
In web.config <mimeMap fileExtension=".svg" mimeType="image/svg+xml" />
What am I doing wrong?
Please note that I cannot change the svg.html file, and this is an ASP.Net web forms project.
If you have complete markup inside html file containing SVG image, you can place a literal control & assign the HTML page contents from code behind by stripping unnecessary markups with regex:
ASPX
<asp:Literal ID="placeholder" runat="server" />
Code-behind
protected void Page_Load(object sender, EventArgs e)
{
string html;
using (StreamReader sr = File.OpenText(Server.MapPath("~/path_to_html_file.html"))
{
html = sr.ReadToEnd();
sr.Close();
}
Regex start = new Regex(#"[\s\S]*<body[^<]*>", RegexOptions.IgnoreCase);
html = start.Replace(html, "");
Regex end = new Regex(#"</body[\s\S]*", RegexOptions.IgnoreCase);
html = end.Replace(html, "");
placeholder.Text = html;
}
If you have raw SVG file and want to use it in literal tag element, you can simply use <iframe src="/path_to_SVG_file.svg" />/<embed src="/path_to_SVG_file.svg" /> inside user control, or a div assigned with InnerHtml attribute:
ASPX
<div id="placeholder" runat="server"></div>
Code-behind
placeholder.InnerHtml = File.ReadAllText(Server.MapPath("~/path_to_SVG_file.svg"));
References:
Include contents of an html page in an aspx page
Interactive Mapping Using SVG & ASP.NET
thanks in advance for any help you can offer. I have been digging through the various posts here on SO trying to solve a missing page break issue. I have a number of cshtml templates that are rendered using a Razor template engine to produce an RTF file. When the file is opened in Word it completely dumps the html that contains the "break" style used to make a page break. The rest of the template renders exactly as designed. I am thinking that maybe my problem is I'm not rendering out the file correctly in the first place.
Sample .cshtml file starts with:
<div style="width: 100%;" class="newpage">
<p align="center" style="text-align:center">NOTICE</p>
<table>
....middle html content....
</table>
<p class="newpage"></p>
</div>
I've tried putting the page break at the beginning and the end just to see if it made any difference and it didn't.
The razor call that gets the .cshtml file is like this:
newNotice.Body = RazorEngine.Razor.Parse(Notifications.GetTemplate(NotificationTemplate.MyTemplate2), data, NotificationTemplate.MyTemplate2.ToString());
return newNotice;
Then I render out the RTF file in the following code where the style for the page break exists:
protected void ProduceNotification(Notification notice, string title)
{
Response.Clear();
Response.Buffer = true;
Response.AddHeader("content-disposition", "attachment;filename=" + title);
Response.ContentType = "application/rtf";
EnableViewState = false;
var stringWrite = new StringWriter();
var sb = new StringBuilder();
sb.Append(#"<html>
<head>
<title></title>
<style type='text/css'>
.body {
margin: 5em;
background-color: white;
width: 100%;
height: 100%;
font-family: Calibri;
}
.spacing {
line-height: 1.5em;
}
.newpage {
mso-special-character:line-break;
page-break-before:always;
clear: both;
}
</style>
</head><body>");
sb.Append(notice.Body);
sb.Append("</body></html>");
stringWrite.WriteLine(sb);
ClearChildControlState();
Response.Write(stringWrite.ToString());
Response.End();
}
When I open up the file in Word, the page breaks are not being respected so I saved the file to .html to see what the mark up looks like and here's what I see:
In the style definition section it shows the style:
p.newpage, li.newpage, div.newpage
{mso-style-name:break;
mso-style-unhide:no;
mso-margin-top-alt:auto;
margin-right:0in;
mso-margin-bottom-alt:auto;
margin-left:0in;
page-break-before:always;
mso-pagination:widow-orphan;
font-size:12.0pt;
font-family:"Times New Roman","serif";
mso-fareast-font-family:"Times New Roman";
mso-fareast-theme-font:minor-fareast;}
But in the document where the html should show the element with the class on it, it looks like this instead (this is in the middle of the html output):
<div>
<p align=center style='text-align:center'>NOTICE </p>
<table>
......middle html content.....
</table>
</div>
Notice that the style and class are missing from the div tag and the p tag is missing all together. What I can't figure out is, is the conversion to RTF deleting these for some reason or is it the Razor Templating Engine that's stripping out the text? I've also tried changing this to output an .doc format also but the result has been the same.
So the aggravating answer also turned out to be the simplest one. The style was applying to p, li, or div elements but only if the element has some kind of content:
<div class='newpage'> </div>
As long as I used one of the correct elements, it works as long as there is some kind of content (in this case just a space). Once I had it working, I also had to address the issue of it adding an extra blank page to the output since originally I had the line in the cshtml file itself. Instead I moved it to the code behind.
I created a var to hold the last list item, as demonstrated in this SO post here.
var lastItem = myList.Last();
foreach(var d in myList)
{
newNotice.Body += RazorEngine.Razor.Parse(Notifications.GetTemplate(NotificationTemplate.MyTemplate2), data, NotificationTemplate.MyTemplate2.ToString());
if(!ReferenceEquals(d, lastItem))
newNotice.Body += "<div class='newpage'> </div>";
}
Following is my html content which i want to show in the webview using android sdk. It will displays only
//Please
But when I put this HTML content into the browser then it shows differently.
<br /><br />Read the handouts please for tomorrow.<br /><br /><!--homework help homework
help help with homework homework assignments elementary school high school middle school
// --><font color="#60c000" size="4"><strong>Please!</strong></font>
Please suggest how to resolve this problem
I have another problem that in HTML content there is a tag
<img src="http://www.homeworknow.com/hwnow/upload/images/tn_star300.gif" border="0" />
in this images does not shows.
Use web.loadDataWithBaseURL instead of web.loadData (And don't forget to escape strings where it's needed)
You need to add internet permission to download images and view them in your manifest file.
This example works for me:
public class SimpleMusicStream extends Activity {
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
WebView wv = (WebView) findViewById(R.id.WebView01);
final String mimeType = "text/html";
final String encoding = "UTF-8";
String html = "<br /><br />Read the handouts please for tomorrow.<br /><br /><!--homework help homework" +
"help help with homework homework assignments elementary school high school middle school" +
"// --><font color='#60c000' size='4'><strong>Please!</strong></font>" +
"<img src='http://www.homeworknow.com/hwnow/upload/images/tn_star300.gif' />";
wv.loadDataWithBaseURL("", html, mimeType, encoding, "");
}
}
And don't forget to add:
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
in your AndroidManifest.xml file
Either you can do it as above or put html file into the asset folder and the use it loke this to display it
view.loadUrl("file:///android_asset/FILENAME.html");
for image display you can do it like
String str= " img src=\"http://www.homeworknow.com/hwnow/upload/images/tn_star300.gif\" alt=\"this is img\"ALIGN=\"right\"/>";
wv.loadData(str, "text/html", "utf-8");