why does .net core "Return" verb inside a controller adds "plaintext.css" ? - asp.net-mvc

I was doing some testing with MVC6 .net core, and did a quick hack to return a bootstrap html code by putting dirtyHTML directly inside a controller.
The HTML contains the official example of bootstrap inside a literal string.
Just a quick way of returning some bootstrap html, (as i experiment with controller functionality), to my surprise when i go to a page using a web browser, all html text is shown like plain text, its not rendered.
namespace WebApplication1.Controllers
{
public class MariaController
{
[HttpGet("/index")]
public string index()
{
string dirtyHtml;
dirtyHtml =
#"<!DOCTYPE html>
<html lang=""en"">
<head>
<title>Bootstrap Example</title>
<meta charset=""utf-8"">
<meta name=""viewport"" content=""width=device-width, initial-scale=1"">
<link rel=""stylesheet"" href=""https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"">
<script src=""https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js""></script>
<script src=""https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js""></script>
</head>
<body>
<div class=""container"">
<h1>My First Bootstrap Page</h1>
";
return dirtyHtml;
}
}
When going to debug mode, initially they show the same asci text, but using firefox i see there is a line inserted before my page code:
<HTML><head>
<link rel="alternate stylesheet" type="text/css"
href="resource://gre-resources/plaintext.css"
title="Wrap Long Lines">`
So then i thought, let's look around in the solution and search for "Wrap Long Lines".. as to see where it comes from,... this is however not found.
So where does that come from ? (as the solution doesnt contain plaintext.css either). And more important to me, can it be disabled?.

I am not sure what you want to achive but following thing is way to go.
"Wrap Long Lines" and css related to that are internal to firefox browser.
You are saying that you return html and it display like html but it does not render html and for that do following thing.
[HttpGet("/index")]
public IActionResult index()
{
string dirtyHtml;
dirtyHtml =
#"<!DOCTYPE html>
<html lang=""en"">
<head>
<title>Bootstrap Example</title>
<meta charset=""utf-8"">
<meta name=""viewport"" content=""width=device-width, initial-scale=1"">
<link rel=""stylesheet"" href=""https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"">
<script src=""https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js""></script>
<script src=""https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js""></script>
</head>
<body>
<div class=""container"">
<h1>My First Bootstrap Page</h1>
";
return Content(dirtyHtml,"text/html");
}
See I have return IActionResult and Use Content from return.
Reason for this is when you return string it will display as string and if it is html then it will become encoded as you did not tell browser content type so it consider "text/plain".

An alternative of #dotnetstep's way is using Produces attribute:
[HttpGet("/index")]
[Produces("text/html")]
public string Index()
{
...
}

Related

How call jScript function in MVC view

I have this function in.js file:
function setValue(amount) {
if (amount === 0) {
.....
loanDriver._mem.loanValue = amount;
}
I like to call this in my MVC view and send this value to it : Model.ApprovedAmount
I tried this:
<script type="text/javascript">
setValue(#Html.Raw(Model.ApprovedAmount))
</script>
it is not working.
How I can do that?
Your existing code likely doesn't need the Html.Raw() call, but besides that it at least appears to be correct :
<script type="text/javascript">
setValue(#Model.ApprovedAmount)
</script>
There are a few things that you may want to look into to further troubleshoot this issue :
Check Your References
Firstly, make sure that the Javascript file that defines your setValue() function is being referenced prior to your existing <script> tag shown in your example. This is important as otherwise your page won't know what setValue()
is:
<script src='your-file-with-setvalue-defined.js'></script>
<script>
setValue(#Model.ApprovedAmount);
</script>
Use the Developer Tools
Check the Developer Tools (F12) within your browser, specifically the Network and Console tabs. These will reveal additional details about what exactly is going wrong (i.e. 404 errors, undefined functions, bad arguments, etc.).
Use the debugger
Consider using the debugger keyword within your setValue() function to see if it's being called and what the value that is being passed in looks like :
<script>
// Run this with your Developer Tools open and step into the function to
// see more
debugger;
setValue(#Model.ApprovedAmount);
</script>
Example
You can see a complete example here and seen below that demonstrates the basic idea behind this working as expected :
// HomeController.cs
public class HomeController : Controller
{
public ActionResult Index()
{
return View(new SampleViewModel(){ Amount = 42 });
}
}
// SampleViewModel.cs
public class SampleViewModel
{
public int Amount { get; set; }
}
// Index.cshtml
#model HelloWorldMvcApp.SampleViewModel
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Calling Function From Model</title>
</head>
<body>
<script>
function setValue(amount) {
alert(amount);
}
setValue(#Model.Amount);
</script>
</body>
</html>
assuming you are just doing it on the view, you can do something like this:
<text><b>some text:</b> </text> #Html.TextBox("something", null, new { "callsomefunction"() })
Thanks guys, simply I had to use name of the file dot name of the function and it worked. jsfile.setValue(#Model.ApprovedAmount);

MVC 5 - Would like to have page display if not logged in

I am using the following code to display a login form (Login.cshtml) when the user is not authenticated and the main page when the user is authenticated:
Layout.cshtml:
<!DOCTYPE html>
<html lang="en">
<head>
<!-- META SECTION -->
<title>Coalesce</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" href="favicon.ico" type="image/x-icon" />
<!-- END META SECTION -->
<!-- CSS INCLUDE -->
<link href="~/Content/Template/css/theme-default.css" rel="stylesheet" />
<!-- EOF CSS INCLUDE -->
</head>
<body>
#if (!Request.IsAuthenticated) {
<div class="login-container">
#RenderPage("~/views/Account/Login.cshtml")
</div>
RenderBody();
}
else {
...Normal page here
}
</body>
</html>
The Login.cshtml looks something like this:
<!DOCTYPE html>
<html lang="en">
<body>
...Login controls
</body>
</html>
I am using OWIN and everything wroks fine, but when I hit the login page portion, it only displays on half the screen, so half is the login page, and the bottom is white.
I've tried RenderPartial and a few other things in the authentication check, but I get get the login page to display on the full browser window.
I'm sure its the way that
#if (!Request.IsAuthenticated) {
#RenderPage("~/views/Account/Login.cshtml")
RenderBody();
}
is constructed, but i'm currently stumped.
I've never seen this approach before, but in any case (assuming it works) Login.cshtml should not contain <!DOCTYPE>, <html> and <body> tags because it will be rendered inside Layout.cshtml, which already contains these tags.
The approach that I am familiar with is: let a Controller, or even a global ActionFilter, check if one is logged in. If not, show View("Login"), or redirect to /Home/Login. Then let Login.cshtml be rendered using Layout.cshtml (which contains no login logic) - and not the other way around which is what you seem to be trying.
Controllers/HomeController.cs example
public ActionResult Index()
{
if (!Request.IsAuthenticated)
return View("Login");
// Add normal flow here
}

How can I dynamically add an attribute to a body element in a GSP page

In Grails 2.3.7, is there a way to use an expression in a GSP page to add an attribute to a body element? In the code below, the expression in the p element works, but the same expression in the body element causes a error: Expecting '=' after attribute name (${raw('this="that"')}).
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
</head>
<body ${raw('this="that"')}>
<p ${raw('this="that"')}>Hello!</p>
</body>
</html>
I'm trying to do this in a layout and pick up the corresponding attribute from the original page with pageProperty, but the same error occurs on the body element in the page layout as well.
Replacing an attribute value does work in a body element like this:
<body this="${that}">
but this won't work because I do not want the attribute to appear at all if it has no value.
the problem is, that the body tag is replaced by the <g:layoutBody /> tag and therefore could not be set like this.
One solution is to use to set different stuff in the sitemesh layout.
An example of this is shown here:
<html>
<head>
<g:layoutHead/>
</head>
<body class="${pageProperty( name:'body.class' )}">
<g:layoutBody/>
</body>
</html>

JavaFX WebView load local Javascript file

I am experimenting with the JavaFX WebView control and I want to use the MathJax Javascript library to render mathematical content.
As a test I have created a basic JavaFX FXML project, added a WebView to the FXML and updated the controller code like so:
public class SampleController implements Initializable {
#FXML
private WebView webView;
#Override
public void initialize(URL url, ResourceBundle rb) {
webView.getEngine().load(
"file:///Users/benjamin/Desktop/Page.html");
}
}
The html file looks like this:
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/x-mathjax-config">
MathJax.Hub.Config({tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}});
</script>
<script type="text/javascript"
src="/Users/benjamin/Downloads/mathjax/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>
</head>
<body>
When $a \ne 0$, there are two solutions to \(ax^2 + bx + c = 0\) and they are
$$x = {-b \pm \sqrt{b^2-4ac} \over 2a}.$$
</body>
</html>
This works as expected and produces the following result:
Note that for the test, both the html and JavaScript file paths are hard coded to locations on my hard drive so the next step is to package the html as a resource that is bundled with the application so that it is not looking for local files.
I have updated the controller code to look up the page like this (the html has not been changed).
#Override
public void initialize(URL url, ResourceBundle rb) {
webView.getEngine().load(
this.getClass().getResource("Page.html").toExternalForm());
}
but this produces the following result:
As you can see, the mathematical content is no longer rendered.
If I change the html <script> tag to reference the JavaScript from a CDN, then everything works as in the original example but I would like to be able to reference the local JavaScript file (and eventually a version that is bundled with the application).
Is what I'm trying to achieve possible?
Add the MathJax.js file to the same package/folder of Page.html then reference to it as
<script type="text/javascript"
src="MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>

ASP.NET MVC: How do I send "text/xml" to all browsers but IE?

I need to be able to send the content type "text/xml" to Firefox and Safari, to allow them to render inline SVG in one of my pages.
This works, as long as the content type is "text/xml".
However, when IE hits the page, if the content type is not "text/html" it tries to render the XML document tree, rather than the XHTML content of the page.
What is the "right way" in ASP.NET MVC to set the HTTP Content-Type of ALL of my views?
Keep in mind that I am going to be rendering the views as ViewResults.
Ok, to clear any confusion up:
User Agent Content-Type Desired
-----------------------------------
IE 5.5 text/html
IE 6 text/html
IE 7 text/html
IE 8 text/html
Firefox text/xml
Safari text/xml
Chrome text/xml
And so on.
All of the browsers listed support SVG inline in some way or another. I have a consistent delivery format, save the content type.
You could look at the properties in Request.Browser and sniff out IE that way, and return the proper view that way, though that is prone to issues. This isn't optimal because IE might support it in the future.
public ActionResult MyAction() {
if (this.Request.Browser.Browser == "IE") {
return View("NonSVG");
} else {
return View("SVG");
}
}
Something worth looking into a little more might be this page on Codeplex. They define a property on Browser called AcceptsImageSVG, but it looks like it's geared towards mobile browsers, don't know if it could be used in your situation.
According to W3, you should be using application/xhtml+xml rather than text/xml to signify XHTML:
http://www.w3.org/TR/2002/NOTE-xhtml-media-types-20020801/#text-xml
The above article also notes that text/html should not be used for XHTML content.
You can determine the browser type by using the Request.Browser object
See this example http://msdn.microsoft.com/en-us/library/system.web.configuration.httpcapabilitiesbase.type%28VS.80%29.aspx
So you could do something like:
if( Request.Browser.Type.ToUpper().Contains("IE") )
{
// Return IE View
}
else
{
// Return the other view
}
Or, if you use this in lots of places you could create a ViewResult factory that returns the proper view result based on the browser type.
Kind of hacky, but... What if the SVG was in a frame, the frame advertised content-type=text/xml, while the containing page advertsized the more proper application/xhtml+xml. This divides the problem into two (possibly) more tractable ones.
I'm not sure whether this will work, but you could try using conditional comments:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<!--[if lte IE 8]>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<![endif]-->
<!--[if gt IE 8]>-->
<meta http-equiv="Content-Type" content="text/xml; charset=UTF-8" />
<!--<![endif]-->
<title>Test page</title>
</head>
<body>
<p>Test page</p>
</body>
</html>
Or, better yet, use HTML5:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Test page</title>
</head>
<body>
<p>Test page</p>
</body>
</html>
You don't even need to specify the content type.

Resources