No overload for method 'RenderPartial' takes 3 arguments - c#

This is driving me crazy, i am getting:
No overload for method 'RenderPartial' takes 3 arguments
a compresed version of my _layout:
<head>
#{
var footer = new footer(User);
var pageTitle = ViewData["Title"].ToString();
}
</head>
<body>
#{
Html.RenderPartial(
"_footer",
footer,
new ViewDataDictionary(this.ViewData) { { "pageTitle", pageTitle } }
);
}
</body>
in my shared _layout, i am trying to pass a model to the partial view and a string which is provided by ViewData not sure what is going on.
i am setting title from the page _mypage.cshtml that uses that layout:
#{
Layout = "~/Views/Shared/_Layout.cshtml";
ViewData["Title"] = "My Title";
}
<h1>Hello there</h1>
_footer is a partial view where i am using the footer object and also calling other partial view where i need the title.

You can do it using ViewBag.
MyController.cs:
// set the title on a ViewBag inside your action
ViewBag.pageTitle = "My Title";
_layout.cshtml:
// call your partial view passing the model
#Html.Partial("footer", footer);
_footer.cshtml:
<!-- use the ViewBag data with # -->
<h1>#ViewBag.pageTitle</h1>

Related

Render correct partial view with ajax call

I have a controller with partial views, for example I have a partial view , like this:
[HttpGet]
[AutorisatieFilter(Rol = "Personeelsdossier | Rekeningen#Lezen")]
public ActionResult Rekeningen()
{
var model = PersoneelsDossierService.GetRekeningLezenModel(Context, HuidigeDienstverbandId,GetMutatieRol(), Gebruiker.DienstverbandId);
SetMedewerkerSelectie(model);
model.IsBevoegd = true;
try
{
BeveiligingService.ControleerManagerBevoegdheidVoorDienstverband(Context, Context.Klant.Id, int.Parse(Context.Gebruiker.ExternId), HuidigeDienstverbandId, Gebruiker.DienstverbandId);
}
catch(AuthenticationException)
{
model.IsBevoegd = false;
}
return PartialView("~/Areas/MSS/Views/PersoneelsDossier/Rekeningen.cshtml", model);
//return View(model);
}
This is inside the controller name: Personeelsdossier.
The view of Rekeningen looks,like this:
Partial Views do not use the Layout, so they will not include CSS unless you have the CSS in the partial view - They are intended to be render into full views.
Just change the Partial View to a full view if you want to use the layout page, or add your CSS to the Partial View if you want the CSS but no layout...
In our Application, we have special Master pages for Partial Views to include Scripts and CSS for example.
1) Create a new Master Page cshtml in Views\Shared folder (for example, PopupMaster.cshtml). It holds a very basic HTML template:
<!DOCTYPE html>
<html lang="en">
<head>
<link href="~/Content/some.additional.css" rel="stylesheet">
</head>
<body>
#RenderBody()
<script src="maybe.some.additional.script.to.execute.js"></script>
</body>
</html>
2) Instead of return PartialView(...) you can now do return View("MyView", "PopupMaster", myModel);
This will result in a partialview-like result, but with possibility to provide extra css and scripts

how to show MVC4 Directory.GetFiles in view

I'm a beginner at programming and I'm trying to build a mvc application that can search a directory and display all the ones found in a view.I have an error message pop up when I search. If someone would tell me what I'm doing wrong or point me in the right direction it would be greatly appreciated.
error message is this:
> The view 'C:\Users\carrick\Downloads' or its master was not found or
> no view engine supports the searched locations. The following
> locations were searched:
> ~/Views/DirectorySearch/C:\Users\carrick\Downloads.aspx
> ~/Views/DirectorySearch/C:\Users\carrick\Downloads.ascx
> ~/Views/Shared/C:\Users\carrick\Downloads.aspx
> ~/Views/Shared/C:\Users\carrick\Downloads.ascx
> ~/Views/DirectorySearch/C:\Users\carrick\Downloads.cshtml
> ~/Views/DirectorySearch/C:\Users\carrick\Downloads.vbhtml
> ~/Views/Shared/C:\Users\carrick\Downloads.cshtml
> ~/Views/Shared/C:\Users\carrick\Downloads.vbhtml
my controller looks like this
public class DirectorySearchController : Controller
{
//
// GET: /DirectorySearch/
public ActionResult Index()
{
return View();
}
public ActionResult GetDirFiles(string directorySearch)
{
//first check directorySearch is a valid path
//then get files
Directory.GetFiles(directorySearch);
ViewBag.message = directorySearch;
return View(ViewBag.message);
}
}
}
and my view
#{
;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>GetDirFiles</title>
</head>
<body>
<div>
<h2>Search Results</h2>
<ul>
<li>#Viewbag.message;</li>
</ul>
</div>
</body>
</html>
This line:
return View(ViewBag.message);
You are telling it to render the view with the name of the directory files, hence why you are getting that error messaging. ViewBag is already passed into your view so you don't need to pass it yourself.
You most likely just want to have the empty parameter call of
return View();
Which will by default return the view of with the name of the method in your controller.
Besides that you are not passing the files to the view, you are passing the path. You will need to do something like this. Note the case of ViewBag(not Viewbag)
Controller:
ViewBag.message = string.Join(",", Directory.GetFiles(directorySearch));
View:
<li>#ViewBag.message</li>
Or you can write a simple loop in your view
Controller:
ViewBag.message = Directory.GetFiles(directorySearch);
View:
#foreach(string file in ViewBag.message)
{
<li>#file</li>
}
In this line
return View(ViewBag.message);
Change it to
return View();
The first argument is the ViewName. ViewBag is passed to the view ambiently/implicitly, so you dont need to pass it on.

