ASP.NET MVC - Order By Date - asp.net

I am trying to sort table (columns: ID, Name, SermonDate, SermonTitle, BibleReading, VideoLink, BulletinLink) by date (SermonDate) so the data with the newest date comes on top and display it in my MVC application.
After some researching, I've tried putting the below with reference to this and this but nothing worked for me - probably because I misunderstood and put wrong code though.
public async Task<IActionResult> Index()
{
return View(await _context.Sermon.OrderBy(sermon =>
DateTime.Now).Take(5).ToListAsync());
}
My current controller (SermonsController.cs):
public SermonsController(BKPCContext context)
{
_context = context;
}
public async Task<IActionResult> Index()
{
return View(await _context.Sermon.OrderBy(sermon => DateTime.Now).Take(5).ToListAsync());
}
public async Task<IActionResult> Details(int? id)
{
if (id == null)
{
return NotFound();
}
var sermon = await _context.Sermon
.SingleOrDefaultAsync(m => m.ID == id);
if (sermon == null)
{
return NotFound();
}
return View(sermon);
}
public IActionResult Create()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("ID,Name,SermonDate,SermonTitle,BibleReading,VideoLink,BulletinLink")] Sermon sermon)
{
if (ModelState.IsValid)
{
_context.Add(sermon);
await _context.SaveChangesAsync();
return RedirectToAction("Index");
}
return View(sermon);
}
And the html table in /Sermons/Index.cshtml as below:
<table class="table">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.Name)
</th>
<th>
#Html.DisplayNameFor(model => model.SermonDate)
</th>
<th>
#Html.DisplayNameFor(model => model.SermonTitle)
</th>
<th>
#Html.DisplayNameFor(model => model.BibleReading)
</th>
<th>
#Html.DisplayNameFor(model => model.VideoLink)
</th>
<th>
#Html.DisplayNameFor(model => model.BulletinLink)
</th>
<th>
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.SermonDate)
</td>
<td>
#Html.DisplayFor(modelItem => item.SermonTitle)
</td>
<td>
#Html.DisplayFor(modelItem => item.BibleReading)
</td>
<td>
#Html.DisplayFor(modelItem => item.VideoLink)
</td>
<td>
#Html.DisplayFor(modelItem => item.BulletinLink)
</td>
<td id="aspButton">
<a role="button" id="btn-primary" class="btn btn-primary" asp-action="Edit" asp-route-id="#item.ID">Edit</a>
<a role="button" id="btn-danger" class="btn btn-danger" asp-action="Delete" asp-route-id="#item.ID">Delete</a>
</td>
</tr>
}
</tbody>
Any help would really be appreciated.

public class Sermon{
public int ID {get;set;}
public DateTime DateAdded {get; set}
}
mySermonList.OrderByDescending(x => x.DateAdded);

i think the issue
sermon => DateTime.Now
you are sorting by DateTime.Now?
if sermon has date added field
sermon => dateadded for example

Related

How to create an ASP.NET Core MVC form with a list of check boxes and a submit button? Issue with model binding

