Can you put a PartialView into a ViewData object? - asp.net-mvc

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.

Related

Pass list of categories to partial view

I have a partial view which will display list of Main Categories and under each Main Category all of its subcategories. But the problem is I don't know how can I pass this Category List to my partial view. Please check the code bellow. I've also attached my .edmx table map picture to give you better idea. Once I pass it to partial view I want to loop though all categories and sub categories to display them
[ChildActionOnly]
public PartialViewResult _GuestNav()
{
using (var db = new TestEntities())
{
db.Categories.ToList(); // get list from here
return PartialView("_GuestNav"); // then pass that list to partial view
}
}
Here is the main action code:
public ActionResult Categories()
{
using (var dbCtx = new DbContext())
{
var categories = dbCtx.Categories.Include(x => x.SubCategories).ToList()
return View(categories);
}
}
Then in your Categories.cshtml you will have the code as below:
#model IEnumerable<Categories>
<ul>
#foreach(var category in Model)
{
<li>#category.CategoryName
#if(category.SubCategories.Any())
{
Html.RenderPartial("~/Partial/_SubCategory.cshtml", category.SubCategories);
}
</li>
}
</ul>
At last you supply a partial view called _SubCategory.cshtml in the Partial folder of Category folder as below:
#model IEnumerable<SubCategory>
<ul>
#foreach(var subCategory in Model)
{
<li>#subCategory.SubCategoryName</li>
}
</ul>
In your case if you want to pass this list to the partial view you specified you can do it as below:
[ChildActionOnly]
public PartialViewResult _GuestNav()
{
using (var db = new TestEntities())
{
var categories = db.Categories.Include(x => x.SubCategories).ToList(); // Added the include if you want to add subcategories as well
return PartialView("_GuestNav", categories); // then pass that list to partial view
}
}
Yo can use model binding, pass a Model or ViewModel as a parameter and access it from the partial view. For example, in your _GuestNav action:
...
return PartialView("_GuestNav",db.Categories.ToList());
Here's a link on how to accomplish that.
Then you can bind the model in your view. For example:
...
#model IEnumerable<Categories>;
For more detail, check out the examples from the link.
The PartialView method has an override that accepts an object. You need to store the results of the db.Categories.ToList() call in a variable and pass that to the method like this:
using (var db = new TestEntities())
{
var cats = db.Categories.Include("SubCategories").ToList(); // get list from here
return PartialView("_GuestNav", cats); // then pass that list to partial view
}
Just make sure your partial view expects a list of categories as its model. Then, inside your view you can iterate over the model and display the subcategories.
You should also look into how to use a viewmodel for your views.
EDIT
You may need to use an include statement since navigation properties are generally lazy loaded. Updated my answer.

Method to render partial view

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"); }

Can i return different objects in views of same action method in Http get and Http Post?

I want to return an object on HTTPGet method and different object in HTTPPost method of the same action method in the controller, but i dont know what to write in the view, which model to get.
Here is the controller code , i have been trying
[HttpGet]
public ActionResult Create()
{
var intSrNo = Convert.ToInt64(TempData["sr_no"]);
MEntities obj_entity = new MEntities();
UDP_get_a_Result obj_proc = obj_entity.UDP_get_a(intSrNo).SingleOrDefault();
return View(obj_proc);
}
[HttpPost]
public ActionResult Create(Table_a obj_a)
{
if (ModelState.IsValid)
{
db.Table_a.AddObject(obj_a);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(obj_a);
}
i'm confused which model to write in view.(Table_a or UDP_get_a_Result) and i want both HttpGet to show values when the page is loaded and HttpPost when the submit is clicked.
View
#model ABC.models.Table_a
#{
ViewBag.Title = "Create";
}
A view can only be strongly typed to a single class. You cannot have different controller actions returning the same view and passing different models to this view. You could use view models: define a class which will hold all the information necessary for this view and then have your controller actions fill this view models and pass it to this view.
I think it would work to have the view typed to some base class (object) and then cast the model to whatever you needed it to be based on get/post. I wouldn't want to maintain it tho. :-D

render Url.Action in model

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.

ASP.Net MVC have An Action render another Action

I have two pages I need, and want to show for the url /index and /review. The only difference between the two pages is on the review I will have a review comment section to show and Submit button. Otherwise the two pages are identical. I thought I could create a user control for the main content.
However, if I could say under the Review action, flag to show review stuff and them return the rest of the index action.
How would you (generic you) do this?
Model example
public class MyModel
{
public bool ShowCommentsSection { get; set; }
}
Controller actions
public ActionResult Index()
{
var myModel = new MyModel();
//Note: ShowCommentsSection (and the bool type) is false by default.
return View(myModel);
}
public ActionResult Review()
{
var myModel = new MyModel
{
ShowCommentsSection = true
};
//Note that we are telling the view engine to return the Index view
return View("Index", myModel);
}
View (somewhere inside your index.aspx probably)
<% if(Model.ShowCommentsSection) { %>
<% Html.RenderPartial("Reviews/ReviewPartial", Model); %>
<% } %>
Or, if Razor is your cup of tea:
#if(Model.ShowCommentsSection) {
Html.RenderPartial("Reviews/ReviewPartial", Model);
}
// ... Make comment section visible
return Index();
Why don't you just always include the review comment form and use client side code to show or hide it. Considering no additional data is required for the review page beyond that of which already needed on the index a round trip to a controller is not necessary. This would allow you to delete the review action and view.

Resources