Rotativa ViewAsPdf, Font size change when published to server - css

I'm working on ASP.NET MVC. I have a problem when using Rotativa to rendering a Pdf page by ViewAsPdf function. It's work fine on Visual Studio debugging, but when published to localhost IIS font size was changed, It's bigger on IIS.
I have compared to HTML page without ViewAsPdf function and no problem, font size does not change, it's changed when I'm using Rotativa.
Here is Controller code:
return new ViewAsPdf(TempData["gridData"])
{
PageSize = Rotativa.Options.Size.A4,
PageOrientation = Rotativa.Options.Orientation.Landscape,
CustomSwitches = string.Format("--footer-left \"Note:.....\" "
+ "--footer-font-size \"8\" "
+ "--footer-right \"Page [page] of [toPage]\" ")
};
This my View code for rendering pdf page:
#model IEnumerable<PM_Calibration.ViewModels.CalibrationDataList>
#{
ViewBag.Title = "Monthly List of Calibration Task";
Layout = null;
}
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>#ViewBag.Title</title>
#Styles.Render("~/Content/css")
#Scripts.Render("~/bundles/modernizr")
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/bootstrap")
<link href="~/Content/Site.css" rel="stylesheet" type="text/css" />
<link href="~/Content/PrintStyle.css" rel="stylesheet" type="text/css" />
<link href="~/Content/themes/base/jquery.ui.all.css" rel="stylesheet" type="text/css" />
</head>
<body>
#{
IList<PM_Calibration.ViewModels.CalibrationDataList> ModelList = Model.ToList();
List<PM_Calibration.ViewModels.CalibrationDataList> TableList = new List<PM_Calibration.ViewModels.CalibrationDataList>();
var i=1;
for (int x = 0; x < ModelList.Count; x++ )
{
var item = ModelList[x];
TableList.Add(ModelList[x]);
if(i==24)
{
#Html.Partial("PartialMonthlyCalibration_Table", TableList)
i = 0;
TableList.Clear();
}
i++;
}
}
</body>
I'm not sure is these code enough for this question.
My question is why my font size was changed on localhost IIS?

Related

Blazor set CSS file based on request path

I'm attempting to switch out the css file on the fly - based on which part of the web-system the user is in (i.e. if the user is on mydomain/students/page then the page loads with students.min.css, rather than site.min.css).
I've tried doing it within the _Host.cshtml:
#page "/"
#namespace FIS2withSyncfusion.Pages
#addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
#{
Layout = null;
//sniff the requst path and switch the stylesheet accordingly
string path = Request.Path;
string css = "site.min.css";
if (path.ToLowerInvariant().StartsWith("/students"))
{
css = "students.min.css";
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Martin's Blazor Testing Site</title>
<base href="~/" />
<link rel="stylesheet" href="css/#(css)" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js"></script>
<script type="text/javascript">
function saveAsFile(filename, bytesBase64) {
if (navigator.msSaveBlob) {
//Download document in Edge browser
var data = window.atob(bytesBase64);
var bytes = new Uint8Array(data.length);
for (var i = 0; i < data.length; i++) {
bytes[i] = data.charCodeAt(i);
}
var blob = new Blob([bytes.buffer], { type: "application/octet-stream" });
navigator.msSaveBlob(blob, filename);
}
else {
var link = document.createElement('a');
link.download = filename;
link.href = "data:application/octet-stream;base64," + bytesBase64;
document.body.appendChild(link); // Needed for Firefox
link.click();
document.body.removeChild(link);
}
}
</script>
</head>
<body>
<component type="typeof(App)" render-mode="ServerPrerendered" />
<script src="_framework/blazor.server.js"></script>
<div id="blazor-error-ui">
<environment include="Staging,Production">
An error has occurred. This application may no longer respond until reloaded.
</environment>
<environment include="Development">
An unhandled exception has occurred. See browser dev tools for details.
</environment>
Reload
<a class="dismiss">🗙</a>
</div>
</body>
</html>
However, it doesn't seem to hit this codeblock after the first load of the site; meaning whichever page they first landed on denotes the stylesheet for the entire site.
Do I have to put this codeblock on every page or is there another way of doing this?
another way you could approach this is to create components that respond to different styling that you desire. From there you have two options:
Create dedicated css associate with the component. From the docs
Create a class toggle in the code block of the component, similar to how the NavMenu works.
After further experimentation, I've found that adding this block:
#{
//sniff the requst path and switch the stylesheet accordingly
string path = navManager.Uri;
Uri uri = new Uri(path);
List<string> parts = uri.Segments.ToList();
string module = parts[1].ToLowerInvariant().Trim('/');
string css = "site.min.css";
if (module == "students")
{
css = "students.min.css";
}
}
<head>
<link rel="stylesheet" href="css/#(css)" />
</head>
To the top of MainLayout.razor works perfectly - so long as you remove the equivalent block from _Host.cshtml

Problem refreshing images with same local route path [duplicate]

