The goal is to have one page with a wizard. Each step of the wizard is a partial view containing a form. I have only one controller (Insurance) with an action for each view. The actions receive the posted data and return the viewmodel for the next step, or the viewmodel of the current step containing the error details.
The page (Index.cshtml) has partial views, rendered as
#Html.Partial("~/Views/Shared/_RegistrationCode.cshtml")
and the partial view itself contains a form, rendered as
#using (Html.BeginForm("RegistrationCodeDetails", "Insurance", FormMethod.Post)) {
and a
<input type="submit" name="nextButton" value="Verder" class="btn btn-success" />
within the form to submit it.
The code works as intended up to the point where the first action returns the viewmodel for the next step (partial view _Product) using
return PartialView("_Product", productViewModel);. The ActionResult is not sent to the partial view, but rendered as a full view, so the result is a partial being rendered as the only thing on the screen.
I've fiddled with #using (Ajax.BeginForm("RegistrationCodeDetails", "Insurance", new AjaxOptions { UpdateTargetId = "articleProductOutput", HttpMethod = "Post" })) { but the data is not rendered in the second wizard step partial.
Edit:
We've decided to take a different approach: One page, one controller and basically one viewmodel. The initial data is rendered right away, data depending on other steps in the wizard is retrieved using JSON and partial views.
Unless you mark your partial view as [ChildActionOnly], it won't load in the same page!
you Partial view should look like
[ChildActionOnly]
public ActionResult _ParialView1()
{
//TODO: Add the required code here
}
//and your PartialView should be included in the main view as :
#{Html.Action("_PartialView1","Controller1");}
Thanks and hope this helps!
Related
How do I render a full fledged view (not partial view) inside another view?
Scenario, I have different controller and want the exactly same view to render which is already there under other controller with different layout.
I have Wishlist page in Home Controller which shows list of added products, and when user logged in , when I click on wish list it also show me navigation when user is signed in.
How would I do that??
Not many developers know about this but you can use RenderPage, it's specifically designed for that purpose(to render an MVC view inside another view)
#RenderPage("~/Views/Shared/SampleView.cshtml")
You can still create or use a partial view with its own controller and use the RenderAction()
[ChildActionOnly]
public ActionResult ActionPartialView(string p1)
{
//code...
return PartialView();
}
The above code can be in any controller, its own controller, just call it in razor with that controller.
Razor:
#{ Html.RenderAction("Index", "Home"); }
Hope that helps
I am new to MVC and just have learned about partial views.
What are the differences/advantages between separate controller per partial view vs only one controller per view (containing multiple partial views)?
Some definitions
PartialView are pieces of code you use to add into a View or a result from an Action.
View is a page you want to show to a user and it is returned by an Action from a Controller.
All .cshtml are consider by asp.net mvc as a View, depending on the way you treat the object, it becomes partially or not. (Html.RenderPartial, PartialView controller method, etc..).
What you can do?
Sometimes you need to return just a piece and you can do it by a async request (using ajax). In these cases, you use an action that returns a Partial View.
Sometimes you need to implement an View that need to add a piece of code, so, you can render it using a Partial View.
You can have an View inside the View/Shared folder and this view could use an Partial View. The Partial View could be into the specific folder of the View. For sample:
Views
Product
Item.cshtml // Partial view
Shared
Index.cshtml // View
The content on the Index.cshtml file is:
<div>
#Html.Partial("Item")
</div>
and you have an controller like this:
public class ProductController : Controller
{
public ActionResult Index()
{
return View();
}
}
It will find an View in Product and not found, after will find in the Shared folder and render. The view in shared folder uses the Partial View, so, the context of the execution is in Product and it will render the Item.cshtml partial view from Product Folder.
If you do in your controller this:
public class ProductController : Controller
{
public ActionResult Index()
{
return PartialView();
}
}
It will return just the process of Index.cshtml without any layout page, because you treat it as a Partial View.
Its some advantages you can use of Partial Views.
Currently I have a partial view where I manually display all my blog categories with links. I would like to make it dynamic by pulling from the database. I am not sure how to accomplish this within a partial view. I would even be willing to do it within the actual _layout page if it's easier that way.
Here is what I have right now.
_Categories.cshtml
<h2>Categories</h2>
<hr/>
<p>
ASP.Net MVC<br/>
Ruby on Rails<br/>
</p>
I would like to create these links dynamically as opposed to hard coding.
_Layout.cshtml
#Html.Partial("_Categories")
The main problem is there is no controller for the layout of a partial which is why I can't figure out how to go about it.
Thanks in advance for any help.
Create a controller action named ListCategories in BlogController (or in a new CategoryController). Add all the categories to the ViewBag in the action by querying them from your back-end database
public ActionResult ListCategories()
{
ViewBag.Categories = db.Categories;
}
And use a #foreach loop in the view for the action ListCategories.cshtml:
<h2>Categories</h2>
<hr/>
<p>
#foreach(Category c in ViewBag.Categories)
{
#c.Name<br/>
}
</p>
Finally, change your _Layout.cshtml to point to this action:
#Html.Action("ListCategories")
// or #Html.Action("ListCategories", "CategoryController")
I have a page that has a search function in a controller which works well
[HttpPost]
public virtual ActionResult Search(SearchModel model)
{
...adds to IEnumerable and such
return View(model);
}
My problem is I have another page with a search box, which I need to redirect to the same view as above. (parameters in the URL is not an option)
#using (Html.BeginForm("Search", "Home", FormMethod.Post, null))
{
#Html.TextBoxFor(t => t.SearchModel)
<input.....
}
but it's not loading up the right URL, it's just adding it to the current one. so instead of example.com/Home/Search it's adding it to the end of where that form is currently located. So if the page was in example.com/About/SearchPage its adding the t.SearchModel to the About/Searchpage
Edit: I have two different Controllers and Views, ControllerA and ViewA works fine, it brings back the search results. I want ViewB, which has an input box, to call ViewA and use ControllerA search technique
You have a nested form. This is not valid HTML. HTML does not allow you to put one form inside another form. You can have more than one form on a page, but you cannot nest them.
I'm also not sure what you mean by "another section", do you mean the #section keyword in Razor? Or do you mean an MVC area? Or something else?
On my site, I want to display a Login box on all pages. So I wanted to make a partial view page, which I use on my _Layout.cshtml file in Shared.
But where would the controller for this partial view go? And how would my Login button have access to it?
So, when the Request.IsAuthenticated is true, the login box shows 'Logged in as ...', but when the result is false, I get a little table with the usual Username/Password form.
Edit: After trying some answers below, I seem to be stuck in an endless lopp on the GET method below. It it because my partial view is trying to load me _Layout.cshtml file, as it want to accosiate the 'masterpage' with the partial view? And because my partial view is being rendered in _Layout.cshtml, it's lopping?
public class LoginController : Controller
{
//
// GET: /Login/
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(LoginModel loginModel)
{
if(ModelState.IsValid)
{
var g = new GallaryImage();
var user = g.LoginUser(loginModel.Username, loginModel.Password);
if(user != null)
{
FormsAuthentication.SetAuthCookie(user.username, false);
return RedirectToAction("index", "Home");
}
ModelState.AddModelError("", "Invalid Username/Password");
}
return View();
}
In my _Layout.cshtml, I am trying to load the partial view like this:
<div style="text-align: right">
#Html.Action("Index", "Login")
</div>
See the issue?
FYI, Views don't have controllers. Controllers have Views. The distinction may seem subtle, but it's not. A view can be used by any number of controllers, and views don't care or know about the controllers. So you have to think about the current URL, which means the current Action Method.
In the case of your login partial, it doesn't need much if anything from the Controller. It's directly accessing the User property of the page to find out if it's authenticated. Your login button is just a form with it's action method set to your login method of your account controller.
Even the username can be displayed from the User property of the page.
Just look at the default MVC app that is generated when you create a new Internet project. It has all this functionality already implemented. Just copy it.
You can give controller name as attribute to Html.Action method
Html.Action("ActionName", "ControllerName")
If you use Razor syntax, you must write #Html.Action("ActionName", "ControllerName") in your view and your Action with name ActionName should return PartialView(which wil be your login area).
Try to use HTML.RenderAction("Action", "Controller") and make sure you are not calling your master page from within the partial view. This has the potential to produce a loop.
I'm using MVC 3 ASPX view engine not razor though.