Call an action method from layout in ASP.NET MVC

I have one layout and one partial view which are in the Shared folder. Partial view presents top menu items which are not static. So I need to call an action method to get menu items from database. To do this, I created a controller and add an action method in it.
When I try to browse the page in web browser, this error occured:
The controller for path '/' was not found or does not implement IController.
Note:
I tried Html.RenderAction, Html.Partial methods too...
And I tried to create another view folder, and create a new partial view and new controller that named with "folder name + Controller" suffix.
Layout:
<!DOCTYPE html>
<html>
<head>
<title>#ViewBag.Title</title>
</head>
<body>
<div id="header">
#Html.Action("~/Views/Shared/_TopMenu.cshtml", "LayoutController", new {area =""}); //Here is the problem.
</div>
<div>
#RenderBody();
</div>
</body>
</html>
_TopMenu.cshtml:
#model IList<string>
#foreach (string item in Model)
{
<span>item</span>
}
LayoutController (in Controllers folder):
public class LayoutController : Controller
{
//
// GET: /Shared/
public ActionResult Index()
{
return View();
}
[ChildActionOnly]
[ActionName("_TopMenu")]
public ActionResult TopMenu()
{
IList<string> menuModel = GetFromDb();
return PartialView("_TopMenu", menuModel);
}
}
What happens if you put this in your view?
#{ Html.RenderAction("TopMenu", "Layout"); }
(And comment this out until everything works: //[ChildActionOnly])
Change this line,
#Html.Action("~/Views/Shared/_TopMenu.cshtml", "LayoutController", new {area =""});
to,
#Html.Action("_TopMenu", "Layout", new {area =""});
and check.
exist differents ways, for this case I like use html.action in layout, and in control I will create a string Menu, the string contains the html code I need, the controller end with return Content(menu);
for example
Layout:
<body>
<nav>
#Html.Action("_TopMenu", "Layout")
</nav>
the controller
public class LayoutController : Controller
{
public ActionResult _TopMenu()
{
IList<string> menuModel = GetFromDb();
string menu = "<ul>";
foreach(string x in menuModel)
{
menu +="<li><a href='"+x+"'>+x+"</a></li>";
}
menu+="</ul>";
return Content(menu);
}
}
I like that because I can use many options to create menus dinamics more complexes.
other way use ajax to recovered the data and use handlebars or other template for the code
You are using the wrong overload of the Action-Method. The 2nd parameter in the variation is not the controllername but the actionname.
You can check the correct Method overloads on this page
Also: If you specify Controllers in the Html.Action Method (which you can do for example with this variation of the Method), you dont need to write the suffix "Controller" even if thats your Classname. So Instead of using the string "LayoutController" you would write simply "Layout".
At this point the framework is convention-based.
This is how I did it:
Layout
#Html.Action("GetAdminMenu", "AdminMenu")
Admin Menu Controller
public PartialViewResult GetAdminMenu()
{
var model = new AdminMenuViewModel();
return PartialView(model);
}
GetAdminMenu.cshtml
#model ReportingPortal.Models.AdminMenuViewModel
<div class="form-group">
<label class="col-md-4 control-label" for="selectbasic">School Name</label>
<div class="col-md-8">
#Html.DropDownListFor(model => model.SelectedID, new SelectList(Model.DataList, "Value", "Text", Model.SelectedID), "", new { #class = "form-control", #required = "*" })
</div>
</div>

What is the best way to set AngularJS $provide.constant values from a C# MVC Model?

I have an AngularJS application with a .NET MVC/WebAPI backend. I have one MVC action that serves up my main HTML page that loads my AngularJS app. This MVC action loads several application settings from the Web.config as well as the database and returns them to the view as a model. I'm looking for a good way to set those MVC Model values as $provide.constant values in my AngularJS .config method.
MVC Controller method:
public ActionResult Index() {
var model = new IndexViewModel {
Uri1 = GetUri1(),
Uri2 = GetUri2()
//...etc
};
return View(model);
}
My MVC _Layout.cshtml:
#model IndexViewModel
<!doctype html>
<html data-ng-app='myApp'>
<head>
#Styles.Render("~/content/css")
<script type='text/javascript'>
#if (Model != null) //May be null on error page
{
<text>
var modelExists = true;
var uri1 = '#Model.Uri1';
var uri2 = '#Model.Uri2';
</text>
}
else
{
<text>
var modelExists = false;
</text>
}
</script>
</head>
<body>
<!-- Body omitted -->
#Scripts.Render("~/bundles/angular", "~/bundles/app") //Loads angular library and my application
</body>
app.js:
"use strict";
angular.module('myApp', [])
.config(['$provide' '$window', function ($provide, $window) {
if ($window.modelExists){
$provide.constant('const_Uri1', $window.uri1);
$provide.constant('const_URi2', $window.uri2);
}
}]);
This is a vastly simplified version of my code but I think it illustrates my concern. Is there a better or standard way of doing this that I am overlooking? I don't like the code in my _Layout.cshtml because I have many more configuration values.
If you have a bunch of config values and you don't mind an extra network call, one way to do this is to create an MVC view that returns the settings as an Angular constant...
using System.Web.Script.Serialization;
// ...
public ActionResult Settings(string angularModuleName = "myApp")
{
var settings = new
{
uri1 = GetUri1(),
uri2 = GetUri1()
// ...
};
var serializer = new JavaScriptSerializer();
var json = serializer.Serialize(settings);
var settingsVm = new SettingsViewModel
{
SettingsJson = json,
AngularModuleName = angularModuleName
};
Response.ContentType = "text/javascript";
return View(settingsVm);
}
In the Razor view...
#model MyApp.SettingsViewModel
#{
Layout = null;
}
(function (app) {
app.constant('settings', #Html.Raw(Model.SettingsJson));
})(angular.module('#Model.AngularModuleName'));
In the pages that need the files, just add a script tag to bring in the constants...
#Scripts.Render("~/bundles/angular", "~/bundles/app") //Loads angular library and my application
<script src="/home/settings?appname=foo"></scripts>
This will return the script...
(function (app) {
app.constant('settings', {
"uri1": "https://uri1",
"uri2": "https://uri2"
});
})(angular.module('foo'));
Now you can inject the settings service anywhere in your Angular code. Nothing is leaked into the global scope.
You can also use this technique to inject the settings directly into a particular HTML view, but I generally prefer to split it out so that it is included only when needed.

Get the model of a partial view and use it in an action link

Let's say that I have this view:
#{
ViewBag.Title = "Send Items";
}
<h2>Sent Items</h2>
<p>
#using (Html.BeginForm())
{
Html.RenderAction("AdvancedSearchEngine", "PartialViews");
}
#Html.ActionLink("Back to Selection", "MenuSelection")
</p>
I want to add an html ActionLink that will get me to another view. I want to get all the model used in the partial view in this actionlink to create the list of items that will be displayed in this view.
Something like #Html.ActionLink("See the results", "DisplayItems", new {_myObject = "blablabla"}).
Is there any way to do that?
EDIT
I have added this method:
#Html.ActionLink("See the results", "DisplayItems", "DispatchItems", new { model = Model }, null);
But once the method actually hits, the object is still null.
Create a new action in your controller:
public ActionResult DisplayItems(MyModel model)
{
// Do stuff
return View(model);
}
Then use this AcitonLink in the SendItems view:
Html.ActionLink("See the results", "DisplayItems", "ControllerName", new { model = Model }, null);
I'm not sure if I understood completely this problem but lets try.
Use AjaxHelper to do this, makes more sense, and render a partial view. The ActionLink must have some information about the model that you want to show, can be an id or anything else. Then you can render this by clicking the link and without a full page refresh. Don't forget to include JQuery reference at the main view.
#{
ViewBag.Title = "Send Items";
}
<h2>Sent Items</h2>
<p>
#using (Html.BeginForm())
{
Html.RenderAction("AdvancedSearchEngine", "PartialViews");
}
#Ajax.ActionLink("Back to Selection", "MenuSelection", new {id = Model.Id}
new AjaxOptions { HttpMethod ="GET",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "results")
<div id="results"></div>
public ActionResult DisplayItems(int id)
{
// Do stuff
return PartialView("");
}
Hopes this help you!

Categories