I need to pass a model to _Layout page for dynamic content editing.
Here is my _Layout
#model IEnumerable<Test.Models.Article>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
...
Later in _Layout I need to use this:
#Html.Raw(Model.Where(x => x.Id == 1).Single().Content) - this works fine
<a asp-controller="Articles" asp-action="Edit" asp-route-id="1">Edit</a> - error after clicking the edit button
This concept is working fine on all pages like Index, About etc. but not on _Layout.cshtml.
I get this error:
InvalidOperationException: The model item passed into the ViewDataDictionary is of type 'Test.Models.Article', but this ViewDataDictionary instance requires a model item of type 'System.Collections.Generic.IEnumerable`1[Test.Models.Article]'.
What shoud I do?
Edit:
Here is my HomeController:
public class HomeController : Controller
{
public ApplicationDbContext _context;
public HomeController(ApplicationDbContext context)
{
_context = context;
}
public async Task<IActionResult> Index()
{
return View(await _context.Article.ToListAsync());
}
public async Task<IActionResult> About()
{
return View(await _context.Article.ToListAsync());
}
}
Here is my ArticleController:
public class ArticlesController : Controller
{
public ApplicationDbContext _context;
public ArticlesController(ApplicationDbContext context)
{
_context = context;
}
// GET: Articles
public async Task<IActionResult> Index()
{
return View(await _context.Article.ToListAsync());
}
// GET: Articles/Edit/5
public async Task<IActionResult> Edit(int? id)
{
if (id == null)
{
return NotFound();
}
var article = await _context.Article.FindAsync(id);
if (article == null)
{
return NotFound();
}
return View(article);
}
// POST: Articles/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,Content")] Article article)
{
if (id != article.Id)
{
return NotFound();
}
if (ModelState.IsValid)
{
try
{
_context.Update(article);
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!ArticleExists(article.Id))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToAction(nameof(Index));
}
return View(article);
}
The whole _Layout:
#model IEnumerable<Test.Models.Article>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>#ViewData["Title"] - PermanentTetovani</title>
<environment include="Development">
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
<link rel="stylesheet" href="~/css/site.css" />
<link rel="stylesheet" href="~/css/default.css" />
<link rel="stylesheet" href="~/lib/font-awesome/css/font-awesome.css" />
</environment>
<environment exclude="Development">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"
asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" />
<link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
<link rel="stylesheet" href="~/lib/font-awesome/css/font-awesome.min.css" />
</environment>
</head>
<body>
<partial name="_CookieConsentPartial" />
<!-- HEADER : begin -->
<header id="header" class="m-animated">
<div class="header-bg">
<div class="header-inner">
<!-- HEADER BRANDING : begin -->
<div class="header-branding">
<a asp-controller="Home" asp-action="Index"><img src="../images/logo.png" alt="Permanentní tetování" data-hires="../images/logo.2x.png" width="291"></a>
</div>
<!-- HEADER BRANDING : end -->
<!-- HEADER NAVIGATION : begin -->
<div class="header-navigation">
<!-- HEADER MENU : begin -->
<nav class="header-menu">
<button class="header-menu-toggle" type="button"><i class="fa fa-bars"></i>MENU</button>
<ul>
<li class="#((ViewBag.PageName == "Index") ? "m-active" : "")">
<span><a asp-controller="Home" asp-action="Index">Úvodní stránka</a></span>
</li>
<li class="#((ViewBag.PageName == "About") ? "m-active" : "")">
<span><a asp-controller="Home" asp-action="About">O nás</a></span>
</li>
<li class="#((ViewBag.PageName == "Gallery") ? "m-active" : "")">
<span><a asp-controller="Home" asp-action="Gallery">Galerie</a></span>
</li>
<li class="#((ViewBag.PageName == "Contact") ? "m-active" : "")">
<span><a asp-controller="Home" asp-action="Contact">Kontakt</a></span>
</li>
</ul>
</nav>
<!-- HEADER MENU : end -->
</div>
<!-- HEADER NAVIGATION : end -->
<!-- HEADER PANEL : begin -->
<div class="header-panel">
<button class="header-panel-toggle" type="button"><i class="fa"></i></button>
<!-- HEADER RESERVATION : begin -->
<div class="header-reservation">
<a asp-controller="Home" asp-action="Contact" class="c-button">Domluvit si schůzku</a>
</div>
<!-- HEADER RESERVATION : end -->
<!-- HEADER CONTACT : begin -->
<div class="header-contact">
<ul>
<!-- PHONE : begin -->
<li>
<div class="item-inner">
<i class="ico fa fa-phone"></i>
<strong>721 805 741</strong>
</div>
</li>
<!-- PHONE : end -->
<!-- EMAIL : begin -->
<li>
<div class="item-inner">
<i class="ico fa fa-envelope-o"></i>
777michaelahavlova<br>
##seznam.cz
</div>
</li>
<!-- EMAIL : end -->
<!-- ADDRESS : begin -->
<li>
<div class="item-inner">
<i class="ico fa fa-map-marker"></i>
<strong>PERMANENT TETOVÁNÍ</strong><br>
Jihočeská univerzita, Vančurova 2904<br>
Tábor 390 01
</div>
</li>
<!-- ADDRESS : end -->
<!-- HOURS : begin -->
<li>
<div class="item-inner">
<i class="ico fa fa-clock-o"></i>
<dl>
<dt>Po. - Pá.:</dt>
<dd>Dle dohody</dd>
<dt>So.:</dt>
<dd>Dle dohody</dd>
<dt>Ne.:</dt>
<dd>Zavřeno</dd>
</dl>
</div>
</li>
<!-- HOURS : end -->
</ul>
</div>
<!-- HEADER CONTACT : end -->
</div>
<!-- HEADER PANEL : end -->
</div>
</div>
</header>
<!-- HEADER : end -->
<!-- WRAPPER : begin -->
<div id="wrapper">
#RenderBody()
<!-- BOTTOM PANEL : begin -->
<div id="bottom-panel">
<div class="bottom-panel-inner">
<div class="container">
<div class="row">
<div class="col-md-6">
<!-- BOTTOM TEXT : begin -->
<div class="bottom-text various-content">
<h3>O našem studiu</h3>
<!--
<p><strong>Permanentní make-up</strong> provádím v Táboře v Jihočeské univerzitě, kde nabízím tyto služby: <strong>permanentní tetování obočí, rtů a očních linek</strong>.</p>
<p>Je potřeba se nejprve předem objednat!</p>
-->
#Html.Raw(Model.Where(x => x.Id == 1).Single().Content)
<a asp-controller="Articles" asp-action="Edit" asp-route-id="1">Edit</a>
</div>
<!-- BOTTOM TEXT : end -->
</div>
<div class="col-md-6">
<!-- BOTTOM SUBSCRIBE : begin -->
<div class="bottom-subscribe various-content">
<h3>Kontakt</h3>
<p>Využijte prosím náš kontaktní formulář.</p>
<a asp-controller="Home" asp-action="Contact" class="c-button">Kontaktujte nás</a>
</div>
<!-- BOTTOM SUBSCRIBE : end -->
</div>
</div>
</div>
</div>
</div>
<!-- BOTTOM PANEL : end -->
<!-- FOOTER : begin -->
<footer id="footer">
<div class="container">
<!-- FOOTER BOTTOM : begin -->
<div class="footer-bottom">
<div class="row">
<div class="col-md-6 col-md-push-6">
<!-- FOOTER MENU : begin -->
<nav class="footer-menu">
<ul>
<li><a asp-controller="Home" asp-action="Index">Úvodní stránka</a></li>
<li><a asp-controller="Home" asp-action="About">O nás</a></li>
<li><a asp-controller="Home" asp-action="Gallery">Galerie</a></li>
<li><a asp-controller="Home" asp-action="Register">Administrace</a></li>
</ul>
</nav>
<!-- FOOTER MENU : end -->
</div>
<div class="col-md-6 col-md-pull-6">
<!-- FOOTER TEXT : begin -->
<div class="footer-text">
<p>
©
<script type="text/javascript">
var today = new Date()
var year = today.getFullYear()
document.write(year)
</script>
PermanentTetovani.cz | Vytvořil ProgNet.cz
</p>
</div>
<!-- FOOTER TEXT : end -->
</div>
</div>
</div>
<!-- FOOTER BOTTOM : end -->
</div>
</footer>
<!-- FOOTER : end -->
</div>
<environment include="Development">
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
</environment>
<environment exclude="Development">
<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-3.3.1.min.js"
asp-fallback-src="~/lib/jquery/dist/jquery.min.js"
asp-fallback-test="window.jQuery"
crossorigin="anonymous"
integrity="sha384-tsQFqpEReu7ZLhBV2VZlAu7zcOV+rXbYlF2cqB8txI/8aZajjp4Bqd+V6D5IgvKT">
</script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"
asp-fallback-src="~/lib/bootstrap/dist/js/bootstrap.min.js"
asp-fallback-test="window.jQuery && window.jQuery.fn && window.jQuery.fn.modal"
crossorigin="anonymous"
integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd">
</script>
<script src="~/js/site.min.js" asp-append-version="true"></script>
</environment>
#RenderSection("Scripts", required: false)
</body>
</html>
#Lukáš, I found the reason of your exception and will try my best to describe it.
From the process below, when reload edit view, it will load _layout.cshtml then render Edit.cshtml.You defined the #model IEnumerable<Test.Models.Article>
but return view(Ariticle).
What's the simplest solution?
open Views/Articles/Edit.cshtml add codes below
#{
Layout = null;
}
Screenshots of test:
WARNING
I have to remind you even though Edit works but others still have same problems.
_Layout.cshtml was added to each Views from _ViewStart.cshtml.
The layout specified can use a full path (for example, /Pages/Shared/_Layout.cshtml or /Views/Shared/_Layout.cshtml) or a partial name (example: _Layout). When a partial name is provided, the Razor view engine searches for the layout file using its standard discovery process. The folder where the handler method (or controller) exists is searched first, followed by the Shared folder. This discovery process is identical to the process used to discover partial views.
The details about Layout in ASP.NET Core.
Related
controller not sending to view . I m trying to send request from controller to view , but its not redirecting . controller always redirect to index page. when i summit the form . its always redirecting same index page ,
controller not sending to view .controller not sending to view
My controller is sending to another view. but its not working .
public IActionResult userLogin([FromBody] Users user)
{
string apiUrl = "https://localhost:44331/api/ProcessAPI";
var input = new
{
email = user.email,
password = user.password
};
string inputJson = (new JavaScriptSerializer()).Serialize(input);
WebClient client = new WebClient();
client.Headers["Content-type"] = "application/json";
// client.Encoding = Encoding.UTF8;
string json = client.UploadString(apiUrl + "/userLogin", inputJson);
// List<Users> customers = (new JavaScriptSerializer()).Deserialize<List<Users>>(json);
user = JsonConvert.DeserializeObject<Users>(json);
return View();
}
and the view page is
#addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
#model myproject.Models.Users
#{
Layout = null;
}
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Inventory Management System</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.3/umd/popper.min.js" integrity="sha384-vFJXuSJphROIrBnz7yo7oB41mKfc8JzQZiCq4NCceLEaO4IHwicKwpJf9c9IpFgh" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/js/bootstrap.min.js" integrity="sha384-alpBpkh1PFOepccYVYDB4do5UnbKysX5WZXm3XxPqe5iKTfUKjNkCk9SaVuEZflJ" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" integrity="sha384-PsH8R72JQ3SOdhVi3uxftmaW6Vc51MKb0q5P2rRUpPvrszuE4W1povHYgTpBfshb" crossorigin="anonymous">
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
#* <link rel="stylesheet" type="text/css" href="./includes/style.css">*#
#*<script type="text/javascript" rel="stylesheet" src="~/js/main.js"></script>*#
</head>
<body>
<div class="overlay"><div class="loader"></div></div>
<!-- Navbar -->
<br /><br />
<div class="container">
<div class="alert alert-success alert-dismissible fade show" role="alert">
#*<?php echo $_GET["msg"]; ?>*#
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
#*<?php
}
?>*#
<div class="card mx-auto" style="width: 20rem;">
<img class="card-img-top mx-auto" style="width:60%;" src="./images/login.png" alt="Login Icon">
<div class="card-body">
<form id="form_login" >
<div class="form-group">
<label for="exampleInputEmail1">Email address</label>
#*<input asp-for="Name" type="text" class="form-control" id="name" required />*#
<input asp-for="email" type="email" class="form-control" id="log_email" placeholder="Enter email">
<small id="e_error" class="form-text text-muted">We'll never share your email with anyone else.</small>
</div>
<div class="form-group">
<label for="exampleInputPassword1">Password</label>
<input type="password" class="form-control" name="log_password" asp-for="password" id="log_password" placeholder="Password">
<small id="p_error" class="form-text text-muted"></small>
</div>
<button type="submit" class="btn btn-primary"><i class="fa fa-lock"> </i>Login</button>
<span>Register</span>
</form>
</div>
<div class="card-footer">Forget Password ?</div>
</div>
</div>
<input type="text" id="txtName" />
<input type="button" id="btnGet" value="Get Current Time" />
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript">
$(function () {
$("#form_login").on("submit", function () {
var data = {
email: $("#log_email").val(),
password: $("#log_password").val(),
// Phone: $("#phone").val()
}
// data: $("#form_login").serialize(),
// var data = $("#form_login").serialize();
console.log(data);
$.ajax({
type: 'POST',
url: '/Process/userLogin',
// window.location.href = '#Url.Action("Process", "Dashboard")';
contentType: 'application/json; charset=utf-8',
data: JSON.stringify(data),
success: function (result) {
alert('Successfully received Data ');
console.log(result);
window.location.href = "Process/Dashboard";
// window.location.href = '#Url.Content("~/User/Home")';
// window.location.href = '#Url.Action("Process", "Dashboard")';
// window.location.href = DOMAIN + "/dashboard.php";
},
error: function () {
alert('Failed to receive the Data');
console.log('Failed ');
}
})
})
});
</script>
</body>
</html>
From your code, since you want to use JQuery Ajax to submit the form data to the action method, in the form submit event, you should use the event.preventDefault() to prevent the form submit action, then you can use JQuery Ajax to submit the form.
Second, does the Index page is the Process/Dashboard page? From your code, we can see in the Ajax success function, you will use the window.location.href to change the request URL, you can change the redirect page from here.
I am working on a very basic weather app to learn MVC architecture. However, I am having an issue with my page reloading once I submit the form and then data from that submission not coming over into the next newly rendered page.
Most of my logic for my page is in my controller.js file. In my view I have a form where the user fills in a city, and then my getWeather function makes an API call where it gets the city's temperature. From there my controller.js should re-render the index page, but pass in the string It is currently ${temp} °F in ${city}.
At least, that's how its supposed to work. Unfortunately when the page reloads the weather const is null and I then have my function catch the error and give me the message "that city is not available".
I have tested my API to make sure that it is correctly retrieving the data, by console.logging the res object, and I am getting that perfectly.
Also, I should note I bring in Weather function from my model. The only thing it does is test to see if the user inputted anything into the form and if they didn't it creates the error "Please enter the name of the city." I don't think it is the source of my issue or the fix for it.
I guess what I'm looking for is a way to prevent my page from reloading when I submit the form, or a way to not lose the data in my function when the page reloads. Any help would be greatly appreciated!
const axios = require('axios')
const API_KEY= "8d130a4fe5369b01d1fe629bccbe0926";
const Weather = require("../model/Weather")
exports.renderHomePAge = (req, res) => {
res.render("index")
}
exports.getWeather = (req, res, ) => {
const city = req.body.city
const url = `http://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${API_KEY}&units=imperial`
const weather = new Weather(city)
weather.validateUserInput()
if(weather.errors.length){
res.render("index", {error: weather.errors.toString()})
} else {
axios.get(url)
.then((response)=>{
// console.log(response)
const {temp} = response.data.main
const {city} = response.data.city
res.render("index", {
weather: `It is currently ${temp} °F in ${city}.`
})
})
.catch((err) =>{
console.log(err)
res.render("index", {
weather: `That city is not avaible`
})
})
}
}
exports.renderAboutPAge = (req, res) => {
res.render("About")
}
I don't think its neccessary for this issue, but just incase here is my index.hbs file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="">
<title>Weather | Home</title>
<!-- Bootstrap core CSS -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav"
aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav">
<li class="nav-item active">
<a class="nav-link" href="/">Home <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="/about">About</a>
</li>
</ul>
</div>
</nav>
<!-- Page Content -->
<div class="container">
<div class="row">
<div class="col-lg-12 text-center main">
<div>
<h1 class="mt-5">MVC Weather Finder</h1>
<p class="lead">Enter the name of the city and press search!</p>
</div>
<div>
<form action="/" method="post">
<input name="city" type="text">
<button>Go!</button>
</form>
<div class="mt-3">
{{weather}}
{{error}}
</div>
</div>
</div>
</div>
</div>
</body>
</html>
It turns out I was pulling data from my response object incorrectly and that was causing the issue.
I have a view like this
#model IEnumerable<DuckingOctoBear.Models.PostViewModel>
<p>
#if (User.IsInRole("Administrator") || User.IsInRole("Editor"))
{
#Html.ActionLink("Create New", "Create")
}
</p>
<div class="">
#foreach (DuckingOctoBear.Models.PostViewModel item in Model)
{
<a href="/Posts/Details/#item.Post.Id" class="post-element">
<h4>#Html.DisplayFor(modelItem => item.Post.Title)</h4>
<h6>
Inserted by #item.User.UserName at #item.Post.Date.ToString("dd MMMM yyyy hh:ss")
</h6>
<article>
#Html.Raw(item.Post.Text)
</article>
<span>
#if (User.IsInRole("Administrator") || User.IsInRole("Editor"))
{
#Html.ActionLink("Edit", "Edit", new { id = item.Post.Id })
<span>|</span>
}
#Html.ActionLink("Details", "Details", new { id = item.Post.Id })
<span>|</span>
#if (User.IsInRole("Administrator"))
{
#Html.ActionLink("Delete", "Delete", new { id = item.Post.Id })
<span>|</span>
}
</span>
</a>
}
</div>
...where I would like include a Javascript file which have strong dependencies to other Javascript files already included in the _Layout.cshtml
<div class="container body-content">
#RenderBody()
<hr />
<footer>
<p>© #DateTime.Now.Year - My ASP.NET Application</p>
</footer>
</div>
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/bootstrap")
How can I include that local file without register it in a bundle, and so for all views?
Ok epic fail
for this _Layout.cshtml
<div class="container body-content">
#RenderBody()
<hr />
<footer>
<p>© #DateTime.Now.Year - My ASP.NET Application</p>
</footer>
</div>
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/bootstrap")
#RenderSection("scripts", required: false)
I could add just a new section
#RenderSection("LocallyScriptLibrary", required: false)
then in the target view doing just:
#section LocalScriptLibrary{
<script src="~/Scripts/LocalLibrary.js"></script>
}
I'm using the standard MVC4 template in VS 2012. It came with a _layout.cshtml file which is as follows:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>#ViewBag.Title - iLoveSport</title>
<link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
<meta name="viewport" content="width=device-width" />
#Styles.Render("~/Content/css")
#Styles.Render("~/Content/kendo")
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/kendo")
#Scripts.Render("~/bundles/modernizr")
</head>
<body>
<header>
<div class="content-wrapper">
<div class="float-left">
<img src="~/Images/logo.png" alt="ILoveSport Logo" />
</div>
<div class="float-right">
<section id="login">
</section>
<nav>
<ul id="menu">
<li>#Html.ActionLink("Home", "Index", "Home")</li>
<li>#Html.ActionLink("AFL", "Index", "AFL")</li>
<li>#Html.ActionLink("NRL", "Index", "NRL")</li>
<li>#Html.ActionLink("State of Origin", "Index", "State of Origin")</li>
<li>#Html.ActionLink("Cricket", "Index", "Cricket")</li>
<li>#Html.ActionLink("Golf", "Index", "Gof")</li>
<li>#Html.ActionLink("Motorsport", "index", "Motorsport")</li>
<li>#Html.ActionLink("About", "About", "Home")</li>
<li>#Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>
</nav>
</div>
</div>
</header>
<div id="body">
#RenderSection("featured", required: false)
<section class="content-wrapper main-content clear-fix">
#RenderBody()
</section>
</div>
<footer>
<div class="content-wrapper">
<div class="float-left">
</div>
</div>
</footer>
#Scripts.Render("~/bundles/jquery")
#RenderSection("scripts", required: false)
</body>
</html>
The _viewstart.cshtml contains the following:
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
What must be modified so that the navigation in my _layout.cshtml page is suppressed on the home page only? The home page needs to have a button that will then trigger the inner page which is currently my home page. Do I create a new layout file suppressing the menu and change viewstart to load it instead? Or, can this be done via another means?
Thanks for your help and guidance.
Update:
My Home Controller now is as follows:
[ChildActionOnly]
public ActionResult NavigationMenu()
{
string controller = ControllerContext.
ParentActionViewContext.RouteData.Values["controller"].ToString();
string action = ControllerContext.
ParentActionViewContext.RouteData.Values["action"].ToString();
if (controller == "Home" && action == "Index")
return Content("");
else
return PartialView("_Menu");
}
My _layout.cshtml is as follows:
<nav>
#Html.Action("NavigationMenu","Partial")
</nav>
However, I receive a debug error stating:
System.Web.HttpException: The controller for path '/' was not found or does not implement IController.
This error is thrown on the layout.cshtml file. How should this be remedied?
You can define your navigation menu as partial view. And render this partial view in your layout.
Inside action method of this partial view, you can check for the controller and action. If it is your home page you can return empty content. Otherwise, return your navigation menu.
Partial View
<nav>
<ul id="menu">
<li>#Html.ActionLink("Home", "Index", "Home")</li>
<li>#Html.ActionLink("AFL", "Index", "AFL")</li>
<li>#Html.ActionLink("NRL", "Index", "NRL")</li>
<li>#Html.ActionLink("State of Origin", "Index", "State of Origin")</li>
<li>#Html.ActionLink("Cricket", "Index", "Cricket")</li>
<li>#Html.ActionLink("Golf", "Index", "Gof")</li>
<li>#Html.ActionLink("Motorsport", "index", "Motorsport")</li>
<li>#Html.ActionLink("About", "About", "Home")</li>
<li>#Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>
</nav>
Action Method
[ChildActionOnly]
public ActionResult NavigationMenu()
{
string controller = ControllerContext.
ParentActionViewContext.
RouteData.Values["controller"].ToString();
string action = ControllerContext.
ParentActionViewContext.
RouteData.Values["action"].ToString();
if(controller == "Home" && action == "Index")
return Content("");
else
return PartialView("_NavigationPartial");
}
Rendering Partial View
#Html.Action("NavigationMenu", "Partial")
I have not tested the code, but most of it should be fine.
This question already has answers here:
How to fix "Headers already sent" error in PHP
(11 answers)
Closed 9 years ago.
My web server shows me the following warning, and I think know where is the problem:
WARNING: CANNOT MODIFY HEADER
INFORMATION - HEADERS ALREADY SENT BY
(OUTPUT STARTED AT
/WWW/ZXQ.NET/A/L/E/ALEXCHEN/HTDOCS/TEST/INDEX.PHP:10)
IN
/WWW/ZXQ.NET/A/L/E/ALEXCHEN/HTDOCS/TEST/LOCALIZATION.PHP
ON LINE 14
But I don't know exactly how to solve it.
Any suggestions?
localization:
<?php
//set session and cookies
session_start();
header('Cache-control: private'); // IE 6 FIX
function get_lang(){
if(!empty($_GET['lang'])) return $_GET['lang'];
if(!empty($_SESSION['lang'])) return $_SESSION['lang'];
if(!empty($_COOKIE['lang'])) return $_COOKIE['lang'];
return 'en';
}
function set_lang($lang){
setcookie("lang", $lang, time() + (3600 * 24 * 30)); //line 14
$_SESSION['lang'] = $lang;
}
function get_lang_file($lang){
$lang_file = "languages/lang.$lang.php";
if(file_exists($lang_file)) return $lang_file;
if($lang_file = get_lang_file('en')) return $lang_file;
return false;
}
//set translation helper function
function l($string){
static $localization;
if(!isset($localization)){
$lang = get_lang();
$lang_file = get_lang_file($lang);
if($lang_file) set_lang($lang);
$localization = include $lang_file;
}
return $localization[$string];
}
?>
index.php:
<?php
include_once 'localization.php';
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<meta name="robots" content="index, follow"/>
<meta name="description" content="Web design and Translation / 網頁設計和翻譯" />
<meta name="keywords" content="web development, web developer, web design, web designer, translation, translator, taiwan, taipei, taichung, english, chinese, spanish, 網站開發者, 網頁設計, 網頁設計師, 翻譯, 翻譯著, 台灣, 台北, 台中, 英文, 中文, 西班牙文, html, css, javascript, php" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
<title>Alex Chen - Web design and Translation / 網頁設計和翻譯</title>
<link rel="stylesheet" type="text/css" href="styles/reset.css" />
<link rel="stylesheet" type="text/css" href="styles/global.css" />
<link rel="stylesheet" type="text/css" href="fancybox/jquery.fancybox-1.3.1.css" />
<?php if(get_lang() == 'zh-tw' || get_lang() == 'zh-cn') {echo '<link rel="stylesheet" type="text/css" href="styles/chinese.css" />';} ?>
</head>
<body id="home">
<div id="header">
<div class="container">
<ul id="lang">
<li <?php if(get_lang() == 'en') {echo 'class="current"';} ?>>ENGLISH</li>
<li <?php if(get_lang() == 'es') {echo 'class="current"';} ?>>ESPAÑOL</li>
<li <?php if(get_lang() == 'zh-tw') {echo 'class="current"';} ?>>中文(繁體)</li>
<li <?php if(get_lang() == 'zh-cn') {echo 'class="current"';} ?>>中文(简体)</li>
</ul>
<div id="logo-bg">
<h1><a>ALEXCHEN</a></h1>
</div>
<div id="nav-bg">
<ul id="nav">
<li><?php echo l('nav1'); ?></li>
<li><?php echo l('nav2'); ?></li>
</ul>
</div>
</div><!-- .container -->
</div><!-- #header -->
<div id="content">
<div class="container">
<div class="showcase">
<div class="first">
<div id="nopic">
<p><?php echo l('tagline_p'); ?></p>
</div>
</div><!-- .first -->
<div class="pusher">
<h3><?php echo l('showcase1_h3'); ?></h3>
<p><?php echo l('showcase1_p'); ?></p>
<div class="pic">
<a id="showcase1" href="showcase/showcase1.php"><img src="images/showcase1t.png"/></a>
</div><!-- .pic -->
</div><!-- .pusher -->
<div class="pusher">
<h3><?php echo l('showcase2_h3'); ?></h3>
<p><?php echo l('showcase2_p'); ?></p>
<div class="pic">
<a id="showcase2" href="showcase/showcase2.php"><img src="images/showcase2t.png"/></a>
</div><!-- .pic -->
</div><!-- .pusher -->
<div class="pusher">
<h3><?php echo l('showcase4_h3'); ?></h3>
<p><?php echo l('showcase4_p'); ?></p>
<div class="pic">
<a id="showcase4" href="showcase/showcase4.php"><img src="images/showcase4t.png"/></a>
</div><!-- .pic -->
</div><!-- .pusher -->
<div class="pusher">
<h3><?php echo l('showcase9_h3'); ?></h3>
<p><?php echo l('showcase9_p'); ?></p>
<div class="pic">
<a id="showcase9" href="showcase/showcase9.php"><img src="images/showcase9t.png"/></a>
</div><!-- .pic -->
</div><!-- .pushed -->
<div class="pusher">
<h3><?php echo l('showcase5_h3'); ?></h3>
<p><?php echo l('showcase5_p'); ?></p>
<div class="pic">
<a id="showcase5" href="showcase/showcase5.php"><img src="images/showcase5t.png"/></a>
</div><!-- .pic -->
</div><!-- .pusher -->
<div class="pusher">
<h3><?php echo l('showcase8_h3'); ?></h3>
<p><?php echo l('showcase8_p'); ?></p>
<div class="pic">
<a id="showcase8" href="showcase/showcase8.php"><img src="images/showcase8t.png"/></a>
</div><!-- .pic -->
</div><!-- .pushed -->
<div class="pusher">
<h3><?php echo l('showcase6_h3'); ?></h3>
<p><?php echo l('showcase6_p'); ?></p>
<div class="pic">
<a id="showcase6" href="showcase/showcase6.php"><img src="images/showcase6t.png"/></a>
</div><!-- .pic -->
</div><!-- .pusher -->
<div class="pusher">
<h3><?php echo l('showcase7_h3'); ?></h3>
<p><?php echo l('showcase7_p'); ?></p>
<div class="pic">
<a id="showcase7" href="showcase/showcase7.php"><img src="images/showcase7t.png"/></a>
</div><!-- .pic -->
</div><!-- .pushed -->
</div><!-- .showcase -->
<div class="pusher">
<h3><?php echo l('showcase3_h3'); ?></h3>
<p><?php echo l('showcase3_p'); ?></p>
<div class="pic">
<a id="showcase3" href="showcase/showcase3.php"><img src="images/showcase3t.png"/></a>
</div><!-- .pic -->
</div><!-- .pusher -->
</div><!-- .container -->
</div><!-- #work -->
<div id="footer">
<div class="container">
<div id="footer-top">
<div id="about">
<h3><?php echo l('about_h3'); ?></h3>
<img src="images/profile.png"/>
<p><?php echo l('about_p'); ?></p>
</div>
<div id="info">
<h3><?php echo l('info_h3'); ?></h3>
<ul>
<li id="mobile"><p></p>0918051170</li>
<li id="gmail"><p></p>alexchen.net#gmail.com</li>
<li id="skype"><p></p>alexchen.net</li>
<li id="facebook">facebook</li>
</ul>
</div>
<div id="contact">
<h3><?php echo l('contact_h3'); ?></h3>
<p><?php echo l('contact_p'); ?></p>
<form id="sendmail" method="post" action="http://www.emailmeform.com/fid.php?formid=254816">
<label for="name"><?php echo l('form_label1'); ?></label>
<input type="text" id="name" name="FieldData0" />
<label for="email"><?php echo l('form_label2'); ?></label>
<input type="text" id="email" name="FieldData1" />
<label for="message"><?php echo l('form_label3'); ?></label>
<textarea type="text" id="message" name="FieldData2"></textarea>
<input id="button" type="submit" value="<?php echo l('submit'); ?>">
</form>
</div>
</div><!-- #footer-top -->
<div id="footer-bottom">
<div id="rights">
<p>Copyright © 2010 Alex Chen. All Rights Reserved. Hosted on Zymic. Contact form hosted on Email Me Form.</p>
</div>
<div id="ads">
<a id="nr" href="http://www.freedomain.co.nr/cheap_web_hosting.php" target="_blank"><img src="http://ruarmza.4u.com.ru/ch.gif" alt="Cheap Web Hosting Providers" width="88" height="31" border="0" /></a>
</div>
</div><!-- #footer-bottom -->
</div><!-- .container -->
</div><!-- #footer -->
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-13164175-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script><!-- google analytics -->
<script type="text/javascript" src="scripts/jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="scripts/jquery.validate.min.js"></script>
<script type="text/javascript" src="fancybox/jquery.fancybox-1.3.1.pack.js"></script>
<script type="text/javascript" src="scripts/jquery.scroll.min.js"></script>
<script type="text/javascript" src="scripts/custom.js"></script>
<?php if(get_lang() =='en') {echo '<script type="text/javascript" src="scripts/jquery-validate/val-en.js"></script>';} ?>
<?php if(get_lang() =='es') {echo '<script type="text/javascript" src="scripts/jquery-validate/val-es.js"></script>';} ?>
<?php if(get_lang() =='zh-tw') {echo '<script type="text/javascript" src="scripts/jquery-validate/val-zh-tw.js"></script>';} ?>
<?php if(get_lang() =='zh-cn') {echo '<script type="text/javascript" src="scripts/jquery-validate/val-zh-cn.js"></script>';} ?>
</body>
</html>
The cause of this error is that modifying the HTTP header requires that the HTTP header is not already sent to the client. And this happens when the first data is put out (either implicitly or explicitly). So with the first data that is put out, the HTTP header is sent along to the client and cannot be modified afterwards.
In your case, according to the error message, some function call tries to modify the HTTP header at /TEST/LOCALIZATION.PHP on line 10 but the output has already started at /TEST/INDEX.PHP on line 1.
To fix this you either need to make sure that the modification of the HTTP header happens before the first output is done (input-process-output model) or you buffer any output with PHP’s output control functions.
The problem seems to be that the function l() calls set_lang(), after content is already sent to the browser. Meanwhile, set_lang() is trying to set a cookie, which must be done in the header, before any content is sent to the browser.
swap your localization.php for this one..
<?php
session_start();
header('Cache-control: private'); // IE 6 FIX
get_localization();
function get_localization()
{
static $localization;
if( empty($localization) ) {
$lang = 'en';
if(!empty($_GET['lang'])) $lang = $_GET['lang'];
if(!empty($_SESSION['lang'])) $lang = $_SESSION['lang'];
if(!empty($_COOKIE['lang'])) $lang = $_COOKIE['lang'];
setcookie("lang", $lang, time() + (3600 * 24 * 30)); //line 14
$_SESSION['lang'] = $lang;
$lang_file = "languages/lang.$lang.php";
if( !file_exists($lang_file) ) {
if( !$lang_file = get_lang_file('en') ) {
return false;
}
}
include $lang_file;
$localization = $lang;
}
return $localization;
}
function l($string){
$l = get_localization();
return is_array($l) && isset($l[$string]) ? $l[$string]: $string;
}
?>
should sort it
make sure that there is no output before calling header(). also, check if your files have BOM(which comes before <?php and thus is output..).