I'm trying to pass the header object here:
<%=FileUtil.AddStylesheetToHeader(Header, "UsedItems.css") %>
In my Master page I have a <head runat="server">. And my aspx page definitely has a reference to my MasterPageFile in the page directive at the top of my MVC based .aspx.
I also have an import statement the namespace that the FileUtil class resides in :
<%# Import Namespace="xxxx.Web.Utilities" %>
In standard ASP.NET you could reference the header with this.Header but in MVC I'm not able to do this...or I'm missing some kind of Imports or something.
for some reason though at runtime, with that call to AddStylesheetToHeader, I get the following error:
The best overloaded method match for 'System.IO.TextWriter.Write(char)' has some invalid arguments.
I'm not sure why it's looking at a .NET type as I know when I mouseover my FileUtil at compile time it's definitely referencing xxxx.Web.Utilities.FileUtil.
In that method I'm using HtmlLink styleSheet = new HtmlLink(); I may not be able to use this as it's an ASP.NET Web control? Here's that method:
public static void AddStylesheetToHeader(HtmlHead header, string cssFilename)
{
HtmlLink styleSheet = new HtmlLink();
styleSheet.Href = "content/css/" + cssFilename;
styleSheet.Attributes.Add("rel", "stylesheet");
styleSheet.Attributes.Add("type", "text/css");
header.Controls.Add(styleSheet);
}
I don't think I can use conrols that stem from System.Web.Controls since this is an ASP.NET application? If so, the how can I add a control to the header controls collection? Would I need to do this differently in MVC?
There may be a way to do it the way you're attempting, but it's more common in ASP.NET MVC to create a content placeholder in the <head> rather than accessing it programmatically. For example, your master view could look something like this:
<html>
<head>
<asp:ContentPlaceHolder ID="HeadContent" runat="server" />
</head>
</html>
And your view could look like this:
<asp:Content runat="server" ContentPlaceHolderID="HeadContent">
<link href="/content/css/UsedItems.css" rel="Stylesheet" type="text/css" />
</asp:Content>
have you tried this.Request.Header?
You can use JavaScript to dynamically add content to your HEAD section as shown in the code below:
<script language="javascript" type="text/javascript">
$(document).ready(function() {
$("head").append("<link href='Content/Site.css' rel='stylesheet' type='text/css' />");
});
</script>
Related
I am getting following error.
An exception of type 'System.InvalidOperationException' occurred in System.Web.Mvc.dll but was not handled in user code
Additional information: The partial view '../Shared/Partial/_ReferencePartial.cshtml' was not found or no view engine supports the searched locations. The following locations were searched:
I am having login controller in Area/Admin. In Login.cshtml view file, I am referencing Partial View file that contains references to script files. This file is in the folder, Solution/Project/Views/Shared/Partial.
Below is my Login.cshtml view file code.
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>#Messages.Login</title>
#Html.Partial("../Shared/Partial/_ReferencePartial.cshtml")
</head>
...
If you want to load the partial view directly inside the main view you could use the Html.Action helper:
#Html.Action("Load", "Home")
or if you don't want to go through the Load action use the HtmlPartial hepler:
#Html.Partial("_LoadView")
If you want to use Ajax.ActionLink, replace your Html.ActionLink with:
#Ajax.ActionLink(
"load partial view",
"Load",
"Home",
new AjaxOptions { UpdateTargetId = "result" }
)
and of course you need to include a holder in your page where the partial will be displayed:
<div id="result"></div>
Also don't forget to include:
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>
in your main view in order to enable Ajax.* helpers. And make sure that unobtrusive javascript is enabled in your web.config (it should be by default):
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
To working my static file (CSS, JS) I have to write absolute path like /AppName/templates/style/main.css. Is there any solution, that I could write relative path like style/main.css?
If your actual concern is the dynamicness of the webapp context (the "AppName" part), then just retrieve it dynamically by HttpServletRequest#getContextPath().
<head>
<link rel="stylesheet" href="${pageContext.request.contextPath}/templates/style/main.css" />
<script src="${pageContext.request.contextPath}/templates/js/main.js"></script>
<script>var base = "${pageContext.request.contextPath}";</script>
</head>
<body>
link
</body>
If you want to set a base path for all relative links so that you don't need to repeat ${pageContext.request.contextPath} in every relative link, use the <base> tag. Here's an example with help of JSTL functions.
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%# taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
...
<head>
<c:set var="url">${pageContext.request.requestURL}</c:set>
<base href="${fn:substring(url, 0, fn:length(url) - fn:length(pageContext.request.requestURI))}${pageContext.request.contextPath}/" />
<link rel="stylesheet" href="templates/style/main.css" />
<script src="templates/js/main.js"></script>
<script>var base = document.getElementsByTagName("base")[0].href;</script>
</head>
<body>
link
</body>
This way every relative link (i.e. not starting with / or a scheme) will become relative to the <base>.
This is by the way not specifically related to Tomcat in any way. It's just related to HTTP/HTML basics. You would have the same problem in every other webserver.
See also:
Browser can't access/find relative resources like CSS, images and links when calling a Servlet which forwards to a JSP
Is it recommended to use the <base> html tag?
Just use <c:url>-tag with an application context relative path.
When the value parameter starts with an /, then the tag will treat it as an application relative url, and will add the application-name to the url.
Example:
jsp:
<c:url value="/templates/style/main.css" var="mainCssUrl" />`
<link rel="stylesheet" href="${mainCssUrl}" />
...
<c:url value="/home" var="homeUrl" />`
home link
will become this html, with an domain relative url:
<link rel="stylesheet" href="/AppName/templates/style/main.css" />
...
home link
You start tomcat from some directory - which is the $cwd for tomcat. You can specify any path relative to this $cwd.
suppose you have
home
- tomcat
|_bin
- cssStore
|_file.css
And suppose you start tomcat from ~/tomcat, using the command "bin/startup.sh".
~/tomcat becomes the home directory ($cwd) for tomcat
You can access "../cssStore/file.css" from class files in your servlet now
Hope that helps, - M.S.
Instead using entire link we can make as below (solution concerns jsp files)
With JSTL we can make it like:
To link resource like css, js:
<link rel="stylesheet" href="${pageContext.request.contextPath}/style/sample.css" />
<script src="${pageContext.request.contextPath}/js/sample.js"></script>
To simply make a link:
<a id=".." class=".." href="${pageContext.request.contextPath}/jsp/sample.jsp">....</a>
It's worth to get familiar with tags
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
There is also jsp method to do it like below, but better way like above:
<link rel="stylesheet" href="<%=request.getContextPath()%>/style/sample.css" />
<script type="text/javascript" src="<%=request.getContextPath()%>/js/sample.js"></script>
To simply make a link:
<a id=".." class=".." href="<%=request.getContextPath()%>/jsp/sample.jsp">....</a>
This could be done simpler:
<base href="${pageContext.request.contextPath}/"/>
All URL will be formed without unnecessary domain:port but with application context.
This is a derivative of #Ralph suggestion that I've been using. Add the c:url to the top of your JSP.
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:url value="/" var="root" />
Then just reference the root variable in your page:
<link rel="stylesheet" href="${root}templates/style/main.css">
Actually I've a master page and I'm adding this master page into another view (Index.cshtml), now I want to add another individual css file into Index.cshtml view.
In the head section of your master page (e.g. _Layout.cshtml) add a RenderSection call. Your header section could look like this:
<head>
<meta charset="utf-8" />
<meta name="description" content="The content description" />
<link rel="shortcut icon" href="#Url.Content("~/Content/images/favicon.ico")" />
<title>#ViewBag.Title</title>
#RenderSection("css", false)
</head>
Then in your Index.cshtml use the section to add your css link:
#section css {
<link href="#Url.Content("~/css/style.css")" rel="stylesheet"/>
}
Note that "css" is a unique name for your section and it needs to match. You can also use this section in any view you want. The part you specify within the css section will then be rendered within the head-tag of your html, just where you put the RenderSection placeholder in your _Layout.cshtml.
Bad practice but you can Just add a html link tag or script tag to the top of the view, modern browsers will still render this. It doesn't always need to be in the head of the master page
You can use Razor sections, or a string collection and store it in ViewBag.CSS, and later render it on the layout, or you can use javascript if you are not profficient with razor
var $ = document; // shortcut
var cssId = 'myCss'; // you could encode the css path itself to generate id..
if (!$.getElementById(cssId))
{
var head = $.getElementsByTagName('head')[0];
var link = $.createElement('link');
link.id = cssId;
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = 'http://website.com/css/stylesheet.css';
link.media = 'all';
head.appendChild(link);
}
I have an Asp.net MVC2 web application. I built the application using VS2008 and tested on internal server, everything was perfect but when I deployed that web application on a local IIS the paths to images in web pages and in CSS file was not correct.
I need to change those paths for working with internal server and local server.
How can I overcome this problem?
Have you tried opening the CSS and Images directly (i.e. not via being called on a page)? Does that work?
How do you link to them on your internal server, if the relative paths don't equate the same, you'll have the problem you describe. An example about how you might fix this is to use Url.Content().
e.g. Instead of using:
<link rel="Stylesheet" href="/Styles/Reset.css" />
You would use:
<link rel="Stylesheet" href="<%=Url.Content("~/Styles/Reset.css")%>" />
This would work out the URL depending upon where the application lives on that box - not relative for the web root.
Edit: In case you need to do this through C# code
// This can be used to create img tag
public static string Image(this HtmlHelper helper)
{
UrlHelper urlHelper = ((Controller)helper.ViewContext.Controller).Url;
TagBuilder imgTag = new TagBuilder("img");
imgTag.MergeAttribute("src", urlHelper.Content("~/Content/images/image.gif"));
imgTag.MergeAttribute("alt", "Alt text");
return imgTag.ToString(TagRenderMode.SelfClosing);
}
To avoid this sort of problems you should always use the built-in helpers to generate URLs. For example:
<script type="text/javascript" src="<%= Url.Content("~/scripts/somescript.js") %>"></script>
and for links
<%= Html.ActionLink("Link text", "action", "controller") %>
Try something like this:
<link href="<%= Url.Content("~/Content/Site.css") %>" rel="stylesheet" type="text/css" />
The tilde ("~") represents the root and the Url.Content does the appropriate magic to get you a nice tidy reference.
I have a ViewPage within which I would like to specify an external style sheet. The style sheet only applies to elements in the ViewPage. After some unsuccessful attempts I settled on using "Url.Content" as follows:
<asp:Content ID="cssLinkContent" ContentPlaceHolderID="CssLinkContent" runat="server">
<link rel="stylesheet" type="text/css" href="<%= Url.Content("~/Content/custom.css")%>" />
</asp:Content>
This works fine at run time, but the error "The class or CssClass value is not defined" is displayed by the Visual Studio editor. I presume this is because Visual Studio cannot resolve the external style sheet when I use "Url.Content".
Any thoughts on a solution that will successfully resolve the URL at runtime and make Visual Studio happy?
Thanks in advance.
I would just ignore Visual Studio. It's a great tool, but sometimes it tries to hard. Are you sure that's an error or a warning? I know it's a sucky answer, but it's what I do.
Won't it complain about styles used simply as jQuery fodder as well?
As an aside, you might want to write an Html.Stylesheet helper to encapsulate the markup and url parsing behavior, as follows:
public static string Stylesheet(this HtmlHelper Html, string url) { return Html.Stylesheet(url, null); }
public static string Stylesheet(this HtmlHelper Html, string url, string media)
{
UrlHelper Url = new UrlHelper(new RequestContext(Html.ViewContext.HttpContext, Html.ViewContext.RouteData));
string html = "<link type=\"text/css\" rel=\"stylesheet\" href=\"{0}\" {1}/>";
if (!string.IsNullOrEmpty(media))
media = "media=\"" + media + "\"";
return string.Format(html, Url.Content(url), media);
}
Resulting in this, much cleaner, markup:
<%= Html.Stylesheet("~/Content/custom.css") %>
It is a weird solution but it works:
<!-- next line only for VS -->
<% if(false) { %><script src="../../Content/custom.css" type="text/javascript"></script><% } %>
<link rel="stylesheet" type="text/css" href="<%= Url.Content("~/Content/custom.css")%>" />
You can also use something like this for jQuery intellisense in your Views:
<% if(false) { %><script src="../../static/jquery/jquery-1.3.2-vsdoc2.js" type="text/javascript"></script><% } %>
Did you try
<link rel="stylesheet" type="text/css"
href="<%= ResolveUrl("~/Content/custom.css")%>" />