ASP. NET Core MVC Problem creating Chart.js Using data from SQL Server - asp.net-core-mvc

I am trying to create a Chart.js from data I am getting from a SQL Table in ASP.NET Core MVC. I am successfully receiving the data, because I tested printing it as a table on the website and it worked. The problem is I am not being able to display the same data in a Chart.js
HomeModel.cs:
namespace SiteFinanceiroGG.Models
{
public class TickerCadastral
{
//...
}
[Keyless]
public class TickerCotacoes
{
public string CodigoNegociacao { get; set; }
[DataType(DataType.Date)]
public DateTime DataPregao { get; set; }
public string Moeda { get; set; }
[Column(TypeName = "decimal(13,2)")]
public double PrecoMin { get; set; }
[Column(TypeName = "decimal(13,2)")]
public double PrecoMax { get; set; }
[Column(TypeName = "decimal(13,2)")]
public double PrecoUltimoNegocio { get; set; }
}
public class TickerMultipleModel
{
public List<TickerCadastral> tickerCadastral { get; set; }
public List<TickerCotacoes> tickerCotacoes { get; set; }
}
}
MyDbContex.cs:
namespace SiteFinanceiroGG.Data
{
public class MyDbContext : DbContext
{
public MyDbContext (DbContextOptions<MyDbContext> options)
: base(options)
{
}
public DbSet<TickerCadastral> TickerCadastral { get; set; }
public DbSet<TickerCotacoes> TickerCotacoes { get; set; }
}
}
HomeController.cs:
namespace SiteFinanceiroGG.Controllers
{
public class HomeController : Controller
{
private readonly MyDbContext _context;
public HomeController(MyDbContext context)
{
_context = context;
}
public IActionResult Index()
{
return View();
}
public async Task<IActionResult> Acoes(string searchString)
{
if (searchString == null)
{
return View();
}
else
{
TickerMultipleModel tickerMultipleModel = new TickerMultipleModel();
tickerMultipleModel.tickerCadastral = await _context.TickerCadastral.Where(m => m.CodigoNegociacao == searchString).ToListAsync();
tickerMultipleModel.tickerCotacoes = await _context.TickerCotacoes.Where(m => m.CodigoNegociacao == searchString)
.OrderBy(m=>m.DataPregao).ToListAsync();
return View(tickerMultipleModel);
}
}
}
}
Acoes.cshtml (table works, but the chart doesn't show up):
#model SiteFinanceiroGG.Models.TickerMultipleModel
#{
ViewData["Title"] = "Ações";
}
<h2>Ações</h2>
#using (Html.BeginForm("Acoes", "Home", FormMethod.Get))
{
#Html.TextBox("searchString");
<input type="submit" value="Pesquisar" placeholder="Buscar Ações" />
}
#if (Model != null)
{
<div>
<canvas id="myChart" width="600" height="400"></canvas>
</div>
<table class="table">
<tbody>
<tr>
<th>#Html.DisplayNameFor(model => model.tickerCotacoes[0].DataPregao)</th>
<th>#Html.DisplayNameFor(model => model.tickerCotacoes[0].CodigoNegociacao)</th>
<th>#Html.DisplayNameFor(model => model.tickerCotacoes[0].Moeda)</th>
<th>#Html.DisplayNameFor(model => model.tickerCotacoes[0].PrecoMin)</th>
<th>#Html.DisplayNameFor(model => model.tickerCotacoes[0].PrecoMax)</th>
<th>#Html.DisplayNameFor(model => model.tickerCotacoes[0].PrecoUltimoNegocio)</th>
</tr>
#foreach (var item in Model.tickerCotacoes)
{
<tr>
<td>#item.DataPregao</td>
<td>#item.CodigoNegociacao</td>
<td>#item.Moeda</td>
<td>#item.PrecoMin</td>
<td>#item.PrecoMax</td>
<td>#item.PrecoUltimoNegocio</td>
</tr>
}
</tbody>
</table>
}
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
const ctx = document.getElementById('myChart');
var DataPregao = [];
var PrecoUltimoNegocio=[];
#if (Model != null)
{
#foreach(var item in Model.tickerCotacoes)
{
#:DataPregao.push(#item.DataPregao);
#:PrecoUltimoNegocio.push(Convert.ToDecimal(#item.PrecoUltimoNegocio));
}
}
new Chart(ctx, {
type: 'line',
data: {
labels: DataPregao,
datasets: [{
label: '# of Votes',
data: PrecoUltimoNegocio,
borderWidth: 1
}]
},
options: {
scales: {
y: {
beginAtZero: true
}
}
}
});
</script>

