ContentPlaceHolder in Razor? - asp.net-mvc

I can use ContentPlaceHolder's with Webforms view engines to put stuff in different locations in the master page.
How do I do that with Razor?
<div id="content">
<asp:ContentPlaceHolder ID="MainContent" runat="server">
</asp:ContentPlaceHolder>
</div>
<div id="footer">
<asp:ContentPlaceHolder ID="Footer" runat="server">
</asp:ContentPlaceHolder>
</div>

Yet again I managed to ask before finding the correct search keywords in Google.
In the layout
#RenderSection("footer", required: false)
View example
<h2>About</h2>
<p>
Some stuff about this page.
</p>
<p>
The current date and time: #DateTime.Now
</p>
#section footer {
Copyright (c) 2010, Robert Sundström.
}

Couldn't leave a comment sorry but you can remove the "required:"
#RenderSection("footer", false)

Related

Column issue when refactoring from aspx to cshtml (Razor)

I am in the process of converting my website from aspx to cshtml (Razor). This is going fine apart from an issue I have with my 2 or 3 column master pages and trying to convert these to a cshtml Layout Page.
In Razor I have basically created separate pages for all of my sections and am then calling these from the Layout Page using #RenderPage. Maybe this in itself is wrong? Basically what all the sections are displaying fine apart from the Main content section which is basically a wrapper for the 3 (or 2) columns that I wish to be displayed within this. I have tried various ways to do this but either just get the 1 main column displayed across the width of the page or get the column displayed above each other but the formatting of the other 2 is incorrect. I know all of the CSS etc works fine in aspx but I am obviously doing something wrong in Razor.
CSHTML New Layout Page
<body>
<div id="container">
<div id="top">
#RenderPage("~/Views/Shared/_Top.cshtml")
</div>
<div id="header">
#RenderPage("~/Views/Shared/_Header.cshtml")
</div>
<div id="nav">
#RenderPage("~/Views/Shared/_Nav.cshtml")
</div>
<div class="main">
#RenderPage("~/Views/Shared/_Main.cshtml")
<div class="columnVerySmall">
#RenderPage("~/Views/Shared/_ColumnVerySmall.cshtml", false)
</div>
<div id="columnLarge">
#RenderBody()
</div>
<div id="columnSmall">
#RenderPage("~/Views/Shared/_ColumnSmall.cshtml", false)
</div>
</div>
<div id="footer">
#RenderPage("~/Views/Shared/_Footer.cshtml")
</div>
<div id="scripts">
#RenderPage("~/Views/Shared/_Scripts.cshtml")
</div>
</div>
</body>
Old ASPX Master Page:
<div class="main">
<main role ="main" class="mainWrapper">
<div class="columnVerySmall">
<asp:ContentPlaceHolder ID="columnVerySmallContent" runat="server"></asp:ContentPlaceHolder>
</div>
<div class="columnLarge">
<asp:ContentPlaceHolder ID="columnLargeContent" runat="server"></asp:ContentPlaceHolder>
</div>
<div class="columnSmall">
<asp:ContentPlaceHolder ID="columnSmallContent" runat="server"></asp:ContentPlaceHolder>
</div>
</main>
</div>
I have managed to solve this by changing the Main section as shown in the code block below. I basically added the "Main" code to my layout and then #Render for the Columns. I don't really see how I can do this by having a separate page for "Main" and then calling it from the Layout Page using #RenderPage as I was originally trying. This is what I changed:
<div class="main">
<main role="main" class="mainWrapper">
<div class="columnVerySmall">
#RenderPage("_ColumnVerySmall.cshtml")
</div>
<div class="columnLarge">
#RenderBody()
</div>
<div class="columnSmall">
#RenderPage("_ColumnSmall.cshtml")
</div>
</main>
</div>

ASP.NET MVC site that works for mobile and non-mobile sites?

