Partial View Does Not Recognize Another Controller - asp.net

I am creating a partial view for the login which will be using the default model (AccountModel) and controller (AccountController) which were added when a new MVC 3 project is created.
However, the partial view (Login) does not recognize the controller (AccountController). I am getting "The resource cannot be found" error when I hit the "Register" link. Below is the snippet of the code.
Please advice.
Thanks
_Layout.cshtml
<div>
<div id="SideBar">
<div id="LoginHeader">
Login
</div>
<div id = "Login">
#Html.Partial("UserControls/UserLogin", new BalanzLab.Models.LogOnModel())
</div>
</div>
</div>
UserLogin.cshtml
#model BalanzLab.Models.LogOnModel
#using (Ajax.BeginForm("LogOn", "AccountController", new AjaxOptions { UpdateTargetId = "AccountController" }))
{
if (Request.IsAuthenticated)
{
Html.DisplayFor(Context.User.Identity);
}
else
{
<div >User Name
#Html.TextBox(" ")
</div>
<div>Password
#Html.Password(" ")
</div>
<div>
#Html.ActionLink("Signup", "Register", "AccountController")
</div>
<p><input type="submit" value="Let me in!" /></p>
}
}

This has to do with where you have the UserLogin shared view and how you're referencing it.
First the how:
You're including the partial view from your _layout view. Therefore, it's in every page that uses that layout.
Now consider what you're doing here. When you click that Register link that's supposed to take you to the Account controller Register method, it's hitting the call to #Html.Partial:
#Html.Partial("UserControls/UserLogin", new BalanzLab.Models.LogOnModel())
and trying to include it in the current page. Since the UserLogin control is actually under a folder in the Home views directory, it's not in the standard search path of where the view engine will search. It will check within the Accounts directory of views (the current controller) and it will check the Shared views directory. Since it can't find the partial view in either location, you get your error. (which looks something like this)
The partial view 'UserControls/UserLogin' was not found or no view engine
supports the searched locations. The following locations were searched:
~/Views/Account/UserControls/UserLogin.aspx
~/Views/Account/UserControls/UserLogin.ascx
~/Views/Shared/UserControls/UserLogin.aspx
~/Views/Shared/UserControls/UserLogin.ascx
~/Views/Account/UserControls/UserLogin.cshtml
~/Views/Account/UserControls/UserLogin.vbhtml
~/Views/Shared/UserControls/UserLogin.cshtml
~/Views/Shared/UserControls/UserLogin.vbhtml
The cleanest solution is to move this partial view to the shared views directory. Since it's part of the _layout view, you almost have to do this to make this work as the partial will be included by every view that uses the layout.

Related

How to Create Form with a Dynamic Repeating Partial View in .Net Core

I'm building a .Net Core application. The user interacts with a form that contains some general information. On the form there is a partialview that is dynamic. This section is populated based on the press of a button, and displays the same partial view depending upon how many times the user presses the button. Think of it like this since I can't describe my actual use case. A user is enrolled in school. The form contains general information on the student. There is a button on the form for adding courses. The user clicks the button and the partial view is populated with the ability to add a single course. The user clicks the button and now the partial view has sections for 2 courses, etc. I tried what I saw at this link Dynamically Append View With MVC Partial View. The issue I am having is that I can't prevent the main form's POST action from firing.
Here is my code:
<div class="row">
<form asp-action="Edit" class="page-content">
...FORM CODE HERE...
<button id="Btn_AddEngagement" type="submit" style="height: 36px; width: 36px;">Add Engagement</button>
<div class="EngagementClass">
#{
await Html.RenderPartialAsync("_Engagements.cshtml");
}
</div>
</form>
</div>
<script>
$(function() {
$(document).on('click', '#Btn_AddEngagement', function(e) {
e.preventDefault;
$.ajax({
url: '/Issue/DisplayNewEngagement',
success: function(partialView) {
$('.EngagementClass').append(partialView);
}
});
})
});
</script>
And in the controller:
public ActionResult DisplayNewEngagement()
{
return PartialView("_Engagements");
}
When I press the Add Engagement button, the partial view gets appended, BUT then the main form's SUBMIT action gets fired. I tried using e.preventdefault, but that didn't work. How can I add/append partial views and prevent the main form's submit from firing?

Load controller's view in iframe without layout items

I have 2 separate solutions. I want to load one of project#1's content from its view in an iframe in project#2. The problem is inside the iframe, it also includes everything in its layout view (the header/footer,etc)
How can I load just the view? (while still using its controller) in the iframe?
If you don't need the layouts then you have to return partial views from those controller actions.
Ex.
return PartialView("ViewName");
In your _Layout view You can generate target link with your IFrame like:-
<li>#Html.ActionLink("Contact", "Contact", "Home", null, new {target ="MainiFrame"})</li>
and in your Content section (in _Layout view) like:-
<section class="content-wrapper main-content clear-fix">
#RenderBody()
<iframe name="MainiFrame" src="" width="920" height="1000" frameborder="0"></iframe>
</section>
Then any view that you like to display in your IFrame you can write the following code in the upper corner of that view.
#model YourProgramName.YourModelClass
#{
Layout = null;
ViewBag.Title = "Your View Title";
}
#* Rest of your codes and mark ups.......... *#
Telling that your view not to use the default Layout, other wise your view will load all of your _Layout elements like menus, banners etc.
Enjoy.