Modify your js code below:
#if (Model != null)
{
#foreach (var item in Model.tickerCotacoes)
{
#:DataPregao.push('#item.DataPregao'); //add '' surround the #item.DataPregao
//add # before Convert
#:PrecoUltimoNegocio.push(#Convert.ToDecimal(#item.PrecoUltimoNegocio));
}
}

Related

How do I Read and Display related data in asp.net mvc-core?

As a sample that I can build on, I want to use Teams.ClubNo to find Club.ClubNo and add Club.ClubName to the Teams Index page.
Sounds simple but I haven't found anything that works yet.
The filter (which I like) is confusing what I need to do in the controller.
No direct navigation exists in the database. Am using EF 2.1
Part of _context.Club and _context.Teams
public partial class Club
{
public Club()
public short ClubNo { get; set; }
public string ClubName { get; set; }
}
public partial class Teams
{
public Teams()
public string Division { get; set; }
public string Grade { get; set; }
public short HomeGround { get; set; }
public short ClubNo { get; set; }
}
Part of my TeamsController.cs to display my Index page.
public class TeamsController : Controller
{
private readonly SSFA_SQLContext _context;
public TeamsController(SSFA_SQLContext context)
{
_context = context;
}
// GET: Teams
public async Task<IActionResult> Index(string filter, string filter1, string filter2, int page = 1, string sortExpression = "Division")
{
var qry = _context.Teams.AsNoTracking().AsQueryable();
if (!string.IsNullOrWhiteSpace(filter))
{ qry = qry.Where(p => p.Division.Contains(filter)); }
var model = await PagingList.CreateAsync(qry, 15, page, sortExpression, "Division");
model.RouteValue = new RouteValueDictionary { "filter", filter } ;
return View(model);
}
Part of my Teams Index page.
<table class="table">
<thead>
<tr>
<td>
#Html.DisplayNameFor(model => model.Division)
</td>
<td>
#Html.DisplayNameFor(model => model.Grade)
</td>
<th>
#Html.DisplayNameFor(model => model.ClubNo)
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Division)
</td>
<td>
#Html.DisplayFor(modelItem => item.Grade)
</td>
<td>
#Html.DisplayFor(modelItem => item.ClubNo)
</td>
Since there is no navigation property between Club and Teams, you need to query the ClubName based on ClubNo. And since there is no ClubName in Teams, you need to define a new model which contains Clubname.
TeamsVM.cs
public partial class TeamsVM
{
public string Division { get; set; }
public string Grade { get; set; }
public string ClubName { get; set; }
}
And change query like below:
public async Task<IActionResult> Index1(string filter, string filter1, string filter2, int page = 1, string sortExpression = "Division")
{
var qry = _applicationDbContext.Teams.AsNoTracking().AsQueryable();
if (!string.IsNullOrWhiteSpace(filter))
{ qry = qry.Where(p => p.Division.Contains(filter)); }
var result = qry.Select(q => new TeamsVM
{
Division = q.Division,
Grade = q.Grade,
ClubName = _applicationDbContext.Club.FirstOrDefault(c => c.ClubNo == q.ClubNo).ClubName
});
var model = await PagingList.CreateAsync(result, 15, page, sortExpression, "Division");
model.RouteValue = new RouteValueDictionary { "filter", filter };
return Ok(result);
}
These 2 documents were very helpful.
https://learn.microsoft.com/en-us/ef/core/modeling/relationships
https://learn.microsoft.com/en-us/aspnet/core/data/ef-rp/read-related-data?view=aspnetcore-2.2&tabs=visual-studio
This is intended as a sample upon which to build other requirements of Related Data.
Part of my Models for Club.cs , Ground.cs and Teams.cs
public partial class Club
{
public Club()
public short ClubNo { get; set; }
public string ClubName { get; set; }
public string PhoneNo { get; set; }
}
public partial class Ground
{
public Ground()
public short GroundNo { get; set; }
public string GroundName { get; set; }
public string Address { get; set; }
}
public partial class Teams
{
public Teams()
public string Division { get; set; }
public string Grade { get; set; }
public short HomeGround { get; set; }
public short ClubNo { get; set; }
}
Part of my TeamsController.cs to display my Index page.
public class TeamsController : Controller
{
private readonly SSFA_SQLContext _context;
public TeamsController(SSFA_SQLContext context)
{
_context = context;
}
// GET: Teams
public async Task<IActionResult> Index(string filter, int page = 1, string sortExpression = "Division")
{
var qry = _context.Teams
.AsNoTracking()
.AsQueryable();
if (!string.IsNullOrWhiteSpace(filter))
{ qry = qry.Where(p => p.Division.Contains(filter)); }
var model = await PagingList.CreateAsync(qry, 15, page, sortExpression, "Division");
model.RouteValue = new RouteValueDictionary { "filter", filter } ;
return View(model);
}
Object is to display ClubName and GroundName on Teams Index page.
Solution: (Most probably one of many possible ways to do it).
Add following to Teams context.cs file: (No change is required to Club or Ground context files)
entity.HasOne(q => q.ClubNavigation);
entity.HasOne(q => q.GroundNavigation);
Add following to Teams.cs model file: (No change is required to Club or Ground model files)
public Club ClubNavigation { get; set; }
public Ground GroundNavigation { get; set; }
Add [ForeignKey("GroundNavigation")] above
public short HomeGround { get; set; }
(This one is required as HomeGround has to find GroundNo)
Add [ForeignKey("ClubNavigation")] above
public short ClubNo { get; set; }
As ClubNo is same in both files the second foreign key is not necessary but I think it is nice to have for consistency.
In TeamsController.cs change
var qry = _context.Teams
.AsNoTracking()
.AsQueryable();
To
var qry = _context.Teams
.Include(q => q.ClubNavigation)
.Include(q => q.GroundNavigation)
.AsNoTracking()
.AsQueryable();
Add following to Teams Index file:
<th>#Html.DisplayNameFor(model => model.HomeGround)</th>
<td><b>#Html.DisplayNameFor(model => model.GroundNavigation.GroundName)</b></td>
<th>#Html.DisplayNameFor(model => model.ClubNo)</th>
<td><b>#Html.DisplayNameFor(model => model.ClubNavigation.ClubName)</b></td>
And
<td>#Html.DisplayFor(modelItem => item.HomeGround)</td>
<td>#Html.DisplayFor(modelItem => item.GroundNavigation.GroundName)</td>
<td>#Html.DisplayFor(modelItem => item.ClubNo)</td>
<td>#Html.DisplayFor(modelItem => item.ClubNavigation.ClubName)</td>
That's it.

mvc 5 ajax: httpError 400.0 Bad request

having trouble with ajax i am using vs 2015 mvc 5.
following are the two model classes which have 1 to many relation.
i am facing some problem.
the view doesn't produce expected links i.e. instead
~/Global/Cities/Details/1 it result ~/Global/Cities/Details/ only.
when i fix that manually in browser it through httperror 400.0 Bade Request
when i remove Url property from ajax options the partial view opens in new tab window
namespace WebApplication1.Areas.Global.Models
{
public class Organization
{
public virtual int OrganizationId { get; set; }
public virtual int CityId { get; set; }
public virtual string Name { get; set; }
public virtual City city { get; set; }
}
public class City
{
public virtual int CityId { get; set; }
public virtual string Name { get; set; }
public virtual ICollection<Organization> Organization { get;set; }
}
}
and this is the partial view controller..
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
City city = db.Cities.Find(id);
if (city == null)
{
return HttpNotFound();
}
return PartialView(city);
}
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DropDownList("Organizations",new SelectList(item.Organization, "OrganizationId","Name"))
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.CityId }) |
#Ajax.ActionLink("Details", "Details",item.CityId,
new AjaxOptions
{
UpdateTargetId = "detail",
Url = Url.Action("Details",item.CityId)
}, new { id=item.CityId }) |
#Html.ActionLink("Delete", "Delete", new { id=item.CityId })
</td>
</tr>
i have also render jqueryval bundle in layout page...
is there any problem with my code please help....

