Use controller result from other mvc project within solution - asp.net-mvc-4

I've got a new solution that contains several project 'groups'. Each group contains a Cloud Project, a Web Role Project and a Test Project. All Web Role Projects are MVC4.
One of the Web Roles is the entry point for the visitor. Parts of what the visitor will see, should come from the other Web Roles from within the solution. I cannot get it working and after spending several hours googling, I still cannot solve it. Maybe anyone can be helpful on this issue.
For example, I need to fill the header content with data that I can get from one of the other Web Roles. Let's call that controller HeaderController. The controller in the main project (HomeController) looks like this:
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application.";
//var headerController = new Generic.HeaderFooterContainer.Controllers.HeaderController();
//var foo = headerController.Index().ExecuteResult();
//ViewBag.Header = headerController.;
return View();
}
In the comments are some things I've tried to debug some things.
Here's the page layout of the main project. The body is still empty, as this problem is just about the page header which could be placed as html from the ViewBag or ViewData or even with an own #section.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta charset="utf-8" />
<title>#ViewBag.Title</title>
<link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
<meta name="viewport" content="width=device-width" />
#Styles.Render("~/Content/css")
#Scripts.Render("~/bundles/modernizr")
</head>
<body>
<div class="headerHolder">
<div class="innertube">
<div id="header">
#ViewBag.Header
</div>
</div>
</div>
<div class="contentHolder">
<div class="innertube">
<div id="content">
#RenderBody()
</div>
</div>
</div>
<div class="footerHolder">
<div class="innertube">
<div id="footer">
</div>
</div>
</div>
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/bms")
#RenderSection("scripts", required: false)
</body>
</html>
The problem I face is that I just can't find out how I should make this work. How do I get the data in the header? A few things I've noticed are:
If I run the HeaderFooterContainer project in its dedicated solution, it works alright (I can get /Header and get the expected response displayed in the browser window)
If I run the Main project, I can see the home page, but if I ask for /Header, it can find the controller, but not the view. It's probably looking for the view in the main project although it is located in the HeaderFooterContainer project.

Related

why RenderPage is not recognized?

This is discouraging me - I'm using the latest version of .NET core, SDK, visual studio 2019,
Started new project - ASP.net core Razor pages, I'm tring to add #RenderPage("") without success.
It looks like it is not part of abstract class RazorPage (that inherit RazorPageBase, at the Microsoft.AspNetCore.Mvc.Razor namespace (part of dotnet\packs\Microsoft.AspNetCore.App.Ref\3.1.3\ref\netcoreapp3.1\Microsoft.AspNetCore.Mvc.Razor.dll))
Everything I try, there is an error that says:
Error CS0103 The name 'RenderPage' does not exist in the current context
my _Layout page looks like this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>#ViewData["Title"] - TestApp</title>
#*<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />*#
<link rel="stylesheet" href="~/css/site.css" />
</head>
<body>
<div>
#RenderPage("/Shared/_MenubarPage")
</div>
<div class="container">
<main role="main" class="pb-3">
#RenderBody()
</main>
</div>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
#RenderSection("Scripts", required: false)
</body>
</html>
(Of course I have partial _MenubarPage.cshtml page within Shared folder)
Can anyone please tell me where am I doing wrong? Should I add some kind of an external nuget?
Try the following code snippet in (the asp.net core 3.1) _layout page.
<partial name="_MenubarPage" />
You can use #RenderPage("_MenubarPage.cshtml");.
You can also use #RenderPage("_MenuPage.cshtml", MyModel) which allows you to supply any model you like to the view by including it as a second parameter.
You can also use #{Html.RenderPartial("_MenubarPage");} if you are using a partial. But don't forget that you need to wrap it with the razor code block #{}

How can I get font awesome icons to show up on the pages for account management in Asp.Net Core Identity?

