ASP.NET MVC PartialView with List - c#

I am at my first MVC project. I want to create a page with a header and in this header to be placed a partial view with category list.
This is what I did so far:
I created the master page (_Home.cshtml). Than in Shared folder I created a View (Category.cshtml). See my picture.
My Category.cshtml content:
#model IEnumerable<ArtSchool.Models.Category>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
<th>
#Html.DisplayNameFor(model => model.Name)
</th>
<th>
#Html.DisplayNameFor(model => model.Visible)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Visible)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.ID }) |
#Html.ActionLink("Details", "Details", new { id=item.ID }) |
#Html.ActionLink("Delete", "Delete", new { id=item.ID })
</td>
</tr>
}
My master page file:
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>_Home</title>
</head>
<body>
<div>
#Html.Partial("ASCX/Header")
#Html.Partial("Category")
#RenderBody()
</div>
When I run the project I got the error:
I know that is a newbie question but it's my first MVC project.
Thanks!

Solution 1
If you want to use partial view you need to pass model to this helper this way
#Html.Partial("Category", CategoryModel)
before you pass this model you have to fill it with some data.
Solution 2
also you can use #Html.Action() Method with name of ActionResult method which will return partial view for you.
for example:
#Html.Action("GetCategories", "ControllerName")
public ActionResult GetCategories() {
// fill some data for your model here
return PartialView("Category", model);
}

If you want to interpret those partials as some static sections inside your HTML, then I would suggest you to call Html.Action() which returns your partials:
#Html.Action("GetPageHeader","Home")
#Html.Action("GetPageCategories","Home")
HomeController
[HttpGet]
public ActionResult GetPageHeader()
{
return PartialView(#"~/Views/Shared/_PageHeader.cshtml");
}
[HttpGet]
public ActionResult GetPageCategories()
{
var categories = databaseContext.GetAllCategories(); //Get your categs
return PartialView(#"~/Views/Shared/_Categories.cshtml",categories);
}

Related

How to set page's title from the model in asp.net?

This is my view code.
#model IEnumerable<TestApplication.Models.ApplicationUser>
#{
Layout = null;
ViewBag.Title = //what goes here? Model.FirstName?
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
</head>
<body>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.FirstName)
</th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.FirstName)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.Id }) |
#Html.ActionLink("Details", "Details", new { id=item.Id }) |
#Html.ActionLink("Delete", "Delete", new { id=item.Id })
</td>
</tr>
}
</table>
</body>
</html>
I want to change the ViewBag's title to whatever the FirstName is in the model. I am expecting something like ViewBag.Title = Model.FirstName. However doing so, I got an error. So what's the syntax?
The issue is that your Model is of type IEnumerable<TestApplication.Models.ApplicationUser> so you cannot call a Property of the ApplicationUser
To demonstrate the problem, try this:
ViewBag.Title = Model.First().FirstName;
The error should disapear, but this is not the correct solution. You should consider which first name out of the list of users you want to display

MVC5 passing a Model item from View to a Controller

I am using .Net MVC5 and I am trying to create an Index view with an Edit Link(or button) that will POST(so I can't use ActionLink) an entire Model item Entity from the list of entities presented in the View. How do I do it?
my code(so far) is below
#model IEnumerable<Projname.Models.MyEntity>
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.Name)
</th>
<th>Hello there</th>
<th>life is good</th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#using (Html.BeginForm("Edit", "Edit", FormMethod.Post))
{
#Html.Hidden(mytem => item);
<input type="submit" value="Edit" class="btn btn-default" />
}
</td>
<td>
#Html.ActionLink("Details", "Details", new { id = item.PrimeKey }) |
#Html.ActionLink("Delete", "Delete", new { id = item.PrimeKey })
</td>
</tr>
}
</table>
</body>
</html>
I am assuming that there is a better way to do it instead of creating a hidden field for each of the properties of the entity.
You need to put the items you want to edit or change into a form
<form class="form-horizontal" action="GetItemsFromView" method="post">
<input type="text" name="EditedModelItem">
</form>
Afterwards you can call any edited item in your controller, through
string hold = Request.Form["EditedModelItem"];
in the GetItemsFromView method.
Wrap everything in:
#using (Html.BeginForm("Edit", "Edit", FormMethod.Post))
{
}
Then:
public ActionResult Edit(Model model)
{
if (ModelState.IsValid)
{
}
}
Or:
public ActionResult Edit(FormCollection formCollection)
{
}