I am trying to create a form where a user can select check boxes in a table of products. I want the boxes checked to be stored but there seems to be an issue with the model binding. When I run the debugger, the parameter products for the Submit action is always empty. Here is what I have right now:
Model:
[DatabaseGenerated(DatabaseGeneratedOption.None)]
[Key]
public string ID { get; set; }
public string Description { get; set; }
public bool Used { get; set; }
public ICollection<ProductCVE> CVE { get; set; }
Controller:
private readonly IProductRepository _repo;
public ProductsController(IProductRepository repo)
{
_repo = repo;
}
// GET: ProductsController
public ActionResult Index()
{
var products = _repo.FindAll().ToList();
return View(products);
}
// POST: ProductsController
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Submit(IEnumerable<Products> products)
{
foreach(Products prod in products)
{
_repo.Update(prod);
}
return RedirectToAction(nameof(Index));
}
View:
#model IEnumerable<KB_Collector_API.Models.Products>
#addTagHelper*, Microsoft.AspNetCore.Mvc.TagHelpers
#{
ViewData["Title"] = "Index";
}
<h1>Products</h1>
<p>
<a asp-action="RunScript">Import Monthly Update</a>
</p>
#using (Html.BeginForm("Submit", "Products", "POST"))
{
<table class="table">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.Description)
</th>
<th>
#Html.DisplayNameFor(model => model.CVE)
</th>
<th>
#Html.DisplayNameFor(model => model.Used)
</th>
</tr>
</thead>
<tbody>
#foreach (var product in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => product.Description)
</td>
<td>
<a asp-controller="ProductCVE" asp-action="Index" asp-route-id="#product.ID">Details</a>
</td>
<td>
#Html.CheckBoxFor(modelItem => product.Used)
</td>
</tr>
}
</tbody>
</table>
<input type="submit" value="Submit" />
}
Firsly,you need know that for each property of the complex type, model binding looks through the sources for the name pattern prefix.property_name. If nothing is found, it looks for just property_name without the prefix.Your backend wants to receive IEnumerable<Products> which is a list model. so what you pass should be [index].PropertyName.
What you did will render checkbox with name product.Used, it does not match the Products model. Change your html:
#model List<Products> //change here....
#using (Html.BeginForm("Submit", "Products", "POST"))
{
<table class="table">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model[0].Description)
</th>
<th>
#Html.DisplayNameFor(model => model[0].CVE)
</th>
<th>
#Html.DisplayNameFor(model => model[0].Used)
</th>
</tr>
</thead>
<tbody>
#for (int i = 0; i < Model.Count(); i++)
{
<tr>
<td>
#Html.DisplayFor(modelItem => Model[i].Description)
</td>
<td>
<a asp-controller="ProductCVE" asp-action="Index" asp-route-id="#Model[i].ID">Details</a>
</td>
<td> //importance here...
#Html.CheckBoxFor(modelItem => Model[i].Used)
</td>
</tr>
}
</tbody>
</table>
<input type="submit" value="Submit" />
}
If you want to post all the properties displayed in the html, you also need to add hidden input for Description property, because DisplayFor jsut render a text in html, it cannot be passed to backend:
<td>
#Html.DisplayFor(modelItem => Model[i].Description)
<input hidden asp-for="#Model[i].Description"/>
</td>

How can I filter my database records on ASP.NET by a dropdownlist?

