I got a partialView that I would only like to render if the user is logged in.
Im thinking something like this:
View:
#Html.ActionLink("Text", "Method", "Controller")
<section id="events">
#Html.Partial("_CreateNewPost")
</section>
Controller:
[Authorize]
public ActionResult Method()
{
Code that renders the PartialView
return View();
}
This way, I would asume that a user that is not logged in will be sent to the login-page.
Thanks!
Edit:
So im wondering if its possible to create code in the method that renders the partial view.
The way it is now, the partial view gets rendered as soon as the page loads.
Sure it's possible. On your controller:
[Authorize]
[ChildActionOnly]
public ActionResult MyPartial()
{
//Do stuff...
return PartialView("_partialViewName");
}
and then in your view:
#Html.Action("MyPartial", "ControllerName")
This is useful in cases where you want to return different partial view, depending on some condition, or if you want to pass some data, like a viewmodel, to the View. The ChildActionOnly specifies that this view is only accessible when it's called from another view, so you can't just type /controller/MyPartial in the address bar.
You can use a child action:
[Authorize]
public ActionResult Method()
{
return PartialView("_CreateNewPost");
}
Then call it in your view:
#if(Request.IsAuthenticated)
{
Html.Action("Method","SomeController")
}
#Html.Partial("ViewName")
#{ Html.RenderPartial("ViewName"); }
Related
I have a controller where all of the action methods contain the same code:
[ActionName("pretty-url")]
public ActionResult Something() {
return PartialView();
}
[ActionName("another-pretty-url")]
public ActionResult SomethingElse() {
return PartialView();
}
I name my partial views in the pretty-url.cshtml format, and these get picked up fine and everything works.
As every action in the controller will always do exactly the same thing and return the same thing, I would like to just have my controller look for the correctly-named view and return it as above, without me having to explicitly implement it.
How would I do that?
TIA
I would create a single action and pass the view name as parameter.
public ActionResult Something(string viewName)
{
return PartialView(viewName);
}
I would add a new method to my controller with a string parameter and use it to load the correct partial view.
public ActionResult Show(string PartialName)
{
return PartialView(PartialName);
}
Now instead of using http://your.domain/pretty_url you will have to use http://your.domain/show/pretty_url but this will work with any new partial view you add later on.
I'm trying to mimic the webforms multiview functionality and the only way i can think of is to put a PartialView into a ViewData object? Something like the following:
View code:
<%= ViewData["PartialViewPlaceholder"] %>
Controller code:
if(//condition){
ViewData["PartialViewPlaceholder"] = partialView1;
} else {
ViewData["PartialViewPlaceholder"] = partialView2;
}
How would you go about this?
ViewData is meant to contain actual data, not views themselves, which contain markup and rendering code. Would it not be possible for you to do this:
public ActionResult MyActionMethod()
{
var model = new MyModel();
model.UsePartialView1 = false; // Tell the view not to use Partial View 1
return View("MyView", model);
}
And in the View MyView:
<% if (Model.UsePartialView1)
Html.RenderPartial("PartialView1", Model);
else
Html.RenderPartial("PartialView2", Model); %>
This will render either PartialView1 or PartialView2 using the same Model depending on the condition set by the Controller.
Or, to return a Partial View with a Model directly from your controller, instead of a normal View, you can do this:
public ActionResult MyActionMethod()
{
var model = ...
ViewData["MyViewData"] = ...
return PartialView("PartialView1", model);
}
This will return the Partial View PartialView1 directly to the client. This is mostly useful in AJAX scenarios, since the result will most probably not be an entire HTML page. Partial Views are .ascx files.
how can i do such thing in model or controller?
<%= Url.Action("Home"); %>
You could use the Url property in the controller:
public ActionResult Index()
{
string url = Url.Action("Home");
// Do something with the url
return View();
}
As far as the model is concerned you should avoid using such methods there. The model is passed to the view and the view has access to helper methods which can do the job.
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.
Is it possible for an ASP.NET MVC controller to create a new instance of a different controller and effectively delegate resonsibility to that?
Let's say for example that I have two controllers in the /Controllers/ directory:
public class HomeController : Controller
{
public ActionResult Index()
{
var otherController = new OtherController();
return otherController.ShowNumberOfThings(100);
}
}
public class OtherController : Controller
{
public ActionResult ShowNumberOfThings(int index)
{
return View(index);
}
}
...and a View called Views/Other/ShowNumberOfThings.aspx:
<%# Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="ViewPage<int>" %>
Number of things: <%= Model.ToString() %>
When I hit the url:
http://localhost/Home/Index
I want to be presented with a page that reads:
"Number of things: 100"
I would like to be able to persist temporary data between controller redirections without being forced to use the session object (TempData[""] uses the session object for cross-controller redirections). My real world case has a complex object which needs passing (not just an int) so using a URL/Cookie is out of the question, and session state is a no-no.
In WebForms at least we could use Server.Transfer and maintain any state in the HttpContext.Items collection. In MVC the only option I can see is to call the controller method directly passing in required arguments.
At the moment it's having trouble trying to resolve the view folder as the "context" is still running under the HomeController.
I guess where I am going with this is trying to cludge ASP.NET MVC into acting like a FrontContoller.
Any ideas?
EDIT
In the end we had to serialise everything into a session and use that. A shame, but I have heard that MVC2 will support serialising objects into a ViewState.
If you want to be presented with "Number of things: 100" when you hit the Index action why not directly render the corresponding view:
public class HomeController : Controller
{
public ActionResult Index()
{
return View("~Views/Other/ShowNumberOfThings.aspx", 100);
}
}
I think it would be preferred to use.
return RedirectToAction("Controller", "Action")
However I'm guessing you want to maintain the Url Home/Index.
If you're looking at the FrontController pattern then you should investigate writing a Custom ControllerFactory which inherits from DefaultControllerFactory then Override the CreateController method.
You can register your factory using the code below.
protected void Application_Start()
{
ControllerBuilder.Current.SetControllerFactory(new MyCustomControllerFactory();
RegisterRoutes(RouteTable.Routes);
}
In the Controller factory you have access to the RequestContext so you can change the RouteData as needed and delegate to the correct controller.
You could of course just set a a Custom route for Home/Index which goes to OtherController.ShowNumberOfThings()
routes.MapRoute("Home", "Home/Index/{id}",
new {controller = "Other", action = "ShowNumberOfThings", id = 100});
a different approach would be the use of partial views
instead of ~Views/Other/ShowNumberOfThings.aspx
you could put your view in ~Views/shared/ShowNumberOfThings.ascx
have both views ~Views/Other/ShowNumberOfThings.aspx and ~Views/Home/Index.aspx implement the partial view
public class HomeController : Controller
{
public ActionResult Index()
{
return View(100);
}
}
public class OtherController : Controller
{
public ActionResult ShowNumberOfThings(int index)
{
return View(index);
}
}
and in both views implement the partial view
<% Html.RenderPartial("~Views/shared/ShowNumberOfThings.ascx", ViewData.Model); %>
you can change the int for any object that will be passed to the model
Another possibility (similar to partial views) is to use Html.RenderAction. This allows for different view model classes and separate controller methods.
<% Html.RenderAction("yourActionName", "yourControllerName", routeValues); %>