Listing Models from ASP pages, with Visual Studio and C#

I am creating a very basic Web application in ASP with Visual Studio, I used the default web site then created the 'Employee' Model. This Model can be stored in the Database using:
public class EmployeeDBContext : DbContext
{
public DbSet<Employee> Employees{ get; set; }
}
In the Employee namespace. When I created the Controller for this Model the default Create, Read, Update and Delete methods are created. There is also an index page created that is shown when the page is 1st loaded and this page shows every Employee currently in the database. The code for Index.cshtml looks like this:
#model IEnumerable<AnotherWebApp.Models.Employee>
#{
ViewBag.Title = "Index";
}
<h2>All Employee Options</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<p>
#Html.ActionLink("View All", "ViewAll")
</p>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.Name)
</th>
<th>
#Html.DisplayNameFor(model => model.Role)
</th>
<th>
<b>Options</b>
</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Role)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.ID }) |
#Html.ActionLink("Details", "Details", new { id = item.ID }) |
#Html.ActionLink("Delete", "Delete", new { id = item.ID })
</td>
</tr>
}
</table>
What I am trying to do is display a basic menu on Index.cshtml and link to a ViewAll page containing the table of all Employees. The problem is it says 'Object reference not set to an instance of an object.' and the page is not displayed. I cannot see why this code works on Index.cshtml but will not work on ViewAll.cshtml, anybody have suggestions?? Here is a link to some tutorials doing this: http://www.asp.net/mvc/tutorials/mvc-5/introduction/accessing-your-models-data-from-a-controller
Thanks for any advice.
Just to clear things up this problem was from the EmployeeController.cs where the View associated with the ViewAll page was being returned. When the ViewAll function looked like this:
public ActionResult ViewAll()
{
return View();
}
The list of Employees could not be accessed so
#model IEnumerable<AnotherWebApp.Models.Employee>
was null.The correct version of this function is:
public ActionResult ViewAll()
{
return View(db.Employees.ToList());
}
Now the list of all Employees is accessible and can be easily displayed on the ViewAll page.
Hope this is of help to somebody, if anybody has furthur questions please ask!!

MVC 4 How to pass an object to partial view when list item is clicked?

This is a controller
public class ProductController : Controller
{
//
// GET: /Product/
public ActionResult Index(int id = 0)
{
return View(DALCategory.GetCategoryList());
}
public PartialViewResult productPartial(int id)
{
if (id > 0)
{
return PartialView("_productPartial", DALProduct.GetProductListByCateDetail(id));
}
else
{
return PartialView("_productPartial", DALProduct.GetProductList());
}
}
This is code in index view
#model IEnumerable<Model.Category>
<h2>Products</h2>
<table>
<tr>
<th>
#Html.DisplayNameFor(model => model.name)
</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.ActionLink(#item.name, "productPartial", new { id = item.id })
</td>
</tr>
}
</table>
#Html.Partial(productPartial)
And this is code for partial view.
#model IEnumerable<Model.Product>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
<th>
#Html.DisplayNameFor(model => model.SKU)
</th>
<th>
#Html.DisplayNameFor(model => model.product_name)
</th>
<th>
#Html.DisplayNameFor(model => model.price)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.SKU)
</td>
<td>
#Html.DisplayFor(modelItem => item.product_name)
</td>
<td>
#Html.DisplayFor(modelItem => item.price)
</td>
<td>
#* #Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) |
#Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) |
#Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ })*#
</td>
</tr>
}
</table>
So what I want to do is... when an item is clicked, it renders the partial with an new object. Yes, the partial view is only rendered on the same page.
I have been doing so many things. Although I do not think it is such a hard problem, I am not really sure what I need to do for this...
Since you want to update a part of the page you will need to use ajax to accomplish that. You have two options there:
User #Ajax.ActionLink (How can i load Partial view inside the view)
You can write your own jquery ajax request that invokes your controller method and returns the partial view.
It happened to me as well. I wanted the page to be partial and loaded on the same page but it kept forwarding me to other link. Make sure following points are taken care of:
You have included your jquery-1.6.2.js or whatever version of this file you have.
Also make you have included your jquery file you have created. Make sure the above one is included first.
If you have included these files in some section of your .cshtml section then make sure you render it in your _Layout.cshtml or other layout file you are using. For example you have included your file in head section of your index.cshtml like this
#section head{
}
then you have to render this section in _layout.cshtml with #RenderSection("head", required: false)
what you can also do is Make sure that jQuery is not included twice and that you don't have some javascript errors. Look at your javascript console in the browser as well as the Network tab to ensure that all your scripts are included properly.
Good Luck!!!