Bar Chart of ChartJS does not Render

I am having trouble displaying bar chart from my ASP.NET-MVC-5 application. I witnessed the JSON comes out correctly (sample is applied below), and as per documentation I had included all, yet the output comes as below:
HTML:
<div class="jumbotron">
<h1>Another Chart</h1>
<canvas id="barChartLoc" width="600" height="400"></canvas>
</div>
This is the Script which calls the Controller, which returns a JSON:
<script type="text/javascript">
function chartFYRevenue() {
$.ajax({
url: '#Url.Action("GetLast5FYRevenueAnalysis", "Utility")',
cache: true
})
.done(function (data) {
var mybarChartLoc = new Chart(document.getElementById("barChartLoc").getContext("2d")).Bar(data);
})
.fail(function () {
alert("Ajax failed to fetch data");
});
}
$(document).ready(function () {
//auto load on page load
chartFYRevenue();
});
</script>
This is the Controller which returns a JSON. I have tested this and things are fine here as well:
public JsonResult GetLast5FYRevenueAnalysis()
{
Models.Chart.BarChartDBContext chartDB = new Models.Chart.BarChartDBContext();
return Json(chartDB.Test, JsonRequestBehavior.AllowGet);
}
This is the Modeler class where I build the Chart Data dynamically:
public class ChartDataSets
{
public string label { get; set; }
public string fillColor { get; set; }
public string highlightFill { get; set; }
public string highlightStroke { get; set; }
public string strokeColor { get; set; }
public string data { get; set; }
}
public class BarChartModel
{
public string labels { get; set; }
public List<ChartDataSets> datasets { get; set; }
}
public class BarChartDBContext : Models.DBHelper.DBHelperClass
{
public BarChartModel GetLast5FInancialYearRevenue
{
get { return getLast5FinancialYearRevenue(); }
}
public BarChartModel Test
{
get { return test(); }
}
private BarChartModel test()
{
List<ChartDataSets> _datasets = new List<ChartDataSets>();
BarChartModel _barChartModel = null;
_datasets.Add(new ChartDataSets()
{
data = string.Format("[{0}]", "10,5,25,35"),
fillColor = "rgba(220,220,220,0.5)",
highlightFill = "rgba(220,220,220,0.75)",
highlightStroke = "rgba(220,220,220,1)",
strokeColor = "rgba(220,220,220,0.8)",
label = "s1"
});
_barChartModel = new BarChartModel();
_barChartModel.labels = string.Format("[{0}]", "c1,c2,c3,c4");
_barChartModel.datasets = _datasets;
return _barChartModel;
}
}
JSON Data Sample:
{
"labels": "[c1,c2,c3,c4]",
"datasets": [
{
"label": "s1",
"fillColor": "rgba(220,220,220,0.5)",
"highlightFill": "rgba(220,220,220,0.75)",
"highlightStroke": "rgba(220,220,220,1)",
"strokeColor": "rgba(220,220,220,0.8)",
"data": "[10,5,25,35]"
}
]
}
Update:
I modified my ChartDataSet and BarChartModel Class to the following:
public class ChartDataSets
{
public string label { get; set; }
public string fillColor { get; set; }
public string highlightFill { get; set; }
public string highlightStroke { get; set; }
public string strokeColor { get; set; }
public string[] data { get; set; }
}
public class BarChartModel
{
public string[] labels { get; set; }
public List<ChartDataSets> datasets { get; set; }
}
Your JSON data generated is incorrect. The right output should be
"{
"labels": ["c1","c2","c3","c4"],
"datasets": [
{
"label":"s1",
"fillColor":"rgba(220,220,220,0.5)",
"highlightFill":"rgba(220,220,220,0.75)",
"highlightStroke":"rgba(220,220,220,1)",
"strokeColor":"rgba(220,220,220,0.8)",
"data":[10,5,25,35]
}
]
}"