I am working on a website, using ASP.NET MVC3 with .aspx pages. The web site supports desktop browsers and mobile phones with the same site. The site has a single master page. I want to avoid redirecting to a mobile site, because that would duplicate a lot of html. I still intend to use the user-agent to determine when a mobile device is hitting the site, but instead of redirecting the browser, I set a flag that I use in the master page to control what HTML is generated.
I have run into trouble determining the best way to get the master page to generate the HTML I want. I have two strategies in mind to solve this problem, but I don’t know if this is the best way.
The first strategy is, to use the mobile flag to add, replace, or remove HTML content that is mobile specific.
Pro: Minimize duplication of HTML
Con: Multiple if statements.
Requires a second mobile specific .css to be downloaded. (Because the html has multiple if statements, we really need 2 css files, one for mobile and one for none mobile. We can't easily use specificity rules to deal with this in one css file).
Here is an excerpt from the master page using this strategy:
<% if (isMobile)
{
Html.RenderPartial("MobileSearchControls");
}
else
{ %>
<div id="viewTabs" class="span3">
...
</div>
<% }
%>
<%--body --%>
<div id="bd" class="row-fluid">
<% if (!isMobile)
{ %>
<div id="left-column" class="span3">
<div id='controls-and-preferences'>
<asp:ContentPlaceHolder ID="LeftColumnContent" runat="server" />
</div>
</div><!--left-column -->
<% }
%>
<div id="main" class="span9">
<div id="search-results">
<asp:ContentPlaceHolder ID="MainContent" runat="server" />
</div>
</div>
<% if (!isMobile)
{ %>
<div class="span2" id='right-column'>
</div>
<% }
%>
The second strategy is divide most of the body in master page into two parts, one for mobile, and one for desktop.
Pro: Avoids downloading an additional .css file. (Because the mobile code can be in a div with id of mobile and use specificity rules in the css).
Con: Greater duplication of code.
The tags must have unique ids, even though they are in mutually exclusive code blocks.
css is more complex for mobile page, because all tags are underneath a mobile tag.
A similar excerpt for the master page using this strategy:
<% if (isMobile)
{
%>
<div id="mobile-search-controls">
<asp:ContentPlaceHolder ID="MobileSearchContent" runat="server" />
</div>
<%--body --%>
<div id="bd" class="row-fluid">
<div id="main" class="span9">
<div id="search-results">
<asp:ContentPlaceHolder ID="MobileMainContent" runat="server" />
</div>
</div>
</div>
<%--body end--%>
</div>
<%
}
else
{ %>
<div id="bd" class="row-fluid">
<div id="left-column" class="span3">
<div id='controls-and-preferences'>
<asp:ContentPlaceHolder ID="LeftColumnContent" runat="server" />
</div>
</div><!--left-column -->
<div id="main" class="span9">
<div id="search-results">
<asp:ContentPlaceHolder ID="MainContent" runat="server" />
</div>
</div>
<div class="span2" id='right-column'>
</div>
</div>
<%--body end--%>
<% }
%>
Which way should I go? Is there a third better way?
You might want to consider using a framework such as Twitter Bootstrap (http://twitter.github.com/bootstrap/).
They have some examples that work well on devices of any resolution:
http://twitter.github.com/bootstrap/examples/fluid.html
you should be using css 3 media queries for things like this.. have a look at this link it has a demo
http://webdesignerwall.com/demo/adaptive-design/final.html
user277498,
I've used the Mobile Ready HTML5 MVC.NET template for vs:
http://visualstudiogallery.msdn.microsoft.com/9df9c61c-4d90-43e5-9aa1-a58786b7a1e4
to great effect. this basically has a viewengine that allows views to be directed twds mobile and/or normal mvc. it's actually quite 'magic' the way it works. give it a try, I've used in 3 projects now with no hiccups.

My design view no longer shows but the site runs fine.

I use a master page for my site and for some reason, I can no longer view the master page in design view. All that appears is a blank page with a blinking cursor. I've been at it for over 2 hours and can't figure it out. Yet when I run it, everything looks and behaves great. What am I missing?
Here is the Site.Master code:
<%# Master Language="C#" AutoEventWireup="true" CodeBehind="Site.master.cs" Inherits="WebApplication2.SiteMaster" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head runat="server">
<title></title>
<%--Here is where you reference your style sheets and JQuery library. The link href takes the
relative path and publishes fine for the directory. With <script> and <style> tags, copies
like the JQuery reference, you will need to use the '<%# Page.ResolveClientUrl() %>' to get
the same relative path behavior at publishing time. Typically you would define a code block
and choose '<%=' however page headers don't play nice with code blocks. '<%#' defines as a
databinding expression and then when you add Page.Header.Databind() to your code behind for
the master page, The DataBind method evaluates all the databinding expression(s) in your
header at load time--%>
<link href="~/Styles/Site.css" rel="stylesheet" type="text/css" />
<link href="~/Styles/style.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="<%# Page.ResolveClientUrl("~/Scripts/jquery-1.4.1.min.js") %>"></script>
<asp:ContentPlaceHolder ID="HeadContent" runat="server">
</asp:ContentPlaceHolder>
</head>
<body>
<form id="form1" runat="server">
<%--The ScriptManager is a what is used by the Microsoft controls to provide AJAX functionality.
It needs to exist for the the AJAX libraries to be referenced and placing it right below the
Master's page Form tag is the best place--%>
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<div class="page">
<div class="header">
<div class="title">
<h1>
SalesPro Technologies Online
</h1>
</div>
<div class="loginDisplay">
<asp:LoginView ID="HeadLoginView" runat="server" EnableViewState="false">
<AnonymousTemplate>
[ Log In ]
</AnonymousTemplate>
<LoggedInTemplate>
Welcome <span class="bold"><asp:LoginName ID="HeadLoginName" runat="server" /></span>!
[ <asp:LoginStatus ID="HeadLoginStatus" runat="server"
LogoutAction="RedirectToLoginPage" LogoutText="Log Out"
LogoutPageUrl="~/Account/Login.aspx"/> ]
</LoggedInTemplate>
</asp:LoginView>
</div>
<div id="divMenu" class="clear hideSkiplink">
<%-- The following code is for a traditional menu bar to appear:
<asp:Menu ID="NavigationMenu" runat="server" CssClass="menu" EnableViewState="false" IncludeStyleBlock="false"
Width="40%" Orientation="Horizontal">
<Items>
<asp:MenuItem NavigateUrl="~/Default.aspx" Text="Home"/>
<asp:MenuItem NavigateUrl="~/About.aspx" Text="About"/>
</Items>
</asp:Menu> --%>
<asp:LinkButton CssClass="LinkCss floatleft" ID="linkHome" runat="server"
PostBackUrl="~/Default.aspx">Home</asp:LinkButton>
<asp:LinkButton CssClass="LinkCss floatright" ID="linkAbout" runat="server"
PostBackUrl="~/About.aspx">About</asp:LinkButton>
<asp:LinkButton CssClass="LinkCss floatright" ID="linkOptions" runat="server">Options</asp:LinkButton>
<asp:LinkButton CssClass="LinkCss floatright" ID="linkReports" runat="server"
PostBackUrl="~/reports.aspx">Reports</asp:LinkButton>
</div>
</div>
<div class="main">
<asp:ContentPlaceHolder ID="MainContent" runat="server">
</asp:ContentPlaceHolder>
</div>
<div class="clear">
</div>
</div>
<div class="footer">
</div>
</form>
</body>
</html>
I think your comments with ASP tags in it are confusing Visual Studio. Try removing <%= <%# %> from within your comments and see if that helps. If this is your problem you may need to add spaces within the tags so they don't confuse VS. ie. < % = You should still be able to understand your comments.

How can I add yes/no dialog to jquery mobile page?

When I added $(document).ready({alert('it is ready')}); into script tags on the SiteMaster.master page and called the page with this link: http://192.168.1.66:90/Reminder/test.aspx#DialogChangeTag.aspx I doesn't work until I called it with http://192.168.1.66:90/Reminder/DialogChangeTag.aspx link.
Where am I making mistake?
DialogChangeTag.aspx:
<%# Page Title="" Language="C#" MasterPageFile="~/TekContent.master" AutoEventWireup="true"
CodeFile="DialogChangeTag.aspx.cs" Inherits="DialogChangeTag" %>
<asp:Content ID="Content1" ContentPlaceHolderID="PageIdContent" runat="Server">
<div data-role="page" id="delete_dialog" data-theme="b">
<script type="text/javascript">
$(document).ready(function () {
alert("calis");
});
</script>
<div data-role="content" data-theme="b">
<h1>
Delete Item?</h1>
<p>
Are you sure you want to delete this item?</p>
Yes
No
</div>
</div>
</asp:Content>
Test.aspx
<%# Page Title="" Language="C#" MasterPageFile="~/TekContent.master" AutoEventWireup="true"
CodeFile="test.aspx.cs" Inherits="test" %>
<asp:Content ID="ContentPage" ContentPlaceHolderID="PageIdContent" runat="Server">
<div data-role="page" id="pageTest">
<div data-role="header" data-position="inline">
<h1>
TEST HEADER</h1>
</div>
<div data-role="content">
<h2>
TEST CONTENT</h2>
<a href="DialogChangeTag.aspx" data-role="button" data-rel="dialog" data-transition="pop">
Show Dialog</a>
</div>
<div data-role="footer" class="ui-bar" id="divFooterContainer">
<h3>
TEST FOOTER</h3>
</div>
</div>
Probably because your jQuery Mobile is setup to work with AJAX. $(document).load() only gets called when a new page is loaded in the browser. This means $(document).load() won't work when you are working with AJAX based pages. Unwraping $(document).load() would solve it if that page is only loaded with AJAX. A better way of solving this problem is using unobtrusive client side code. Take a look at Backbone.js.

How do I inject plain text into an asp.net MVC1 master page from a child?

All the searches I've come up with talk about regular asp.net where there is a code behind page or you are accessing an asp.net control of some sort.
Since there is no code behind in the master page for Asp.net MVC how would I put a sub page
name in plain text/html just under the master page title?
<div id="header">
<div id="menu">
<ul id="main">
<li class="current_page_item" id="menu"><%= Html.ActionLink("Home", "Index", "Home")%></li>
<%-- <li><%= Html.ActionLink("About", "About", "Home")%></li>--%>
</ul>
</div>
<div id="logo">
<h1><span>Defect Severity Assessment Tool</span></h1>
<p id="subpage"><%--*What goes here?*--%></p>
</div>
</div>
<div id="content">
<asp:ContentPlaceHolder ID="MainContent" runat="server" />
<div id="footer">
</div>
</div>
Use a content placeholder.
Master Page
<div id="header">
<div id="menu">
<ul id="main">
<li class="current_page_item" id="menu"><%= Html.ActionLink("Home", "Index", "Home")%></li>
<%-- <li><%= Html.ActionLink("About", "About", "Home")%></li>--%>
</ul>
</div>
<div id="logo">
<h1><span>Defect Severity Assessment Tool</span></h1>
<p id="subpage"><asp:ContentPlaceHolder ID="TitleContent" runat="server" /></p>
</div>
</div>
<div id="content">
<asp:ContentPlaceHolder ID="MainContent" runat="server" />
<div id="footer">
</div>
</div>
Content Page
<asp:Content ID="Title" ContentPlaceHolderID="TitleContent" runat="server">
<!-- Your markup here -->
</asp:Content>
You could put the logic that sets the subpage name in a base, abstract controller class that your concrete controller classes derive from. Override OnActionExecuting in your base controller and add code that looks something like this:
protected override void OnActionExecuting(ActionExecutingContext context) {
ViewData["subpage"] = <add code to set subpage>;
base.OnActionExecuting(context);
}
In your view, you can now reference the subpage name like so:
<div id="logo">
<h1><span>Defect Severity Assessment Tool</span></h1>
<p id="subpage"><% =ViewData["subpage"] %></p>
</div>
If you need to set the value of subpage specifically per controller, simply override OnActionExecuting in your concrete controller and set the ViewData value there instead.
EDIT:
If the value of subpage is always dependent on the controller currently handling the request, you may be better off defining an abstract method to set its value in the base controller and then overriding it in each concrete controller. For instance:
public abstract class BaseController : Controller
{
protected abstract void SetSubPage();
}
public class ConcreteController : BaseController
{
protected override void SetSubPage()
{
ViewData["subpage"] = <code goes here>;
}
}
Since there is no code behind in the master page for Asp.net MVC
But you can add one.
how would I put a sub page name in
plain text/html just under the master
page title?
<p id="subpage"><%--*What goes here?*--%></p>
What about this MasterPage:
<p id="subpage"><%= Page.Title %></p>
And your page would be:
<%# Page Title="Name of Subpage" Language="C#" MasterPageFile="~/Templates/Main.Master" Inherits="System.Web.Mvc.ViewPage" %>
So, we just use Page's Title to render its name on the page.
you could try Html.RenderPartial and render a partial ascx control

Resources