Database change notification to signalr via mvc4 controller

I have created a NerdDinner like application using the NerdDinner tutorial available online by ScottGu. I want to add SignalR to my application such that every time a new dinner is created, the value of dinners displayed on the home page should be updated.
I have a create method in my HomeController
[HttpPost]
public ActionResult Create(Dinner dinner)
{
if (ModelState.IsValid)
{
nerdDinners.Dinners.Add(dinner);
nerdDinners.SaveChanges();
}
return RedirectToAction("Index");
}
And my Hub class is as below:
[HubName("DinnerHub")]
public class NewDinnerHub : Hub
{
int dinnerCount = 0;
NerdDinners.Models.NerdDinners nerdDinners = new NerdDinners.Models.NerdDinners();
public void SendDinnerNumber(int no_of_dinners)
{
var dinners = from d in nerdDinners.Dinners
select d;
dinnerCount = dinners.ToList().Count();
no_of_dinners = dinnerCount;
IHubContext context = GlobalHost.ConnectionManager.GetHubContext<NewDinnerHub>();
context.Clients.All.getDinnerNumber(this.Context.ConnectionId, no_of_dinners);
}
}
And here is my index.cshtml
#model IEnumerable<NerdDinners.Models.Dinner>
<h2>Index</h2>
<h1>Upcoming Dinners</h1>
<ul>
#foreach(var d in Model) {
<li>
#Html.DisplayFor(modelItem => d.Title)
#Html.DisplayFor(modelItem => d.EventDate)
</li>
}
</ul>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<p>
#Html.Label("Number_of_Dinners","Number of Dinners : ") <label id="No_of_Dinners" />
</p>
<table>
<tr>
<th>
Title
</th>
<th>
EventDate
</th>
<th>
Address
</th>
<th>
HostedBy
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Title)
</td>
<td>
#Html.DisplayFor(modelItem => item.EventDate)
</td>
<td>
#Html.DisplayFor(modelItem => item.Address)
</td>
<td>
#Html.DisplayFor(modelItem => item.HostedBy)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.DinnerID }) |
#Html.ActionLink("Details", "Details", new { id=item.DinnerID }) |
#Html.ActionLink("Delete", "Delete", new { id=item.DinnerID })
</td>
</tr>
}
</table>
And my javascript which is inside my index.cshtml as well is below
<script>
$(function () {
var hub = $.connection.DinnerHub;
$No_of_Dinners = $("#No_of_Dinners");
hub.client.getDinnerNumber = function (connectionId, no_of_dinners) {
$No_of_Dinners.text = no_of_dinners;
};
$.connection.hub.start().done(function () {
hub.server.sendDinnerNumber($No_of_Dinners);
});
});
</script>
<script src="../../Scripts/jquery-1.7.1.js"></script>
<script src="../../Scripts/jquery-ui-1.8.20.js"></script>
<script src="../../Scripts/jquery.signalR-1.0.1.js"></script>
<script src="/signalr/hubs"></script>
I'm unsure of what is going wrong. I need to update my 'No_of_Dinners' label with the number of dinners in the database whenever a new dinner is added. Also,I'm using .Net MVC4 and I do not want to change my pattern to MVVM. All examples I have seen online are MVVM.
Thanks in advance.
I solved the problem. I wasn't working properly because I did not have my Route.MapHubs() method above RegisterRoutes(). Also, I had to delete bundles/jquery from _Layout.cshtml

Categories