I have an image at the URL http://192.168.1.53/html/cam.jpg (from a Raspberry Pi) and this image is changing very fast (it is from a camera).
So I want to have some JavaScript on a website that will reload this image every second for example.
My HTML is:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Pi Viewer</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
</head>
<body>
<style>
img,body {
padding: 0px;
margin: 0px;
}
</style>
<img id="img" src="http://192.168.1.53/html/cam.jpg">
<img id="img1" src="http://192.168.1.53/html/cam.jpg">
<script src="script.js"></script>
</body>
</html>
And my script:
function update() {
window.alert("aa");
document.getElementById("img").src = "http://192.168.1.53/html/cam.jpg";
document.getElementById("img1").src = "http://192.168.1.53/html/cam.jpg";
setTimeout(update, 1000);
}
setTimeout(update, 1000);
alert is working, but the image is not changing :/ (I have 2 images (they are the same))
The problem is that the image src is not altered so the image is not reloaded.
You need to convince the browser that the image is new. A good trick is to append a timestamp to the url so that it is always considered new.
function update() {
var source = 'http://192.168.1.53/html/cam.jpg',
timestamp = (new Date()).getTime(),
newUrl = source + '?_=' + timestamp;
document.getElementById("img").src = newUrl;
document.getElementById("img1").src = newUrl;
setTimeout(update, 1000);
}

Unable to insert stylesheet/script into window.open

I have been fighting this issue for quite some time now, and have been (still) unable to print my div with its styling.
Currently, my script is:
$('#printMeButton').click(function () {
//alert("a");
var data = document.getElementById('thisPrintableTable').outerHTML;
var mywindow = window.open('', data);
mywindow.document.write('<html><head><title>Print Me!!!</title>');
// mywindow.document.write('<link rel="stylesheet" type="text/css" href="Site.css" media="screen">');
mywindow.document.write('</head><body>');
mywindow.document.write(data);
mywindow.document.write('</body></html>');
mywindow.document.close();
mywindow.focus();
mywindow.print();
mywindow.close();
return true;
});
which is nested within a $(document).ready function.
When I include the desired stylesheet (currently commented out), Nothing appears in the print preview.
I also have some script that has an effect on the appearance of the table, and, as such, I believe this may hold the key of having these included into the popup window.
How can i include this into the new popup?
Could someone please suggest a way of printing this as it stands?
Edit History
removed space at end of </head><body>
Changed var data to have outerHTML instead of innerHTML
Altered Question/details from better understanding of issue
Try to open a local html file using window.open with css linked within it. And set the content html to be printed to the local html file using js.
Here is the page to be printed:-
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link href="test.css" rel="stylesheet" type="text/css" />
<script src="jquery.js"></script>
</head>
<body>
<div id="print">
<div class="red">TODO write content</div>
</div>
<button id="print_btn">Print</button>
<script>
$('#print_btn').click(function(){
var newWindow = window.open('print.html','_blank');
$(newWindow).load(function(){
$(newWindow.document).find('body').html($('#print').html());
});
})
</script>
</body>
</html>
The css file test.css is linked here, and I'm opening print.html at the time of window.open, the test.css is also linked in the print.html
Now, in print.html I'll write:-
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link href="test.css" rel="stylesheet" type="text/css" />
</head>
<body>
</body>
</html>
Since you provide an empty string as a new window's URL (the first parameter of the open function), the page inside it most likely can't figure out where your stylesheet is (as it's address is "relative to nothing"). Try specifying an absolute URL to your stylesheet.
Also, there is media="screen" attribute that should be changed to media="print"
mywindow.document.write('<link rel="stylesheet" type="text/css" href="http://my.site/Site.css" media="print"')
The issue can be solved by introducing some delay time before executing mywindow.close(); method. Seems that some time is needed for CSS to be applied (loaded), like this:
$('#printMeButton').click(function () {
var content = document.getElementById(id).innerHTML;
var mywindow = window.open('', 'Print', 'height=600,width=800');
mywindow.document.write('<!DOCTYPE html><html dir="rtl"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Print</title>');
mywindow.document.write('<link rel="stylesheet" type="text/css" href="/static/css/styles.css" />');
mywindow.document.write('</head><body >');
mywindow.document.write(content);
mywindow.document.write('</body></html>');
mywindow.document.close();
mywindow.focus()
mywindow.print();
// this is needed for CSS to load before printing..
setTimeout(function () {
mywindow.close();
}, 250);
return true;
});
We can use this inline style.
var divToPrint = document.getElementById('DivIdToPrint');
var newWin=window.open('','Print-Window');
newWin.document.open();
newWin.document.write('<html>' +
'<style>' +
".btn-petty-cash-split{display: none}"+
".btn-petty-cash-split{display: none}"+
'</style>' +
'<body onload="window.print()">'+divToPrint.innerHTML+'</body></html>');
newWin.document.close();
setTimeout(function(){
newWin.close();
window.location.reload();
},10);

View can't find layout page

My view can't find layout. But everything looks fine. My structure is shown below:
And my view is shown below:
#model xxx.Web.Model.Home.IndexModel
#{
ViewBag.Title = "Index";
Layout = "~/Views/_MainLayout.cshtml";
}
And my layout is shown below:
<!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="utf-8">
<title>Bootstrappage:Free Bootstrap Template (bootstrap 2.3.1 version)</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="">
<!--
<link rel="stylesheet" href="themes/style/bootstrap.min.css" />
<link rel="stylesheet" href="themes/style/bootstrap-responsive.min.css" />
-->
<link rel="stylesheet/less" type="text/css" href="../../themes/less/bootstrap.less">
<script src="../../themes/js/less/less.js" type="text/javascript"></script>
<link rel="shortcut icon" href="assets/ico/favicon.ico">
<link rel="apple-touch-icon-precomposed" sizes="144x144" href="assets/ico/apple-touch-icon-144-precomposed.png">
<link rel="apple-touch-icon-precomposed" sizes="114x114" href="assets/ico/apple-touch-icon-114-precomposed.png">
<link rel="apple-touch-icon-precomposed" sizes="72x72" href="assets/ico/apple-touch-icon-72-precomposed.png">
<link rel="apple-touch-icon-precomposed" href="assets/ico/apple-touch-icon-57-precomposed.png">
<script type="text/javascript">
$(function () {
#RenderSection("DocumentReady", false)
});
</script>
</head>
<body data-offset="40">
#{Html.RenderAction("Header", "Partial");}
#{Html.RenderAction("Navbar", "Partial");}
#RenderBody()
#{Html.RenderAction("Footer", "Partial");}
<script src="themes/js/lib/jquery-1.9.1.min.js"></script>
<script src="bootstrap/js/bootstrap.min.js"></script>
</body>
</html>
Also my controller is shown below:
public ActionResult Index()
{
IndexModel model = new IndexModel();
HomeModelFactory modelFactory = new HomeModelFactory();
model.Files = modelFactory.CreateIndexModel();
return View(model);
}
And exception:
Why I am getting this exception? It was working well.
And the full contents of the View / Controller as well please?
Some possible scenarios without looking at the View / Controller are;
- Some sections are missing (e.g. "DocumentReady")
- The view is trying to resolve model properties which are not set (i.e null)
You might check your properties setting on your _MainLayout.cshtml file. I had this same problem (the Layout page could not be found in the search path) until I set the VisualStudio properties BuildAction to Content. I had copied the file and renamed it, and the property had been set to 'none'.
This is your problem: Layout = "~/Views/_MainLayout.cshtml";
The _Layout reference should be Layout = "~/Views/Shared/_MainLayout.cshtml";
Dont make these type of mistakes again!