I'm trying to filter my records from a table created with Entity Framework where I want it to show my records with a specific condition.
I have this controller called ProductoesController, which is from the model Productos, that has the following attributes:
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int idProducto { get; set; }
public String nombre { get; set; }
public String descripcion { get; set; }
public float precio { get; set; }
//ENUMS ---------------------
[EnumDataType(typeof(Talle))]
public Talle talle { get; set; }
[EnumDataType(typeof(ColorProducto))]
public ColorProducto ColorProd { get; set; }
[EnumDataType(typeof(CategoriaProducto))]
public CategoriaProducto CategoriaProd { get; set; }
public int CurrentNegocioId { get; set; }
public Negocio Negocio { get; set; }
This is the Enum I want to use to filter the products I loaded:
namespace MVCShopping.Models {
public enum ColorProducto {
ROJO,
ROSA,
VERDE,
AMARILLO,
NEGRO,
BLANCO,
GRIS
}
}
I had created a Viewbag.colors in the Index method of the controller where it creates a list with the loaded Enums
public async Task<IActionResult> Index()
{
ViewBag.colors = new SelectList(Enum.GetNames(typeof(ColorProducto)), ColorProducto.AMARILLO);
return View(await _context.Producto.ToListAsync());
}
My Index.cshtml has the following content:
#model IEnumerable<MVCShopping.Models.Producto>
#{
ViewData["Title"] = "Index";
}
<h1>Index</h1>
<p>
<a asp-action="Create">Create New</a>
</p>
<table class="table">
#Html.DropDownList("ColorProducto", (ViewBag.colores as SelectList))
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.nombre)
</th>
<th>
#Html.DisplayNameFor(model => model.descripcion)
</th>
<th>
#Html.DisplayNameFor(model => model.precio)
</th>
<th>
#Html.DisplayNameFor(model => model.talle)
</th>
<th>
#Html.DisplayNameFor(model => model.ColorProd)
</th>
<th>
#Html.DisplayNameFor(model => model.CategoriaProd)
</th>
<th>
#Html.DisplayNameFor(model => model.CurrentNegocioId)
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.nombre)
</td>
<td>
#Html.DisplayFor(modelItem => item.descripcion)
</td>
<td>
#Html.DisplayFor(modelItem => item.precio)
</td>
<td>
#Html.DisplayFor(modelItem => item.talle)
</td>
<td>
#Html.DisplayFor(modelItem => item.ColorProd)
</td>
<td>
#Html.DisplayFor(modelItem => item.CategoriaProd)
</td>
<td>
#Html.DisplayFor(modelItem => item.CurrentNegocioId)
</td>
<td>
<a asp-action="Edit" asp-route-id="#item.idProducto">Edit</a> |
<a asp-action="Details" asp-route-id="#item.idProducto">Details</a> |
<a asp-action="Delete" asp-route-id="#item.idProducto">Delete</a>
</td>
</tr>
}
</tbody>
</table>
I added the #Html.DropDownList("ColorProducto", (ViewBag.colores as SelectList)) line, but I don't know how to configure this to filter my records by my selection.
This is a screenshot of how it is showing:
How do I code the records of the table to show up only if ColorProd has the same value than that DropDownList?
Thank you so much!
Table In Html
<div class="table-responsive">
<table class="table table-hover table-bordered mb-0 text-center" id="detailsTable">
<thead style="background-color:#f1f1f1;">
<tr>
<th style="width:10%;">ItemID</th>
<th style="width:40%">Item Name</th>
<th hidden="hidden" style="width:8%;">Unite No</th>
<th style="width:10%">Unite Name</th>
<th hidden="hidden" style="width:10%">F</th>
<th style="width:10%">Count</th>
<th style="width:10%">Price</th>
<th style="width:10%">Total</th>
</tr>
</thead>
<tbody id="contacts"></tbody>
</table>
</div>
Use Ajax in view
$('#BLDItemID').bind('change', function () {
$("#detailsTable tbody tr").remove();
$('#BLDCount').val(1);
$("#ITMNM").val('');
$("#ItemEXP").val('');
$.ajax({
url: '#Url.Action("RefrishItemList", "Manufacturings")',
type: "GET",
contentType: "application/json; charset=utf-8",
data: { id: $("#BLDItemID").val() },
dataType: "json",
success: function (data) {
var row = '';
var PRS = '';
var dtExpert = '';
$.each(data, function (index, item) {
row += '<tr><td>' + item.Id + '</td><td>' + item.Name + '</td><td hidden="hidden">' + item.Unite + '</td><td>' + item.UnitName + '</td><td hidden>' + item.UnTOT + '</td><td>' + item.Count + '</td><td>' + item.Price + '</td><td>' + item.Total + '</td></tr>';
PRS = item.ITPrice;
dtExpert = item.ITDTEXP;
});
$("#contacts").html(row);
$("#BLDPrice").val(PRS);
$("#ItemEXP").val(dtExpert);
$("#ITMNM").val($("#BLDItemID option:selected").text());
},
error: function (result) {
alert("Error");
}
});
})
in Control
public JsonResult RefrishItemList(int? id)
{
string DTExprVL = "";
var ITMPrice = db.TBLItems.Where(s => s.ItemID == id).Select(x => x.ItemInvoicePR).FirstOrDefault();
var EXPDT = db.TBLItems.Where(s => s.ItemID == id).Select(x => x.ItemNoticeDateActive).FirstOrDefault();
if (EXPDT == true)
{
DTExprVL = "1";
}
else
{
DTExprVL = "0";
}
var CusList = db.TBLColecteItems.Include(t => t.TBLItem).Include(t => t.TBLItem1).Where(s => s.TMainItemID == id).Select(x => new
{
Id = x.TBLItem1.ItemID,
Name = x.TBLItem1.ItemName,
Unite = x.TUnite,
UnitName = x.TBLUnite.UnitesName,
UnTOT = x.TUnTOT,
Count = x.TCount,
Price = x.TPrice,
Total = x.TTotal,
ITPrice = ITMPrice,
ITDTEXP = DTExprVL
}).ToList();
return Json(CusList, JsonRequestBehavior.AllowGet);
}
just Change the Parmeters