activating a different <div> with a partial view in my Layout.html by getting the name of controller action or view

I'd like to get the name of my partial view in my layout page to determine which div is going to be active. Because of the design I cannot css this nicely so I went for a more sloppy approach.
In my _Layout.chtml The Renderbody loads my content. And here depending on which button I press, I get a map or a list.
These are both functions in my controller and what I would like to do is get the functionname or partial view so I can then decide which I want to show.
so I wanted to do something like this in my _Layout.chtml
#if ( get the controllername or view == mapname or listname)
{
<div>
#Html.Partial("tabMap")
</div>
}
else
{
<div>
#Html.Partial("tabList")
</div>
}
Any quick fix to do this ?
access the RouteData dictionary from the ViewContext Object
will be like this
#ViewContext.RouteData.Values["Controller"]
with the RouteData Dictionary you can get all the info needed about the controller , action and extra parameters names , depending on them output the data you want

Orchard and master detail editing

I was reading http://www.orchardproject.net/docs/Creating-1-n-and-n-n-relations.ashx and could not get the idea, if it is possible to easily make master detail editing, to give you concrete example i've attached screenshot from wordpress:
So there is post and post contains set of custom fields, simple 1:N relationship, everything edited in one page - you can add/edit custom field without leaving post page.
May be someone saw similar example for Orchard on internet, or could shortly describe path to achieve this by code, would be really helpful (I hope not only for me, because this is quite common case I think).
This should be possible, although not in the most 'Orchardy' way.
I've not tested any of the below so it is probably full of mistakes - but maybe Bertrand or Pszmyd will be along later today to correct me :-)
As you have probably seen you can pass a view model to a view when creating a content shape in your editor driver:
protected override DriverResult Editor(CatPart part, dynamic shapeHelper)
{
// Driver for our cat editor
var viewModel = new CatViewModel
{
Cats = _catService.GetCats() // Cats is IEnumerable<Cat>
};
return ContentShape("Parts_CatPart_Edit",
() => shapeHelper.EditorTemplate(
TemplateName: "Parts/CatPart",
Model: viewModel,
Prefix: Prefix
));
}
So we can pass in a list of items, and render it in our view like so:
#foreach(var cat in Model.Cats)
{
<span class="cat">
<p>#cat.Name</p>
<a href="...">Delete Cat</p>
</span>
}
The problem here would be posting back changes to update the model. Orchard provides an override of the Editor method to handle the postback when a part is edited, and we can revive the viewmodel we passed in the previous method:
protected override DriverResult Editor(CatPart part, IUpdateModel updater, dynamic shapeHelper)
{
var viewModel = new CatViewModel();
if (updater.TryUpdateModel(viewModel, Prefix, null, null))
{
// Access stuff altered in the Cat view model, we can then update the CatPart with this info if needed.
}
}
This works really well for basic information like strings or integers. But I've never been able to get it working with (and not been sure if it is possible to do this with) dynamic lists which are edited on the client side.
One way around this would be to set up the buttons for the items on the N-end of the 1:N relationship such that they post back to an MVC controller. This controller can then update the model and redirect the client back to the editor they came from, showing the updated version of the record. This would require you to consistently set the HTML ID/Name property of elements you add on the client side so that they can be read when the POST request is made to your controller, or create seperate nested forms that submit directly to the contoller.
So your view might become:
#foreach(var cat in Model.Cats)
{
<form action="/My.Module/MyController/MyAction" method="POST">
<input type="hidden" name="cat-id" value="#cat.Id" />
<span class="cat">
<p>#cat.Name</p>
<input type="submit" name="delete" value="Delete Cat" />
</span>
</form>
}
<form action="/My.Module/MyController/AddItem" method="POST">
<input type="hidden" name="part-id" value="<relevant identifier>" />
<input type="submit" name="add" value="Add Cat" />
</form>
Another possibility would be to create a controller that can return the relevant data as XML/JSON and implement this all on the client side with Javascript.
You may need to do some hacking to get this to work on the editor for new records (think creating a content item vs. creating one) as the content item (and all it's parts) don't exist yet.
I hope this all makes sense, let me know if you have any questions :-)

Ajax update after Delete action on Index view in ASP.MVC

I'm trying to do an Ajax delete in a fairly standard Index view, i.e. I have a generated Index view with one added filter drop-down, of little relevance here. I have changed the free Delete Html.ActionLink on every row to an Ajax.ActionLink, and the delete and ajax update work, but whichever container div I try and update, I always somehow get some kind of nesting in the updated page, e.g. after a delete and update, I get duplicate Home and About links from the master page inside my content.
Here is my current action link that causes what I describe above:
<%: Ajax.ActionLink("Delete", "Delete", new { id = item.InstallationDBNumber }, new AjaxOptions { UpdateTargetId = "jobList" }) %>
... and here is where jobList is located, just outside the table used for the index list:
<div style="clear: both;">
</div>
<div id="jobList" class="index-list">
<table>
<tr>
You should post your code for your Delete action method on your controller. But from the sounds of it, you are returning Return View(myModel) instead of Return PartialView("partialViewName", myModel).
Create a partial view contianing the layout information for jobList and return that from your controller action method.

Resources