Or, if that's impossible for some reason, a simpler question: how can I get the physical directory of the current file from a layout page?
this.VirtualPath will refer to the virtual path of the layout file itself, and this.NormalizePath(".") will only get the virtual path of the directory containing the layout file.
I just want to be able to have a site that doesn't have the possibility of relative links suddenly not working just because some guy typed http://example.com/index/some/other/junk for no reason.
EDIT to show you what I mean:
TestLayout.cshtml
<html>
<head>
<title>Test Page</title>
</head>
<body>
<div style="background: grey">
#Request.RawUrl<br />
#Request.Url.AbsolutePath<br />
#Request.Url.AbsoluteUri<br />
#Request.Url.LocalPath<br />
#Request.CurrentExecutionFilePath<br />
#Request.FilePath<br />
#Request.Path<br />
#VirtualPath<br />
</div>
<div style="background: red">
#RenderBody()
</div>
</body>
</html>
Test.cshtml
#{
Layout = "TestLayout.cshtml";
}
#Request.RawUrl<br />
#Request.Url.AbsolutePath<br />
#Request.Url.AbsoluteUri<br />
#Request.Url.LocalPath<br />
#Request.CurrentExecutionFilePath<br />
#Request.FilePath<br />
#Request.Path<br />
#VirtualPath<br />
If you go to http://example.com/Test/random/junk/at/the/end, you'll find that the only lines that correctly trim all the cruft are the two #VirtualPath lines - however, the VirtualPath property of the layout page is TestLayout.cshtml. How do I access Test.cshtml's VirtualPath property from within TestLayout.cshtml?
So, after many, many hours, I've figured it out.
No, you cannot disable the automatic URL routing of ASP.Net WebPages - it's baked in to the WebPageRoute class. The only way to disable it is to disable WebPages entirely.
There are two ways that you can access the VirtualPath of the parent .cshtml file from a child layout.
You can manually parse the URL. This is fairly involved, although all the work has been done already in the WebPageRoute.cs file, so you can just nick it with a few tweaks. The problem is that you can only get the VirtualPath of the topmost parent page.
You can extend the WebPage class, overriding the ConfigurePage method, and store the argument for later use. Example code follows:
CustomWebPage.cs
using System.Web;
using System.Web.WebPages;
public abstract class CustomWebPage : WebPage
{
private WebPageBase _parentPage;
public WebPageBase ParentPage { get; private set; }
protected override void ConfigurePage(WebPageBase parentPage)
{
ParentPage = parentPage;
}
}
TestLayout.cshtml
<html>
<head>
<title>Test Page</title>
</head>
<body>
<div style="background: grey">
Inside the layout page!<br/>
VirtualPath is: #VirtualPath<br />
Parent's VirtualPath is: #ParentPage.VirtualPath
</div>
<div style="background: red">
#RenderBody()
</div>
</body>
</html>
Test.cshtml
#{
Layout = "TestLayout.cshtml";
}
Inside the main test page!<br />
VirtualPath is #VirtualPath
Output:
Inside the layout page!
VirtualPath is: ~/TestLayout.cshtml
Parent's VirtualPath is: ~/Test.cshtml
Inside the main test page!
VirtualPath is ~/Test.cshtml
Related
I have searched extensively for what seems a rather simple question but found no answers. Does anybody know how to reference a webpage created in Node Red running on IBM Bluemix? Here is my flow...
My http in node is referencing "/temp1" but when I type my bluemix address with "/temp1" at the end I get the error "Cannot GET /temp1". This seems so remedial I am sure that it is just a setting or missing characters in the reference. Thank you so much for your help. Here is my web page html by the way...
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<title>Test Home HVAC Zone Control</title>
</head>
<body>
<h2>
WebSocket Test
</h2>
Outside Temperature: <input id="display_external_temperature" type="text" value="0"></input><br>
Media Room:<br>
Set Temperature: <input id="mr_set_temp" type="text" value="0"></input><br>
Current Temperature: <div id="mr_temp">0</div><br>
Humidity: <div id="mr_humidity">0</div><br>
DC Voltage: <div id="mr_vcc">0</div><br>
Status: <div id="status">unknown</div>
</body>
</html>
You need to set an appropriate header, add for example a function node after your html one with:
msg.headers={"Content-Type":"text/html"}
return msg;
Here is a modified flow:
[{"id":"d6ed730e.41fab8","type":"http in","z":"f0084239.95c63","name":"/temp","url":"/temp","method":"get","swaggerDoc":"","x":88.5,"y":425.40000915527344,"wires":[["6b3a011d.14e8d"]]},{"id":"6b3a011d.14e8d","type":"template","z":"f0084239.95c63","name":"html","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\">\n<html>\n <head>\n <title>Test Home HVAC Zone Control</title>\n </head>\n <body>\n <h2>\n WebSocket Test\n </h2>\n Outside Temperature: <input id=\"display_external_temperature\" type=\"text\" value=\"0\"></input><br>\n Media Room:<br>\n Set Temperature: <input id=\"mr_set_temp\" type=\"text\" value=\"0\"></input><br>\n Current Temperature: <div id=\"mr_temp\">0</div><br>\n Humidity: <div id=\"mr_humidity\">0</div><br>\n DC Voltage: <div id=\"mr_vcc\">0</div><br>\n Status: <div id=\"status\">unknown</div>\n\n\n </body>\n</html>","x":283.49998474121094,"y":416.40000915527344,"wires":[["9ac696a6.89a578"]]},{"id":"9ac696a6.89a578","type":"function","z":"f0084239.95c63","name":"setHTTPheader","func":"msg.headers={\"Content-Type\":\"text/html\"}\nreturn msg;","outputs":1,"noerr":0,"x":514.2000122070312,"y":419.20001220703125,"wires":[["dc5c1338.e50888"]]},{"id":"dc5c1338.e50888","type":"http response","z":"f0084239.95c63","name":"/temp","x":745.4999847412109,"y":405.8000030517578,"wires":[]}]
I have to display a PDF inside a modal dialog, for which I'm using the object element. As per my understanding, the moment I assign a URL to the "data" attribute of the object element, it'll make an internal call to the URL to fetch the document. What if that call fails due to, say, connectivity issues? I have a div (the error message container) inside the object tag as the fallback content, which is supposed to be displayed if the call fails. But that isn't happening. If the document is not being loaded, the dialog remains blank, instead of showing my error message. Below is the markup for the object element.
<object id="pdfContainer" type="application/pdf">
<div id="pdfFetchFailureMessage" data-message-container="pdfFetchFailureMessage" class="spacer">
<div class="message-group">
<div class="messaging error customer-level" data-message-context="default">
<div class="message-container" data-focus-first-message="" tabindex="-1">
<span class="icon-wrapper"><i class="icon"></i></span>
<div class="message-content">
<p role="error"><em class="visuallyhidden">error</em>The form could not be generated at the moment. Please try again later.</p>
</div>
</div>
</div>
</div>
</div>
</object>
I'll be assigning the URL to the "data" attribute dynamically, which initiates the call. If the call fails, I should get the div with id pdfFetchFailureMessage in the dialog, but it's coming up blank. Where exactly am I going wrong?
Put the message-content div outside the object tag and use JS to check for the load event error and show your message.
var pdf = document.querySelector('#pdfContainer');
var msg = document.querySelector('#pdfFetchFailureMessage');
pdf.addEventListener('error', function (event) {
msg.classList.remove('hidden');
});
pdf.setAttribute('data', 'http://box2d.org/manual.pdf');
.error {
color: red;
}
.hidden {
display: none;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<object id="pdfContainer" type="application/pdf"></object>
<div id="pdfFetchFailureMessage" data-message-container="pdfFetchFailureMessage" class="spacer hidden">
<div class="message-group">
<div class="messaging error customer-level" data-message-context="default">
<div class="message-container" data-focus-first-message="" tabindex="-1">
<span class="icon-wrapper"><i class="icon"></i></span>
<div class="message-content">
<p role="error"><em class="visuallyhidden">error</em>The form could not be generated at the moment. Please try again later.</p>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
Hello I have an MVC application where a page is converted into a PDF using iTextSharp. I have a separate PDF style sheet called pdfStyleSheet.css that links to _PDFLayout. When linking the CSS page to my page layout the styles aren't being passed. My link is below. However if I put an inner style in _PDFLayout it works fine. Any ideas what I'm doing wrong?
The code below does not work
_PDFLayout Link
<link rel="stylesheet" type="text/css" href="~/Content/pdfStyleSheet.css" />
pdfStyleSheet.css
.test {
font-weight:bold;
color:red;
}
HTML
<div class="test">
#Html.DisplayNameFor(model => model.Requestor)
</div>
Controller
public ActionResult getPDF(int id)
{
MEOmodel model = _repository.GetMEOById(id);
return new PdfActionResult(model);
}
Hi I am using MVC Mailer to manage creating and sending emails in my application. It will create and send the email fine but any html I insert inside the body in the layout is not in the email.
Mailer
public class Mailer : MailerBase, IMailer
{
public aMailer()
{
MasterName = "_EmailLayout";
}
public virtual MvcMailMessage RequestAccess(RequestAccessViewModel viewmodel)
{
ViewData.Model = viewmodel;
return Populate(x =>
{
x.Subject = "RequestAccess for Data";
x.ViewName = "RequestAccess";
x.To.Add("AppTeam#groups.hp.com");
x.From = new MailAddress(viewmodel.Email);
});
}
}
I am setting it to use _EmailLayout here, I cahnged the name after seeing that there was an issue with naming it _Layout because it would conflict with any other files named _Layout.
_EmailLayout
<html>
<head>
</head>
<body>
<h1>Mailer</h1>
#RenderBody()
Thanks
</body>
The contents of the H1 tag or "Thanks" are not in the email
Access.cshtml
<h3>"This is a Application email." </h3>
<p>#Model.Message</p>
<br/>
<p>Regards</p>
<p>#Model.Name</p>
<p>Business Area: #Model.BusinessArea</p>
Email Source
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii"><title></title>
</head>
<body>
<p> Hi jeff test,</p>
<br>
<p>Thank you for your enquiry about the Application.</p>
<br>
</body>
Has anyone come across this issue before? When I debug my application I can see that it is going into the _EmailLayout but I don't know why the HTML in that files is not rendered.
After posting the following issue on the github page for MVC Mailer
Changing the layout code to this fixed the problem
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
Mailer
#RenderBody()
Thanks
</body>
</html>
I'm not sure why this fixed the problem but it did.
I want to display an iframe in a .aspx page, and the iframes source should be the same page.
I need to use a relative uri.
What value should I give the 'src' attribute?
I realise this is a little unusual - the page will be displayed in different states depending on parameters passed in, so the iframe won't be displayed within itself.
If you do this you will get an endless loop... the processsing will "never end". maybe thats why it is white? it is really processing pages..
- is that what you want ? if you for example want just 2-3 pages in depth, you can youse querystring and for example disable the iframe when the querystrings are incremented to 3.
MyPage.aspx?depth=1 --MyPage.aspx?depth=2 --MyPage.aspx?depth=3 etc
The literal relative path should work. IE: MyPage.aspx
Here is an ASP.NET Example...
Seemed to work fine for me with the following...
Markup:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication2._Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<iframe runat="server" id="myFrame" src="Default.aspx?message=Hello%20World"></iframe>
<div id="myDiv" runat="server"></div>
</div>
</form>
</body>
</html>
Code Behind:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebApplication2
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string message = Request.QueryString["message"];
if (null != message)
{
myDiv.InnerText = message;
myFrame.Visible = false;
}
else
{
myDiv.Visible = false;
}
}
}
}
The short answer is src="localfilename.aspx" within the iframe tag. The web standard, loosely applied, says anything not proceeded by a '/' is relative to the location of the current page. Sometimes src="" might even work for substituting the current file name (at the browser level)