Durandal MVC 4 separate layout/mastepage for login ?

I am using MVC 4 Hot towel template, i have solved it MVC way right now, where i have _viewStart.cshtml:
#{
if (User.Identity.IsAuthenticated)
{
Layout = "~/Views/Shared/_Layout.cshtml";
Page.Title = "Home1";
}
else
{
Layout = "~/Views/Shared/_loginLayout.cshtml";
Page.Title = "Home2";
}}
and in the index.cshtml:
#using System.Web
#using System.Web.Optimization
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<meta name="format-detection" content="telephone=no"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script type="text/javascript">
if (navigator.userAgent.match(/IEMobile\/10\.0/)) {
var msViewportStyle = document.createElement("style");
var mq = "##-ms-viewport{width:auto!important}";
msViewportStyle.appendChild(document.createTextNode(mq));
document.getElementsByTagName("head")[0].appendChild(msViewportStyle);
}
</script>
#if (#User.Identity.IsAuthenticated)
{
<div id="applicationHost">
#Html.Partial("_splash")
</div>
#Scripts.Render("~/scripts/vendor");
if(HttpContext.Current.IsDebuggingEnabled) {
#Html.AntiForgeryToken()
<script>
window.userId = "#User.Identity.Name";
console.log(window.userId);
</script>
<script type="text/javascript" src="~/App/durandal/amd/require.js" data-main="#Url.Content("~/App/main")"></script>
} else {
<!-- Remember to run the Durandal optimizer.exe to create the main-built.js -->
<script type="text/javascript" src="~/App/main-built.js"></script>
}
}
else
{
<script src="~/Scripts/jquery-1.9.1.min.js"></script>
<div id="login">
<p>hello world</p>
</div>
}
Ive created a separate viewmodel user for login:
define(['services/logger'], function (logger) {
var vm = {
activate: activate(),
userName: ko.observable(),
password: ko.observable()
};
return vm;
//#region Internal Methods
function activate() {
logger.log('login View Activated', null, 'login', true);
return true;
}
//#endregion
});
and created login view:
<section>
<h2>My login model without content yet</h2>
</section>
(i know i am not using viewmodel in this view, but its only for test)
How do i do same functionality in Durandal? and is it even possible?
No hate, i am new to Single page application and durandal + breeze.js + knockout.
I would suggest using the built in ASP.net authentication / login mechanisms - ie <authentication> in web.config.
I found https://github.com/jamesc88/Durandal_Serverside_Authentication useful.

Resources