In my app's main _Layout.cshtml, I am linking to the Font Awesome stylesheet:
<link rel="stylesheet" href="~/lib/fontawesome/css/all.css" />
... and icons are appearing where I expect them to. Except for the razor pages concerning account management under Identity.
The _Layout.cshtml-file for account management sits in /Areas/Identity/Pages/Account/Manage. It does not contain <html>, <head> or <body>-tags, so there's no place there to add a <link rel.... I am however able to get icons working if I add those tags in, but that results in a nested set of tags, and is a hacky workaround.
Icons are displayed in these files (among others):
Areas/Identity/Pages/Account/Register.cshtml
Areas/Identity/Pages/Account/Login.cshtml
But not in these (among others):
Areas/Identity/Pages/Account/Manage/Index.cshtml
Areas/Identity/Pages/Account/Manage/Email.cshtml
How can I get it working for the files inside ../Manage/ without "hacking"?
The _Layout.cshtml-file for account management sits in /Areas/Identity/Pages/Account/Manage.
It does not contain , or -tags, so there's no place there to add a <link rel....
To add reference to fontawesome css file(s), you can directly link to style sheet file of fontawesome icons in Account/Manage/_Layout.cshtml page, like below.
#{
Layout = "/Areas/Identity/Pages/_Layout.cshtml";
}
<link href="~/fontawesome/css/all.css" rel="stylesheet" />
<h1>Manage your account</h1>
<div>
<h4>Change your account settings</h4>
<hr />
<div class="row">
<div class="col-md-3">
<partial name="_ManageNav" />
</div>
<div class="col-md-9">
#RenderBody()
</div>
</div>
</div>
#section Scripts {
#RenderSection("Scripts", required: false)
}
Besides, if you also specify /Areas/Identity/Pages/_Layout.cshtml as the layout page of Account/Manage/_Layout.cshtml as above, adding reference to ~/fontawesome/css/all.css in section of /Areas/Identity/Pages/_Layout.cshtml page would works too.
Test Result

Navigating to different views without reloading entire page

I have a layout page that has one dropdown box. I created 3 views that will make use of this
layout. The value selected in the dropdown will be used in all 3 views created.
I have actionlinks used for navigation in the layout. Here is what I will like to achieve
Avoid reloading the entire page(layout) when I navigate from view to view since I want to keep
the dropdown value selected.
How can I achieve this such that it is only the content of the views that will be changing
when I navigate from page to page by clicking on the action links. The value of dropdown selected
must always remain the same unless changed by user
#model Company.Domain.Classes.Companyviewmodel
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>#ViewBag.Title</title>
<link href="~/Content/Site.css" rel="stylesheet" />
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
</head>
<body>
<div class="page">
#{
ViewBag.Title = "Project Status Maintenance";
}
<div id="MainContent1">
<div id="ProjID">
<label for="SelectProjID">Project:</label>
#Html.DropDownList("ddlprojects", Model.GetProjectInformationActive.ProjectsInfoSelectList, Model.GetProjectInformationActive.SelectedProject)
</div>
<ul>
<li class="pp1">#Html.ActionLink("Section1", "Index", "Home")</li>
<li class="pp2">#Html.ActionLink("Section2", "GetSection1Data", "Home")</li>
<li class="pp3">#Html.ActionLink("Section3", "GetSection2Data", "Home")</li>
</ul>
<hr class="divide" />
#RenderBody()
</div>
<footer>
<div class="ftrcontent">
<p>Got it !!</p>
</div>
</footer>
</div>
</body>
</html>
You can use ajax to do partial page loads. To start, give a css class to your links so that we can use those as our jQuery selectors when wiring up the ajax behavior.
#Html.ActionLink("Section1", "Index", "Home",null, new {#class="ajaxLink"})
#Html.ActionLink("Section2", "GetSection1Data", "Home", new {#class="ajaxLink"})
#Html.ActionLink("Section3", "GetSectionwData", "Home", new {#class="ajaxLink"})
Now you should have a container div in your page to which we will load the partial view content. May be your current view (index ?) , you can add a container view like this
<div id="pageContent"></div>
Now, let's listen to the click event on our links, get the content of the target page's via ajax and load to the container div. Assuming you have jQuery loaded to your page, we can use jQuery load() method.
$(function(){
//Load the first link's content on document ready
var firstLinkHref=$("a.ajaxLink").eq(0).attr("href");
$("#pageContent").load(firstLinkHref);
$("a.ajaxLink").click(function(e){
e.preventDefault();
$("#pageContent").load($(this).attr("href"));
});
});
Since we are loading partial page content to our placeholder div, we do not need to return the full markup(including layout) from your action methods, We just need to the partial view content. You may use the PartialView() method instead of View() method to achieve this.
public ActionResult GetSection1Data()
{
if(Request.IsAjaxRequest())
{
return PartialView();
}
return View();
}

Html.RenderPartial Works but Html.RenderAction not working (is blank) and no errors or exceptions

