Get lastest record from section using mvc5 - asp.net-mvc-4

I want to show in my home page: All section (all link category and one lastest news record in this section).
Please help me to complete my code.
Thank you so much.
My DbContext class:
public partial class xxDbContext : DbContext
{
public xxDbContext()
: base("name=xxDbConnection") { }
public virtual DbSet<Category> Categories { get; set; }
public virtual DbSet<Section> Sections { get; set; }
public virtual DbSet<News> News { get; set; }
}
public partial class Section
{
public int Id { get; set; }
public string Name { get; set; }
public virtual List<Category> Categories { get; set; }
}
public partial class Category
{
public int Id { get; set; }
public int SectionId { get; set; }
public string Name { get; set; }
public virtual Section Section { get; set; }
}
public partial class News
{
public int Id { get; set; }
public int CateId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
}
My controllers
public ActionResult NewsInSec()
{
var model = db.Sections.Where(m => m.Publish).ToList();
return PartialView("NewsInSec", model);
}
My view
#model IEnumerable<xx.Models.Section>
<div>
#foreach (var sect in Model)
{
<ol class="breadcrumb">
<li>#sect.Name</li>
#foreach (var cate in sect.Categories)
{
<li>#cate.Name</li>
}
</ol>
**foreach (var item in sect.Categories.SelectMany(c => c.News).Where(c => c.Publish).OrderByDescending(c => c.CreateDate).Take(4).ToList())
{
<div>
#* News title*#
<h4>#item.Title</h4>
<img src="~/img/news/#item.Image" />
#*Content of lastest news*#
<p>#item.NewsContent</p>
<p>#item.Title</p>
</div>
}**
}
Finally, i want to show section, cate, news as my attached photo.
Please help me to see and fix my code above one more time? Thanks and thanks so much.

You can add navigation property in Category for easy access to News.
public partial class Category
{
public int Id { get; set; }
public int SectionId { get; set; }
...
public virtual List<News> News { get; set; }
}
And select last news for section:
#foreach (var cate in sect.SelectMany(s=>s.Categories.SelectMany(c=>c.News))
.OrderByDescending(n=>n.ID).Take(5))
{
<div>
// Title of lastest news
<h3></h3>
<img src="~/img/...." />
// Content of lastest news
<p></p>
</div>
}
Note: more correct way find last news in your Controller and include result in ViewModel, Like that:
public class SomeViewModel
{
public IEnumerable<Section> Sections {get;set;}
public IEnumerable<News> LastNews{get;set;}
}
Fill this model in controller and pass in view.

Related

create a field, by many to many relationship on ef core (razor pages)

