Hey guys I've got this function:
if (Cookies.CheckIfCookiesExists())
{
int.TryParse(Cookies.getWorkerCookieId("u-Site_Admin"), out uid);
var worker = unitOfWork.Workers.Get(uid);
ViewBag.isSuperAdmin = worker.IsSuperAdmin;
}
I want to pass the isSuperAdmin property down to the layout, and I need a controller to do this check every time the user switches between tabs.
My home controller returns this view:
#{
Layout = "~/Views/Shared/_Layout.cshtml";
ViewBag.Title = "";
ViewBag.isSuperAdmin = ViewBag.isSuperAdmin;
}
Inside the layout what I care about is the Aside page:
#{ Html.RenderPartial("~/Views/Shared/partials/_aside.cshtml"); }
How would I go about achieving this? Basically the problem is the ViewBag value is lost like I've stated.
In the controller, set the ViewBag property.
Render the partial view within the view. Note that I'm using Html.Partial() instead of Html.RenderPartial.
The ViewBag property will be passed to the partial view.
Controller:
public class HomeController : Controller
{
public ActionResult Test()
{
ViewBag.isSuperAdmin = true;
return View();
}
}
View:
#{
ViewBag.Title = "Test";
}
<h2>Test</h2>
#Html.Partial("~/Views/Shared/partials/_aside.cshtml")
Partial View:
<h3>ViewBag.isSuperAdmin = #ViewBag.isSuperAdmin</h3>
Result:
Related
I'm new to MVC and trying to pass data from a view to page and am having two problems:
The ID that is in the page url is not being passed to the controller
(customers/details/1)
I cannot get the variable to be written to the page. (i've been told
to try avoiding the use of viewbag and viewdata).
My controller looks like this:
public class CustomersController : Controller
{
public ActionResult Details(int? pageIndex)
{
var Name = "Nope";
if(pageIndex == 1)
{
Name = "John Smith";
};
return View(Name);
}
}
}
My view look like this:
#{
ViewBag.Title = "Details";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Details</h2>
<p>#Model.Name</p>
I have the same child action placed in several parents actions, let's say there are these two parent views :
#model Parent1Model
#{
ViewBag.Title = "Parent1";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#Html.Action("Child","MainControler")
The second parent :
#model Parent2Model
#{
ViewBag.Title = "Parent2";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#Html.Action("Child","MainControler")
All actions are placed in the same controller.
public ActionResult parent1() //GET
{
Parent1Model model = new Parent1Model()
return View(model );
}
public ActionResult parent2() //GET
{
Parent2Model model = new Parent2Model()
return View(model );
}
public ActionResult Child() //GET
{
ChildModel model = new ChildModel()
return View(model );
}
[HttpPost]
public ActionResult Child(ChildModel model) //POST
{
DoThingsWithResult(model)
// The next line should return the get of the parent action
return RedirectToParent() // This does not exist...
}
Now, how do i tell the child to call his RIGHT parent's GET? Being the child of many parents, how can he know which parent called it this time ?
I could not find anything, neither on google nor in the "Questions that may already have your answer".
You can add one more param to determine where it is coming from,
you can also make this param a string which will be the parent action name itself and pass that param to your RedirectToAction(param)
Ex
[HttpPost]
public ActionResult Child(string ParentName, ChildModel model) //POST
{
DoThingsWithResult(model)
// The next line should return the get of the parent action
return RedirectToAction(ParentName) // This does not exist...
}
in your parent action
public ActionResult parent2() //GET
{
Parent2Model model = new Parent2Model();
ViewBag.Parent = "parent2";
return View(model );
}
in your view
#model Parent2Model
#{
ViewBag.Title = "Parent2";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#Html.Action("Child","MainControler", new {ParentName= ViewBag.Parent})
Do the same for Parent Action 1
I have created a Web rendering and try to get a specific Item by its path.
Something like this :
Item item=Sitecore.Context.Database.GetItem("/sitecore/content/home");
Is it possible to get item using #Model.Sitecore() ?
Thanks
I don't recommend it, but you can just get it in your view with #{ }
#{
var item = Sitecore.Context.Database.GetItem("/sitecore/content/home");
}
You should really move to a Sitecore controller rendering and do this work in the controller and return the Item as your model.
public class YourController : Controller
{
public ActionResult Stuff()
{
var item = Sitecore.Context.Database.GetItem("/sitecore/content/home");
return View(item);
}
}
Your view
#model Sitecore.Data.Items.Item
<div>
#Model.DisplayName
</div>
In asp.net MVC 3 is there a way to override the Layout declaration set in a view from a controller or action filter?
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
I have tried overriding the MasterName property in the OnResultExecuted or the OnResultExecuting like the following code snippet, to no avail.
public override void OnResultExecuting(ResultExecutingContext filterContext)
{
var view = filterContext.Result as ViewResult;
view.MasterName = null;
}
Another place where you can control the layout is in the _ViewStart.cshtml.
Here, you can do the logic you need and programatically specify which layout to use. This allows you to place the logic in only one place and keep it out of the view.
#{
if(myBusinessRule)
{
Layout = "~/Views/Shared/_Layout.cshtml";
}
else
{
Layout = "~/Views/Shared/_SecondaryLayout.cshtml";
}
}
Blog post where it was introduced by Scott Gu
You can create an action filter to override Layout file, but if you want to remove it, you will have to create an empty layout file instead of assigning the Master property to null. Like this:
public class OverrideLayoutFilter : ActionFilterAttribute
{
public override void OnResultExecuting(ResultExecutingContext filterContext)
{
var view = filterContext.Result as ViewResult;
view.MasterName = "_LayoutEmpty";
base.OnResultExecuting(filterContext);
}
}
Controller:
public class HomeController : Controller
{
[OverrideLayoutFilter]
public ActionResult Index()
{
return View();
}
}
Now your new layout file needs to be placed in SharedFolder and you only put the RenderBody function inside
_LayoutEmpty.cshtml
#RenderBody()
Note: If you have sections defined in a view that you want to override layout you will also have to define those sections with an empty content.
Use ViewBag
when you need to change the layout call an action and put the new layout (even null) in viewbag.
#{
Layout = ViewBag.layout;
}
and inside the action
if(something)
ViewBag.layout = "~/Views/Shared/whatever.cshtml";
else
ViewBag.layout = null;
sorry to simply add a ref to one of my previous posts on this subject, but have a look here, it may give a wider view (pun intended) on the topic:
Where and how is the _ViewStart.cshtml layout file linked?
I am experimenting with MvcContrib subcontrollers. Looking at the example in the source, your parent controller (HomeController) takes an action which takes the subcontroller (FirstLevelSubController) as a parameter:
public class HomeController : Controller
{
public ActionResult Index(FirstLevelSubController firstLevel)
{
ViewData["Title"] = "Home Page";
return View();
}
}
In Home's index view, you call ViewData.Get like this to render the subcontroller and it's view:
<div style="border:dotted 1px blue">
<%=ViewData["text"] %>
<% ViewData.Get<Action>("firstLevel").Invoke(); %>
</div>
The subcontroller's action gets called (ignore the secondlevelcontroller, the example is just demonstrating how you can nest multiple subcontrollers):
public class FirstLevelSubController : SubController
{
public ViewResult FirstLevel(SecondLevelSubController secondLevel)
{
ViewData["text"] = "I am a first level controller";
return View();
}
}
This all works, the subcontroller's view gets rendered inside the parent view.
But what if I need other parameters in my home controller's action? For example, I may want to pass a Guid to my controller's index method:
public class HomeController : Controller
{
public ActionResult Index(Guid someId, FirstLevelSubController firstLevel)
{
//Do something with someId
ViewData["Title"] = "Home Page";
return View();
}
}
There doesn't seem to be any way to do <% ViewData.Get("firstLevel").Invoke(); %> with parameters. So I can't figure out how to link to my controller from another controller passing a parameter like this:
Html.ActionLink<HomeController>(x => x.Index(someThing.Id), "Edit")
Perhaps I am approaching this the wrong way? How else can I get my parent controller to use a subcontroller, but also do interesting stuff like accept parameters / arguments?
Have a look at this blog post:
Passing objects to SubControllers
http://mhinze.com/passing-objects-to-subcontrollers/
Note that SubControllers are deprecated. They have been replaced with RenderAction.