Here is what i am trying
Layout
<!DOCTYPE html>
<html lang="en">
<head>
<title>WebApp Name</title>
<meta charset="utf-8" />
</head>
<body>
<div id="menuContainer">
#{Html.RenderPartial("~/Views/CustomPartials/_MainMenuPartial.cshtml");} #*Works*#
#*#{Html.RenderAction("GetMenuStructure", "Custom");}*# #*Not working*#
</div>
<div>
#RenderBody()
</div>
</body>
</html>
Controller and Action method
namespace Webappl.Controllers
{
[Authorize]
public class CustomController : Controller
{
[AllowAnonymous]
[ChildActionOnly]
public ActionResult GetMenuStructure()
{
return PartialView("~/Views/CustomPartials/_MainMenuPartial.cshtml");
}
}
}
_MainMenuPartial.cshtml
<ul id="ul_MainMenuStructure">
<li>Guest Pg1</li>
<li>Guest Pg2</li>
<li>Guest Pg3</li>
</ul>
The problem is
#{Html.RenderPartial("~/Views/CustomPartials/_MainMenuPartial.cshtml");}
Renders the contents of _MainMenuPartial.cshtml into the layout perfectly.
While
#{Html.RenderAction("GetMenuStructure", "Custom");}
Does nothing. No errors. No exceptions. Just blank. If i place a break-point at
return PartialView("~/Views/CustomPartials/_MainMenuPartial.cshtml");
The break-point is getting hit. I press F5 and it goes forward without any error/exceptions but menu structure does not get rendered in the layout. All I have is a blank
<div id="menuContainer">
</div>
in the final rendered page when I view it in the browser.
I need to do it through the action method for certain custom logic to be executed. Thats why a render partial is not sufficient.
I was not able to find similar behavior reported any where including stackoverflow. It could be bad binging/googling skills.
Some help will be so greatly appreciated. Banging my head on it for 3 days now.
I simply changed
#Html.RenderAction("X", "Y")
To
#Html.Action("X", "Y")

Add Dynamically Links to jQuery Mobile

I read a lot about how to add stuff dynamically in jquery mobile, but I couldn't figure out how to add links.
Currently my solution looks like this:
Add a new Page - with id (id="list-1")
Creating a Link for it (href="#list-1")
This solution works perfectly in static pages, but I want to do it dynamically. I have tried a lot with page() and stuff like that but nothing helped me.
My questions are:
How do I add dynamic links & pages?
Did I choose the right way to use ids & anchors (#list-1) as links or is there another solution for jquery mobile?
Let me know if you need more information
To add dynamic links, I have found the easiest way is to just have an event listener waiting for a click on those links. This event listener then saves any parameters you want to pass into the next page you are visiting. You pass the parameters from the list element to the event listener by just specifying parameters within each "li" element.
(create the HTML for a list dynamically & store it into list-1-html)
$("div#my-page div[data-role=content]").html(list-1-html);
$("div.list-1 ul").listview();
$("div.list-1 ul").listview('refresh');
Then your event listener would look something like:
$('#my-page').delegate('li', 'click', function() {
passedParameter = $(this).get(0).getAttribute('passed-parameter');
});
When jQuery Mobile loads your next page, you'll probably want to load this page dynamically and you'll have this passedParameter variable available to you. To load the page dynamically, just add a listener that waits for JQM to try to load the page:
$('[data-role=page]').live('pageshow',function(e, ui){
page_name = e.target.id;
if (page_name == 'my-page-2'){
(do something with passedParameter)
}
});
This is the workflow I use with jQuery Mobile and it has been working just fine. I'm guessing in future releases, though, that they'll build in some kind of support for passing dynamic parameters to pages.
Any new enhancement to the DOM should be done before the page initializes. But by default JQM automatically initializes the page once the page is load in browser.
Hence first you need to set autoInitializePage property to false and then call initializePage() method after the new page and links are add to the document. Hope this helps.
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.css" />
<script src="http://code.jquery.com/jquery-1.8.2.min.js"></script>
<script>
$(document).bind("mobileinit", function(){
$.mobile.autoInitializePage = false;
});
</script>
<script src="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.js"></script>
<script>
$(document).ready(function() {
//add a link.
$("#page1 div[data-role='content']").append('Next Page');
//add a page.
$('body').append(' <div data-role="page" id="page2" data-title="next page"><header data-role="header" class="header"> <h5>Page 2</h5></header><div data-role="content"><h3>Good Morning...</h3>Back</div><footer data-role="footer" data-position="fixed"><h5>© All rights reserved</h5></footer></div>');
});
window.onload = function() {
$.mobile.initializePage();
};
</script>
</head>
<body>
<div data-role="page" id="page1">
<header data-role="header" class="header">
<h5>jQuery Mobile</h5>
</header>
<div data-role="content">
<form method="get" action="" data-transition="slideup">
<label for="email">Email:</label>
<input type="email" name="email" id="email" value=""/>
</form>
</div>
<footer data-role="footer" data-position="fixed"><h5>© All rights reserved</h5></footer>
</div>
</body>
</html>