i want to create a field, by many to many relationship on ef core, this is my book class:
public class Book:BaseModel
{
public string Name { get; private set; }
public string Author { get; private set; }
public List<BookCategory> Categories { get; private set; }
public Book(string name, string author)
{
Name = name;
Author = author;
Categories=new List<BookCategory>();
}
public Book()
{
}
}
and the category class:
public class Category:BaseModel
{
public string Name { get; private set; }
public List<BookCategory> Books { get; private set; }
public Category(string name)
{
Name = name;
Books = new List<BookCategory>();
}
public Category()
{
}
my bookCategory class:
public class BookCategory
{
public long BookId { get; set; }
public long CategoryId { get; set; }
public Book Book { get; set; }
public Category Category { get; set; }
}
and now when i am creating a new book, i want to select multiple items of category and save this items to the categories property in the book:
<div class="form-group">
<label asp-for="?" class="control-label">Category product</label>
<select multiple="multiple" class="form-control" asp-for="?"
asp-items='new SelectList(Model.Categories, "Id", "Name")' >
<option value="0">productCategory</option>
</select>
<span asp-validation-for="Name" class="error"></span>
</div>
this is my repository(just i show here my Categoryrepository, the BookRepository is like this):
(notice: because of my architucture i use CategoryViewModel and BookViewModel instead of Book and Category,
public List<CategoryViewModel> GetAllCategories()
{
return _shopContext.Categories
.Include(x => x.Books)
.ThenInclude(x => x.Book)
.Select(x => new CategoryViewModel
{
Id = x.Id,
Name = x.Name,
//Books = ?
}).ToList();
}
CreateBook Class:
public long Id { get; set; }
public string Name { get; set; }
public List<CategoryViewModel> Categories { get; set; }
Index Model:
public IActionResult OnGetCreate()
{
var book = new CreateBook()
{
Categories = _categoryApplication.GetAllCategories(),
};
return Partial("Create" , book);
}
public JsonResult OnPostCreate(CreateBook command)
{
var book = _bookApplication.Create(command);
return new JsonResult(book);
}
it show me the categories, but when i select the items and push submit, the categories send null,
maybe because i didn't defenited category id in the book class,it's because of using many to many relationship that u should definete category id in a seperate class,and now what should i do?
i use from ? in some lines, it means that i don't know what should i use instead ,
i am using many to many relationship on ef core, i want to create a book with a list of categories, i can see the categories but when i select them and push submit button the categoreies sent as null,
Firstly, it is impossible to receive the value for you use private access modifier.
Secondly, the multiple select listpdownwill match the type of List<int> or int[].
At last, Model bound complex types must not be abstract or value types and must have a parameterless constructor.
The whole working demo for how to receive the multiple select dropdown should be:
Model:
public class Book : BaseModel
{
public string Name { get; set; }
public string Author { get; set; }
public List<BookCategory> Categories { get; set; }
public Book(string name, string author)
{
Name = name;
Author = author;
Categories = new List<BookCategory>();
}
public Book()
{
}
}
public class Category : BaseModel
{
public string Name { get; private set; }
public List<BookCategory> Books { get; private set; }
public Category(string name)
{
Name = name;
Books = new List<BookCategory>();
}
public Category()
{
}
}
public class BookCategory
{
public long BookId { get; set; }
public long CategoryId { get; set; }
public Book Book { get; set; }
public Category Category { get; set; }
}
Page:
#page
#model IndexModel
<form method="post">
<div class="form-group">
<label asp-for="Book.Name" class="control-label">گروه محصول</label>
<select multiple="multiple" class="form-control" asp-for="CategoryIds"
asp-items='new SelectList(Model.Categories, "Id", "Name")'>
<option value="0">گروه محصول</option>
</select>
<span asp-validation-for="Book.Name" class="error"></span>
</div>
<div class="form-group">
<label asp-for="Book.Author" class="control-label">گروه محصول</label>
<input asp-for="Book.Author" />
<span asp-validation-for="Book.Author" class="error"></span>
</div>
<input type="submit" value="Create" />
</form>
PageModel:
public class IndexModel : PageModel
{
[BindProperty]
public Book Book { get; set; }
public List<Category> Categories { get; set; }
[BindProperty]
public int[] CategoryIds { get; set; }
public void OnGet()
{
Categories = ......
}
public void OnPost()
{
//append the value to the Book model
foreach(int id in CategoryIds)
{
Book.Categories = new List<BookCategory>();
Book.Categories.Add(new BookCategory() { BookId = Book.Id, CategoryId = id });
}
//do your stuff for database insert operation...
}
}

passing single model twice or thrice to contoller

I am new to asp.net MVC-4 and stuck up while retrieving data from view to controller in case of render single partial view twice on company/create.cshtml
My complex model is as follow.
public partial class Company
{
public int CCode { get; set; }
public string CName { get; set; }
public string Addr1 { get; set; }
public string Addr2 { get; set; }
public string City { get; set; }
public string Country { get; set; }
public string EmailID { get; set; }
public string Remarks { get; set; }
public CompanyContacts Contacts { get; set; }
public partial class CompanyContacts
{
public int refCCode_Company { get; set; }
public int SrNo { get; set; }
public string ContactPerson { get; set; }
public string Designation { get; set; }
public string Contact1 { get; set; }
public string Contact2 { get; set; }
public string EmailID { get; set; }
public string IsActive { get; set; }
}
}
where in the CompanyContact is partial view rendered twice in company/create.cshtml page.
"#model ProjectName.Models.Company" so that i can bind HTML control as follow. #HTML.TextBoxFor(model >= model.CompanyContact)
<div class="tab-pane fade" id="contacts">
<div class="col-md-6">
<p>
#Html.Partial("_LedgerContactsPartial")
</p>
</div>
<div class="col-md-6">
<p>
#Html.Partial("_LedgerContactsPartial")
</p>
</div>
</div>
while save the data, how do i pass two contact person details to controller.
Thanks in Adv.
You need to pass list of contact person details to controller. to achieve this you could follow naming convention for input fields that the default ModelBinder expects to bind to a list.
This article by Phill Hack shows Model Binding To A List.
And take look to this question How to pass IEnumerable list to controller in MVC including checkbox state.

#Html.LisboxFor Model Binding for multiple items

My Class is
public partial class Team
{
public int TeamId { get; set; }
public string TeamName { get; set; }
public string TeamDescription { get; set; }
public virtual IList<Trials> Trials { get; set; }
}
Trials is anothetr calss
public partial class Trials
{
public int TrialID { get; set; }
public string Name { get; set; }
public int TrialTyp_RefID { get; set; }
public bool isChk { get; set; }
public virtual ICollection<Team> Team { get; set; }
}
in my view I amn trying to bind the ListBoxFor with Trials inseide the team
#model Trials.Classes.Team
<td colspan="2">
#Html.ListBoxFor(model=> model.Trials,
new SelectList(ViewBag.trials,"TrialID", "Name"),
new { #class = "chosen-select", data_placeholder = "Select Trials...", style = "width:500px;", tabindex = "4" }
)
</td>
I cant get any value for Trials calss in the controller ..It shows null but I select multi values from listbox
A multiple select only posts back an array of primitive values. It does not post back a collection of complex objects.
You need a view model with a property to bind the selected Trials
public class TeamVM
{
public int TeamId { get; set; }
....
public int[] SelectedTrials { get; set; }
public SelectList Trials { get; set; } // Assign this in your controller rather than using ViewBag
}
then in you view
#Html.ListBoxFor(m => m.SelectedTrials, Model.Trials)
When you post back, Team.SelectedTrials will contain and array of the selected TrialID values.
I changed the Team class as
public partial class Team
{
public int TeamId { get; set; }
public string TeamName { get; set; }
public string TeamDescription { get; set; }
public virtual IList<Trials> Trials { get; set;
public int[] AuthorisedTrials { get; set; }
}
and in View
#model Trials.Classes.Team
<td colspan="2">
#Html.ListBoxFor(model=> model.AuthorisedTrials ,
new SelectList(ViewBag.trials,"TrialID", "Name"),
new { #class = "chosen-select", data_placeholder = "Select Trials...", style = "width:500px;", tabindex = "4" }
)
</td>
and in my controller I was able to get the Vlaues for Selected Trials

Pass through multiple dbmodel to a view from a controller

I am using ASP.NET MVC 4.
I have this class:
namespace Attempt4.Models
{
public class UsersModel : DbContext
{
public UsersModel()
: base("name=UsersConnection")
{
}
public DbSet<UserProfile> UserProfiles { get; set; }
public DbSet<Roles> UserRoles { get; set; }
public DbSet<UsersInRoles> UsersInUserRoles { get; set; }
}
}
and
[Table("UserProfile")]
public class UserProfile
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
}
Then there is another class:
public partial class FskWebInterfaceContext : DbContext
{
public FskWebInterfaceContext()
: base("name=FskWebInterfaceContext")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public DbSet<trigger_dest_assoc> trigger_dest_assoc { get; set; }
public DbSet<ut_AccessLevel> ut_AccessLevel { get; set; }
public DbSet<ut_Client> ut_Client { get; set; }
public DbSet<ut_ContactID> ut_ContactID { get; set; }
public DbSet<ut_destinations> ut_destinations { get; set; }
public DbSet<ut_DeviceDescription> ut_DeviceDescription { get; set; }
public DbSet<ut_DeviceType> ut_DeviceType { get; set; }
public DbSet<ut_event_log> ut_event_log { get; set; }
public DbSet<ut_GMUTempData> ut_GMUTempData { get; set; }
public DbSet<ut_Triggers> ut_Triggers { get; set; }
public DbSet<ut_User> ut_User { get; set; }
public DbSet<ut_UserAPNdevices> ut_UserAPNdevices { get; set; }
public DbSet<ut_UserClientLink> ut_UserClientLink { get; set; }
}
Now I need to be able to access both of these database contexts from my view.
I know how to pass through just a model for example just UserProfile. But I need to be able to access all of the elements in these two classes.
How can i pass them through from the controller to the View.
And Specifically, once I have passed them through, how do I access them individually in the view?
You have the answer in the comments section of your question:
From what I have been reading I need to make use of a ViewModel class.
So go ahead and define a class that will contain the necessary information. Then in your controller action populate the properties of this model and have it passed to the view.
For example let's suppose that you wanted to access UserProfiles from the first context and the ut_GMUTempData from the second context:
public class MyViewModel
{
public IList<UserProfile> UserProfiles { get; set; }
public IList<ut_GMUTempData> GMUTempData { get; set; }
}
and in your controller action:
public ActionResult Index()
{
using (var ctx1 = new UsersModel())
using (var ctx2 = new FskWebInterfaceContext())
{
var model = new MyViewModel();
model.UserProfiles = ctx1.UserProfiles.ToList();
model.GMUTempData = ctx2.ut_GMUTempData.ToList();
return View(model);
}
}
and now your view becomes strongly typed to the view model and you can access both properties:
#model MyViewModel
... you could use both #Model.UserProfiles and #Model.GMUTempData collections
UPDATE:
As requested in the comments section here's how you could loop through the user profiles in the view:
#model MyViewModel
#foreach (var profile in Model.UserProfiles)
{
<div>#profile.SomePropertyOfTheUserProfileClassThatYouWantToDisplayHere</div>
}

System.Collections.Generic.IEnumerable<MyBlogSite.Models.BlogPost>' does not contain a definition for 'Categories'

Here is my BlogPost Model class:
public class BlogPost
{
public int Id { get; set; }
public string Title { get; set; }
[AllowHtml]
public string ShortDescription { get; set; }
[AllowHtml]
public string PostBody { get; set; }
public string Meta { get; set; }
public string UrlSlug { get; set; }
public DateTime PostedOn { get; set; }
public DateTime? Modified { get; set; }
public virtual ICollection<BlogPostCategory> Categories { get; set; }
public virtual ICollection<BlogPostTag> Tags { get; set; }
}
Here is my BlogPostCategory Model class:
public class BlogPostCategory
{
public int Id { get; set; }
public string Name { get; set; }
public string UrlSlug { get; set; }
public string Description { get; set; }
// Decared virtual because the data must be returned from another table.
public virtual ICollection<BlogPost> BlogPosts { get; set; }
}
Each class belongs to a separate Controller/View.
Finally, here is the top port of the Index View for Blog:
#model IEnumerable<MyBlogSite.Models.BlogPost>
#{
ViewBag.Title = "Index";
}
#Html.RenderPartial("~/Views/Category/_Categories.cshtml", Model.Categories );
<p>
#Html.ActionLink("New Blog Post", "Create")
</p>
<table>
<tr>
<th>
#Html.DisplayNameFor(model => model.Title)
</th>
....
In the View where Model.Categories is being passed in is where I am getting the exception from the title of this post. It seems to me that I have defined Categories within the BlogPost Model. What am I doing wrong?
The Model on your Razor page is an IEnumerable<MyBlogSite.Models.BlogPost>. It seems you're trying to display the information about each of the items in your collection. If so, then you can loop through them or create a display/editor template and use #Html.DisplayFor(x => x) or #Html.EditorFor(x => x), respectively.
#foreach(var post in Model) {
<p>Do stuff here with the local "post" variable.</p>
}
Here's a link to Scott Gu's blog talking about the #model directive in Razor views.