Two partial views inside an MVC view - asp.net-mvc

I have the following scenario, where I have one model (named Model A) in a view (View1).
This view initially loads a partial view (Partial View 1)
On button click of partial view, I am trying to pass the id generated to another partial view (Partial View 2).
But I am getting an error saying View 1 cannot be found, which loaded without any issues on first run.
If I remove the else statement, the page successfully reloads after submission.
Any tips on passing this model object successfully to the other view please.
I put id=1 and tested it and the same error occured.
I tried RenderAction, RenderPartial and all these failed
Page
#model MyModel
#{
if (ViewBag.Created ==0) {
#Html.Partial("CreateView1",Model);
}
else
{
{ Html.Action("Action2", "Area/Controller2", new { id = Model.Id }); }
}
}
Controller methods:
Controller 1:Entry point of view
[Route("{CreateView1}")]
public ActionResult Create() {
ViewBag.Created = 0;
return View(new MyModel());
}
[Route("{CreateView1}")]
[HttpPost]
public ActionResult Create(MyModel model) {
...........................
ViewBag.Created = 1;
}
Controller 2 which renders 2nd partial view:
public PartialViewResult Index(int createdId)
{
return PartialView(new List<Model2>());
}

Regarding View 1 cannot be found, is because the keyword return in your second Create action is missing. The button click submits the form to the Create method with [HttpPost] attribute and the end of the method, it needs a return View.
Reg Any tips on passing this model object successfully to the other view please, The return in the second Create method should be return View(model); and not 'return View(new MyModel);` as later on in the View you are going to use the Model.
Re I put id=1 and tested it and the same error occured., because runtime never reachs that point as the operation is being handed to '[HttpPost] Create' and it never get back to your Original Page.
There are other issues with your code as you are using different names in your code than what you mention in your description...
A simple solution is:
1- use the following return at the end of you [HttpPost]Create Action:
return RedirectToAction("Action2", "Area/Controller2", new { id = model.Id});
2- replace the following code in your initial page
if (ViewBag.Created ==0) {
#Html.Partial("CreateView1",Model);
}
else
{
{ Html.Action("Action2", "Area/Controller2", new { id = Model.Id }); }
}
with the following:
#Html.Partial("CreateView1",Model);
and remove anywhere you set ViewBag.Created = 0 or ViewBag.Created =1
I also assume the action action2 in controller Controller2 returns a valid Partial View.
Hope this help you get some idea to fix your code.

You may have omitted this for brevity, but you will want to return a viewresult at the end of your post action:
return View(new MyModel());

try this:
if (ViewBag.Created ==0) {
#Html.RenderPartial("CreateView1",Model);
}

Related

Trying To pass list of data in from controller to partial view in mvc

I am trying to pass list of data through viewbag from controller to partial view but getting error
in login form after submitting data taking it from formcollection through HttPost and once action complete it return to home page from there i am calling method Page_Init inside that in 'loadmessage' method i am trying to return list to a partial view "Header" based on condition.but not able to perform getting error
Home controller
[HttpPost]
public ActionResult Login(FormCollection form)
{
return View("Home");
}
in Home.cshtml
calling method page_init in controller
$.get("/Home/Page_Init",null, function (data) {
alert(data);
});
Home controller
public ActionResult Page_Init()
{
loadMessages();
return view("Home");
}
public ActionResult loadMessages()
{
List<MessageModel> lstMessages = new List<MessageModel>();
List<MessageModel> lstInfoMessages = new List<MessageModel>();
lstInfoMessages = lstMessages.Where(msg => msg.MESSAGE_TYPE.Equals(CommonConstants.SAFETY_MESSAGE_INFO, StringComparison.InvariantCultureIgnoreCase)).ToList<MessageModel>();
if (lstInfoMessages.Count > 0)
{
ViewBag.lstInfoMessages = 1;
ViewBag.lstInfoMessages1 = lstInfoMessages;
return PartialView("Header", lstInfoMessages);
}
}
also trying to go to partial view from Home view
#ViewBag.lstInfoMessages1
#if (ViewBag.lstInfoMessages == 1)
{
#Html.Partial("Header",ViewBag.lstInfoMessages1)
}
Expected that list of information should go to partial view and bind
Error:Not getting Exact syntax what to do and how to proceed the steps tried above throw error
#Html.Partial method does not accept the dynamic value – so we need to cast it to the actual type.
#model MessageModel //you need to give correct path of MessageModel
#ViewBag.lstInfoMessages1
#if (ViewBag.lstInfoMessages == 1)
{
#Html.Partial("Header", (List<MessageModel>)ViewBag.lstInfoMessages1)
}
In Header Partial view, you can retrieve list using #Model