#Html.DisplayNameFor() respects [Display] attribute but #Html.DisplayFor() ignores [DisplayFormat] attribute

I have this view model:
public class ConceptViewModel
{
public int Id { get; set; }
[Required(ErrorMessageResourceName = "Message_Required", ErrorMessageResourceType = typeof(Resources.Web.ValidationsViewModels))]
[Display(Name = "ConceptViewModel_Name", ResourceType = typeof(Resources.Web.Contracts))]
public string Concept { get; set; }
[Required(ErrorMessageResourceName = "Message_Required", ErrorMessageResourceType = typeof(Resources.Web.ValidationsViewModels))]
[Display(Name = "ConceptViewModel_TotalUnits", ResourceType = typeof(Resources.Web.Contracts))]
[DisplayFormat(DataFormatString = "{0:###,###}")] // Ignored by #Html.DisplayFor()
public decimal TotalUnits { get; set; }
}
That view model is inside a collection property of another view model that happens to be the one passed to the view:
public class ContratConceptsViewModel : BaseClass
{
public int ContratId { get; set; }
// This collection
public List<ConceptViewModel> Concepts { get; set; }
public ContratConceptsViewModel()
{
Concepts = new List<ConceptViewModel>();
}
}
And then, inside the view, I have this code:
#model ContratConceptsViewModel
#foreach (var concept in Model.Concepts)
{
<thead>
<tr>
<td> #Html.DisplayNameFor(model => concept.Concept) </td> #* Works as expected *#
<td> #Html.DisplayNameFor(model => concept.TotalUnits) </td> #* Works as expected *#
</tr>
</thead>
<tbody>
<tr>
<td> #Html.DisplayFor(model => concept.Concept) </td>
<td> #Html.DisplayFor(model => concept.TotalUnits) </td> #* Doesn't show the correct format *#
</tr>
</tbody>
}
When I execute this code, the [Display] attribute is taken into account, but the [DisplayFormat] attribute is totally ignored. What am I doing wrong?
NOTE: I have searched for a question like this one, and despite there are many others with a similar title, they are different from this one.
Ok, it was all my fault. One of my coworkers created a template for decimal inside the folder Views\Shared\DisplayTemplates\Decimal.cshtml. That's why #Html.DisplayFor() was ignoring the attribute, it was because it was respecting the template created by my coworker.
You should amend you expressions inside DisplayFor and DisplayNameFor.
It must be #Html.DisplayFor(model => model.TotalUnits), not #Html.DisplayFor(model => concept.TotalUnits).
UPDATE
Because you're displaying items from the list #Html.DisplayFor will not work properly: it's supposed to work with single model. I would suggest to extract your template for each item into separate file(it's called display template in MVC):
Your display template(it must be placed in DisplayTemplates folder):
#model ConceptViewModel
<thead>
<tr>
<td> #Html.DisplayNameFor(model => model.Concept) </td>
<td> #Html.DisplayNameFor(model => model.TotalUnits) </td>
</tr>
</thead>
<tbody>
<tr>
<td> #Html.DisplayFor(model => model.Concept) </td>
<td> #Html.DisplayFor(model => model.TotalUnits) </td>
</tr>
</tbody>
Your main page:
#model ContratConceptsViewModel
#foreach (var concept in Model.Concepts)
{
#Html.DisplayFor(model => concept, "name of your display template, optional if you follow conventions")
}
Here is the link about display templates.

How to export string data to pdf format in .Net Core MVC

How to export string data to pdf format in .Net Core MVC. Please anyone help me for export the data in pdf format in .net core.
You might be able to tap into the Response during OnResultExecuting and replace the Filter property with something that stores the resultant HTML in a MemoryStream. Then you could clear the Response during OnResultExecuted and replace it with the results of your PDF conversion. I'm not sure that this would be better than just getting the HTML from the URL, though.
eg =
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace WebApplication2.Models
{
public class Person
{
public string Name { get; set; }
public string Email { get; set; }
public int Age { get; set; }
}
}
public ActionResult GetPersons()
{
List<Person> persons = new List<Person>();
persons.Add(new Person() { Age = 29, Name = "Rami1", Email = "Rami1#abc.com" });
persons.Add(new Person() { Age = 28, Name = "Rami2", Email = "Rami2#abc.com" });
return View(persons);
}
#model IEnumerable<WebApplication2.Models.Person>
#{
ViewBag.Title = "GetPersons";
}
<h2>GetPersons</h2>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.Name)
</th>
<th>
#Html.DisplayNameFor(model => model.Email)
</th>
<th>
#Html.DisplayNameFor(model => model.Age)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Email)
</td>
<td>
#Html.DisplayFor(modelItem => item.Age)
</td>
</tr>
}
</table>