Learning ASP.NET MVC 3 EntityFramework library 4.1.0.0 (not the latest) and getting no data

My context is:
public class RegistrationManagerContext : DbContext
{
public DbSet<User> Users { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<User>()
.ToTable("aspnet_Users");
}
}
and my User class is:
[Table("aspnet_Users")]
public class User
{
[Key]
[Display(AutoGenerateField = true)]
[Required]
public Guid UserId { get; set; }
[DataType("nvarchar")]
[MaxLength(256)]
[Required]
public string UserName { get; set; }
[DisplayFormat(ApplyFormatInEditMode = true, ConvertEmptyStringToNull = true, DataFormatString = "{0:d}")]
[Required]
public DateTime LastActivityDate { get; set; }
[NotMapped]
public AccountProfile Profile
{
get
{
if (_profile == null)
{
_profile = AccountProfile.GetUserProfile(this.UserName);
}
return _profile;
}
}
private AccountProfile _profile = null;
}
and my call method (Controller) is:
namespace RegistrationManager.Controllers
{
[Authorize(Roles="Admins")]
public class AdminController : Controller
{
private RegistrationManagerContext db = new RegistrationManagerContext();
//
// GET: /Admin/
public ActionResult Index(int? id)
{
var viewModel = db.Users;
if (id.HasValue)
{
ViewBag.UserID = id.Value;
}
return View(viewModel);
}
}
}
My view is:
#model IEnumerable<RegistrationManager.Models.User>
#{
ViewBag.Title = "Users";
}
<h2>Users</h2>
<table>
<tr>
<th>Email Address</th>
<th>Given Names</th>
<th>Surname</th>
<th>Last Ac</th>
<th>Refresh</th>
</tr>
#foreach (var item in Model)
{
string selectedRow = "";
if (ViewBag.UserId != null && item.UserId == ViewBag.UserId)
{
selectedRow = "selectedrow";
}
<tr class="#selectedRow" valign="top">
<td>
#item.UserName
</td>
<td>
#item.Profile.GivenNames
</td>
<td>
#item.Profile.Surname
</td>
<td>
#String.Format("{0:d}", item.LastActivityDate)
</td>
<td>
#Html.ActionLink("Refresh", "Refresh", "Admin", new { id = item.UserId })
</td>
</tr>
}
</table>
So what am I doing wrong or what am I missing?? As I get no data!!?? There is definitely data as I should at least see my own login, right!?
Shouldn't you be doing something like this:
public ActionResult Index(Guid? id)
{
if (id.HasValue)
{
var viewModel = db.Users.Where(x=>x.UserId == id.Value).FirstOrDefault();
//ViewBag.UserID = id.Value; //You do not need it here
if(viewModel != null)
return View(viewModel);
}
return RedirectToAction("UsersListPage");
}
UPDATE #1
Controller:
public ViewResult Index(){
return View(db.Users.ToList());
}
View:
#model IEnumerable<YourNamespace.User>
#foreach (var user in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => user.UserName)
</td>
</tr>
}
Isn't this working for you?