How to return multiple views in MVC

I’m just wondering if I have a view with two partial views on it. How can a single controller return more than one view?
e.g.
I have a search page with a search button.
You have to option to search by Organisation or a Service.
I have created two partial views to display the results as they are different in makeup.
These partial views appear on the main Search view.
Html.Partial("_OrgResult") // partialview of results
Html.Partial("_ServiceResult") // partialview of results
I have a controller like this
[HttpPost]
public ActionResult GetResults(int SearchType = 0, string SeartchTxt = "")
{
if (SearchType < 2)
{
return PartialView("~/Views/Search/_OrgResult.cshtml", GetOrganisationResults(SearchType, SeartchTxt));
}
else
{
return PartialView("~/Views/Search/_ServicehResult.cshtml", GetServiceResults(SearchType, SeartchTxt));
}
}
is this the correct way to do this ?
Will it even work ?
The best approach would be to have a single HTML.partial line in your view:
Html.Partial("Result") // partialview of results
Then, in your controller, return the view that corresponds to the parameters:
[HttpGet]
public ActionResult Results(int SearchType = 0, string SeartchTxt = "")
{
if (SearchType < 2)
{
return PartialView("~/Views/Search/_OrgResult.cshtml", GetOrganisationResults(SearchType, SeartchTxt));
}
else
{
return PartialView("~/Views/Search/_ServicehResult.cshtml", GetServiceResults(SearchType, SeartchTxt));
}
}

After an ajax post, I have problems for displaying results

I have a view named Index.cshtml with a table of users (create/edit/update functionalities).
When buttons (create/edit/update) are clicked I have a jQuery dialog for it. Next I use an ajax post like this:
Edit >> call an action controller for editing and return a json >> update row table with javascript
Delete >> call an action controller for deleting and return a json >> delete row table with javascript
Create >> call an action controller for creating and redirect to Index.cshtml >> ???
For the create part, I have a problem: I would like "simply" to display my view but I am in an ajax post. I don't know how to proceed.
Here is my code (submitting data and then refreshing the view):
$.post($(this).attr('action'), $(this).serialize(), function (data, status) {
$('#my-modal').modal('hide');
if (data.operation == 'edit') {
// Edit
var row = $('#' + data.userid);
row.children(':eq(0)').text(data.company);
row.children(':eq(1)').text(data.username);
row.children(':eq(2)').text(data.email);
row.children(':eq(3)').text(data.firstname);
row.children(':eq(4)').text(data.lastname);
} else if (data.operation == 'delete') {
// Delete
var row = $('#' + data.userid);
row.remove();
} else {
// Create
alert(data);
$("#userList").html(data);
}
})
As you can see, I check the data.operation which tells me if I do an 'edit' or 'delete' of (last possibility) a 'create'. For the create the problem is that my entire view (< html> < body>...) is generated and added in my #userList div. That's duplicate things.
Maybe that's not the right thing to do?
Thanks.
UPDATED
Here is my Create action:
[HttpPost]
public ActionResult Create(UserCreateViewModel viewModel)
{
if (!ModelState.IsValid)
{
this.Response.StatusCode = 400;
return PartialView("Create", viewModel);
}
var userDTO = new UserDTO();
Mapper.Map(viewModel, userDTO);
_requestServiceClient.CreateNewUser(userDTO);
return RedirectToAction("Index");
}
Here is my Index action:
[Authorize]
public ActionResult Index(string q, int? page)
{
var users = _requestServiceClient.GetUsers();
...
...
if (Request.IsAjaxRequest())
return PartialView(userListPaged);
else
return View(usersListPaged);
}
After relexion, in case of 'create' maybe it is better in my view to simply reload the page like this:
...
} else if (data.operation == 'create') {
// Create >> refresh the page
location.reload();
}
Thanks anyway.
If your list is not too long I would suggest to send back the complete list in every ajax request, doesn't matter if update, create or delete.
So you can remove your data operation check (your :eq(0) stuff will fail if you change the order of the columns some day) and simply put the result from the ajax request in your #userlist div.
EDIT
But to solve your create problem:
Just replace in the Create action this line:
return RedirectToAction("Index");
with this line:
return PartialView("Index", _requestServiceClient.GetUsers());
and it should return only the new list.
EDIT2
Ok, your Index.cshtml seems to have the complete layout, not just the list as I thought. So you have to do this first:
Move just the HTML code required to build the list in a seperate View, name it _List.cshtml for example
At the place where the HTML code was in your Index.cshtml put #Html.Partial("_List") in there
At this point your index view should look the same as before but you have your list view seperatly
Change my example above to not return the Index but the _List partial:
return PartialView("_List", _requestServiceClient.GetUsers());
I hope that works for you.
Place this code into your partial view:
#{
Layout = null;
}
This code says that you don't need a master view for this page.