Posted model is empty

I have a ViewModel as following
public class MetalStockAddVM
{
public MetalStock MetalStock { get; set; }
public MetalStockAddVM()
{
this.MetalStock=new MetalStock();
}
}
Here is My controller
public class MetalStockController : Controller
{
private readonly IMetalStockRepository iMetalStockRepository;
public MetalStockController(IMetalStockRepository iMetalStockRepository)
{
this.iMetalStockRepository = iMetalStockRepository;
}
// GET: MetalStock
[HttpGet]
public ActionResult AddMetalStock()
{
MetalStockAddVM addVm=new MetalStockAddVM();
return View(addVm);
}
[HttpPost]
public ActionResult AddMetalStock([Bind(Include = "MetalStock")]MetalStockAddVM metalStock)
{
MetalStockDto metalStockDto = new MetalStockDto();
metalStockDto = Mapper.Map<MetalStock, MetalStockDto>(metalStock.MetalStock);
iMetalStockRepository.Insert(metalStockDto);
return RedirectToAction("Index","Home") ;
}
}
Here is my view
#model LearningSpike.Models.ViewModels.MetalStockAddVM
#using (Html.BeginForm("AddMetalStock","MetalStock",FormMethod.Post))
{
<table>
<tr>
<th>
#Html.LabelFor(m => m.MetalStock.MetalId)
</th>
<td>
#Html.EditorFor(m => m.MetalStock.MetalId)
</td>
</tr>
<tr>
<th>
#Html.LabelFor(m => m.MetalStock.GlobalMaterialId)
</th>
<td>
#Html.EditorFor(m => m.MetalStock.GlobalMaterialId)
</td>
</tr>
<tr>
<th>
#Html.LabelFor(m => m.MetalStock.Length)
</th>
<td>
#Html.EditorFor(m => m.MetalStock.Length)
</td>
</tr>
<tr>
<th>
#Html.LabelFor(m => m.MetalStock.ColourCode)
</th>
<td>
#Html.EditorFor(m => m.MetalStock.ColourCode)
</td>
</tr>
<tr>
<th>
#Html.LabelFor(m => m.MetalStock.QuantityInStock)
</th>
<td>
#Html.EditorFor(m => m.MetalStock.QuantityInStock)
</td>
</tr>
</table>
<input type="submit" value="Create"/>
}
When I post the model that is passed to the controller action method is empty .
Please tell me what I'm doing wrong? I am creating an architectural spike for the first time so I can learn a lot.Thus its my first time implementing all heavy stuff (DI , DTO's , REpositories etc.) . I am still struggling with putting things in right places.
Thanks!
Cheers!
First remove [Bind(Include = "MetalStock")] and second rename metalStock to some something like metalStockVm and see does it works or not.
[HttpPost]
public ActionResult AddMetalStock(MetalStockAddVM metalStockVm)
Please try the below one
change your model code like below
public class MetalStockAddVM
{
public MetalStock MetalStock { get; set; }
}
And then change you Action method code for HTTPPOST in AddMetalStock as below
[HttpPost]
public ActionResult AddMetalStock(MetalStockAddVM metalStock)
{
MetalStockDto metalStockDto = new MetalStockDto();
metalStockDto = Mapper.Map<MetalStock, MetalStockDto>(metalStock.MetalStock);
iMetalStockRepository.Insert(metalStockDto);
return RedirectToAction("Index","Home") ;
}

Resources