MVC3 cannot display other table value using foreign key

I am trying to display two values in a entity by using two foreign keys.
I have three tables; one of table is Product table.
Two tables are Category and Model for displaying these value 'name', and 'modelName'.
When I use LINQ, I was using this coding before adding the Model entity.
var product = from a in db.Product.Include(a => a.Category)
select a;
How can I add Model entity in here?
such as
var product = from a in db.Product.Include(a => a.Category, a => a.Model)
select a;
Is it possible to write?
Here is my models.
--Prodruct.cs--
public class Product
{
[Key] public int productId { get; set; }
[Required(ErrorMessage = "Please select category")]
public int categoryId { get; set; }
[Required(ErrorMessage = "Please select model")]
public int modelId { get; set; }
[DisplayName("Model name")]
public String model { get; set; }
public virtual Category Category { get; set; }
public virtual Model Model { get; set; }
}
--Category.cs--
public class Category
{
[Key] public int categoryId { get; set; }
public String name { get; set; }
}
--Model.cs--
public class Model
{
[Key] public int modelId { get; set; }
public String name { get; set; }
}
--RentalDB.cs--
public class rentalDB : DbContext
{
public DbSet<Product> Product { get; set; }
public DbSet<Model> Model { get; set; }
public DbSet<Customer> Customer { get; set; }
public DbSet<Order> Order { get; set; }
public DbSet<Cart> Cart { get; set; }
public DbSet<Category> Category { get; set; }
public DbSet<OrderDetails> OrderDetails { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
Please let me know how to put inner join(?) in LINQ.
Thank you.
I think you might want the following since Include returns IQueryable:
var product = from a in db.Product.Include(a => a.Category).Include(a => a.Model)
select a;
Is this what you need in your ProductController.cs?...
public ViewResult index(int param_categoryId, int param_modelId)
{
List<Product> locvar_CollectionOfProduct
= getCollectionOfProduct(param_categoryId, param_modelId);
return View("index", locvar_CollectionOfProduct);
}
private List<Product> getCollectionOfProduct(int param_categoryId, int param_modelId)
{
return db.Product.Where(a => a.categoryId == param_categoryId && a.modelId == param_modelId).ToList();
}
public void Product_Save(List<Product> param_CollectionOfProduct)
{
if (Model.IsValid)
{
foreach (Product i_Product in param_CollectionOfProduct)
{
Product locvar_Product = null;
if (i_Product.productId == null || i_Product.productId == 0)
{
locvar_Product = new Product();
}
else
{
locvar_Product = new Product{productId = i_Product.productId};
db.Product.Attach(locvar_Product)
}
locvar_Product.categoryId = i_Product.categoryId;
locvar_Product.modelId = i_Product.modelId;
if (i_Product.productId == null || i_Product.productId == 0)
{
db.Product.Add(locvar_Product);
}
}
db.SaveChanges();
}
}
and then in your "Views\Product\index.cshtml" view you can iterate through these. I'll put them in a table for you:
#using insert_entity_reference_here.Models;
#model List<Product>
#{
List<Product> param_CollectionOfProduct = Model;
}
#using (Ajax.BeginForm("Product_Save", "Product", null, new AjaxOptions { HttpMethod = "POST" }))
{
<table style="width:100%">
<tr>
<th>
Category Name
</th>
<th>
Model Name
</th>
</tr>
#if(Model.Count() > 0)
{
for( i_Product = 0 ; i_Product < Model.Count() ; i_Product++ )
{
#Html.HiddenFor(modelItem => param_CollectionOfProduct[i_Product].productId)
<tr>
<td>
#Html.HiddenFor(modelItem => param_CollectionOfProduct[i_Product].Category.categoryId)
#Html.EditorFor(modelItem => param_CollectionOfProduct[i_Product].Category.Name, new { style="width:100%" })
#Html.ValidationMessageFor(modelItem => param_CollectionOfProduct[i_Product].Category.Name)
</td>
<td>
#Html.HiddenFor(modelItem => param_CollectionOfProduct[i_Product].Model.modelId)
#Html.EditorFor(modelItem => param_CollectionOfProduct[i_Product].Model.Name, new { style="width:100%" })
#Html.ValidationMessageFor(modelItem => param_CollectionOfProduct[i_Product].Model.Name)
</td>
</tr>
}
}
</table>
<input type="submit">Save</input>
}
Let me know if I'm on the right track. If so, I should be able to help you some more.
Best Regards,
Nick

Resources