MVC3 - RenderPartial inside RenderSection not working

I'm working on an MVC3/Razor page, and in my _layout I have
#RenderSection("relatedBooksContainer", false)
In another page I use that section with:
#section relatedBooksContainer
{
#{ Html.RenderPartial("~/Views/Shared/Bookshelf.cshtml", Model.Books);}
}
This doesn't work. From what I've read, RenderSection will only ever go one layer deep - it has no concept of the Html.RenderPartial in the related section and will just return a blank area. The workaround I read at http://forums.asp.net/t/1590688.aspx/2/10 is to use RenderPage and commit the returned HTML to a string, then outout that string in the render section...which works! That is, until I pass a model to the partial page, then it throws an error saying:
The model item passed into the
dictionary is of type
'TheBookshelf.ViewModels.BookshelfViewModel',
but this dictionary requires a model
item of type
'System.Collections.Generic.List`1[TheBookshelf.EntityModel.Book]'.
Anyone have any idea why this might be happening? Are there any other ways to achieve this?
Try the #Html.Partial instead
#section relatedBooksContainer
{
#{ Html.Partial("~/Views/Shared/Bookshelf.cshtml", Model.Books);}
}
The error message is regarding the type and return type of the Bookshelf from the model.
public IEnumerable<Book> Bookshelf()
{
var q = from book in bookshelf
select book;
IEnumerable<Book> myBooks = q.ToList<Book>();
return myBooks;
}
did the solution in the provided link work for you?
I couldn't get it to work. That is I couldn't get ViewData["MainView"] to pass the data from Layout.cshtml to partialview. This aparently is a feature as every view is supposed to have it own ViewData obj. It seems ViewData is not global like I have thought. So what I get in ViewData["MainView"] from Layout in my partial view is null......I eventually found a work around for this and was able to pass the page reference from Layout to Partialview via a #Html.Action call from Layout -> Controller -> PartialView. I was able to get my partialview to access and write to the correct rendersection. However I want to call the same partialview many times in my Layout.cshtml. A subsequent call to the same Partialview again in the Layout, does not work, as the reference to layout has changed since the first call and rendersection update. So the code looks like this:
Layout.cshtml:
#RenderSection("Top", false)
#Html.Action("Load", "Home", new { viewname = "_testPartialView", pageref = this })
#Html.Action("Load", "Home", new { viewname = "_testPartialView", pageref = this })
Partial View:
#Model Models.testModel
#Model.Content
#{
var md = (System.Web.Mvc.WebViewPage)#Model.pageRef;
#*This check fails in subsequent loads as we get null*#
if(md.IsSectionDefined("Footer")) {
md.RenderSection("Footer");
}
else {
md.DefineSection("Footer", () => { md.WriteLiteral("<div>My Contents</div>"); });
}
}
}
controller:
public ActionResult Load(string viewname, System.Web.Mvc.WebViewPage pageRef)
{
var model = new Models.testModel { Content = new HtmlString("time " + i++.ToString()), pageRef = pageRef };
return PartialView(viewname, model);
}

View Called from Partial Not Submitting Form Data

I hope I am able to put this question together well.
In a partial view I have a link to a create action:
public ActionResult CreateProject()
{
return View("EditProject", new Project());
}
Now this loads another view which allows editing of the blank model passed to it. But when form is submitted it is supposed to post to:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult EditProject(Project record)
{
if (ModelState.IsValid)
{
projectRepo.saveProject(record);
return View("Close");
}
else
{
return View("EditProject");
}
}
This method works for many of the tables and edit actions work just as well for the same view. But only for the create action (with the blank model) the form keeps calling to the create action, as I traced with the debugger.
One of my team mates has solved this problem so:
[AcceptVerbs(HttpVerbs.Get)]
public ViewResult EditProject(int id)
{
Project project = null;
if (id == 0)
{
project = new Project();
}
else
{
project = (from p in projectRepo.Projects
where p.ProjectID == id
select p).First();
}
return View(project);
}
And in the partial instead of having <%= Html.ActionLink("Create New", "CreateProject")%> there'd be <%= Html.ActionLink("Create New", "CreateProject", new { id = 0 })%>.
Now I was hoping to find out why the previous method would not go through, since it does for other tables in other views. Thanks.
By default your form will post to same URL it was rendered at. Since you called create action it will post back to create action, and not edit, 'cos views do not matter (-:
Explicitly use
<%= using( Html.BeginForm("Action","Controller) ){ %>

Resources