Binding a multi dimentional javascript array as method parameter in c# - javascript

hi i am looking for a way to bind this data :
columns[0][data]:0
columns[0][name]:
columns[0][searchable]:true
columns[0][orderable]:true
columns[0][search][value]:
columns[0][search][regex]:false
columns[1][data]:1
columns[1][name]:
columns[1][searchable]:true
columns[1][orderable]:true
columns[1][search][value]:
columns[1][search][regex]:false
columns[2][data]:2
columns[2][name]:
columns[2][searchable]:true
columns[2][orderable]:true
columns[2][search][value]:
columns[2][search][regex]:false
columns[3][data]:3
columns[3][name]:
columns[3][searchable]:true
columns[3][orderable]:true
columns[3][search][value]:
columns[3][search][regex]:false
columns[4][data]:4
columns[4][name]:
columns[4][searchable]:true
columns[4][orderable]:true
columns[4][search][value]:
columns[4][search][regex]:false
columns[5][data]:5
columns[5][name]:
columns[5][searchable]:true
columns[5][orderable]:true
columns[5][search][value]:
columns[5][search][regex]:false
columns[6][data]:6
columns[6][name]:
columns[6][searchable]:true
columns[6][orderable]:true
columns[6][search][value]:
columns[6][search][regex]:false
columns[7][data]:7
columns[7][name]:
columns[7][searchable]:true
columns[7][orderable]:true
columns[7][search][value]:
columns[7][search][regex]:false
columns[8][data]:8
columns[8][name]:
columns[8][searchable]:true
columns[8][orderable]:false
columns[8][search][value]:
columns[8][search][regex]:false
to my method so far i tried an object array but it didn't work here is my method definition:
public async Task<JsonResult> DriveDataTable(jQueryDataTableParamModel param)
and jQueryDataTableParamModel class :
public class jQueryDataTableParamModel
{
//Paging first record indicator. This is the start point in the current data set (0 index based - i.e. 0 is the first record).
public int start { get; set; }
// global search keyword
public string search { get; set; }
// Number of records that should be shown in table
public int length { get; set; }
//represent the index of column which is to ordered
public int orderByCol { get; set; }
//order direction (asc or desc)
public string orderDirection { get; set; }
public object[] columns { get; set; }
}

Assuming that myArr is your javascript multidimensional array you can npass it to c# in this way
JSON.stringify(myArr)
then in c# class you can change the property in
public object columns { get; set; }
but I think that also
public string columns { get; set; } should work
then server side you could deserialize it in some way
Usually I send serialized objects over javascript and when they come back in a string format to my C# methods I deserialize them in this way
[HttpPost]
public ActionResult MyMethod(string model)
{
//model in this case is what JSON.stringify(myArr) sends
var jsSettings = new JsonSerializerSettings();
jsSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
var deserializedModel = JsonConvert.DeserializeObject<MyComplexType>(model, jsSettings);
//now deserializedModel is of type MyComplexType
return PartialView("~/Views/Shared/Somefile.cshtml", deserializedModel);
}

Additional Information.
Here Is classes
public class JQDTParams
{
public int draw { get; set; }
public int start { get; set; }
public int length { get; set; }
public JQDTColumnSearch /*Dictionary<string, string>*/ search { get; set; }
public List<JQDTColumnOrder/*Dictionary<string, string>*/> order { get; set; }
public List<JQDTColumn/*Dictionary<string, string>*/> columns { get; set; }
}
public enum JQDTColumnOrderDirection
{
asc, desc
}
public class JQDTColumnOrder
{
public int column { get; set; }
public JQDTColumnOrderDirection dir { get; set; }
}
public class JQDTColumnSearch
{
public string value { get; set; }
public string regex { get; set; }
}
public class JQDTColumn
{
public string data { get; set; }
public string name { get; set; }
public Boolean searchable { get; set; }
public Boolean orderable { get; set; }
public JQDTColumnSearch search { get; set; }
}
And Usage
HTML
<div>
<table id="aractipiListesi" class="display" cellspacing="0" width="100%">
<thead>
<tr class="filter-input">
<th>PK</th>
<th>Markası</th>
<th>Modeli</th>
<th></th>
</tr>
<tr>
<th>PK</th>
<th>Markası</th>
<th>Modeli</th>
<th></th>
</tr>
</thead>
</table>
<script type="text/javascript">
$(document).ready(function () {
$('#aractipiListesi').DataTable({
"processing": true,
"serverSide": true,
"filter": true,
"pageLength": 8,
"columns": [
{
"name": "ID",
"orderable": false
},
{
"name": "MARKAADI",
"orderable": true
},
{
"name": "TIPADI",
"orderable": true
},
{
"name": "SEC",
"orderable": false
}
],
"ajax":
{
url: "#Url.Action("AracTipiAra", "Common", new { area = "" })",
type: "post"
},
"columnDefs":
[
{
"render": function (data, type, row) { return AracTipiListesiTableDropDownToggle(data, type, row); },
"targets": [3]
},
{
"visible": false,
"targets": [0]
}
],
"language": DTConstants.Language
});
var aractipi_filtrelenecekBasliklar = ['Markası', 'Modeli'];
// Setup - add a text input to each footer cell
$('#aractipiListesi thead .filter-input th').each(function () {
var title = $(this).text();
if (title != '' && $.inArray(title, aractipi_filtrelenecekBasliklar) >= 0) {
$(this).html('<input type="text" placeholder="' + title + ' Ara" />');
}
});
// DataTable
var table = $('#aractipiListesi').DataTable();
// Apply the search
table.columns().every(function () {
var that = this;
$('input', this.footer()).on('keyup change', function () {
if (that.search() !== this.value) {
that.search(this.value).draw();
}
});
});
});
</script>
</div>
Controller
public JsonResult AracTipiAra(JQDTParams param)
{
using (var db = new MBOSSEntities())
{
var q = from x in db.VW_ARACMARKATIPI select x;
var nonfilteredcount = q.Count();
//filter
//-------------------------------------------------------------------
foreach (var item in param.columns)
{
var filterText = item.search.value;
if (!String.IsNullOrEmpty(filterText))
{
filterText = filterText.ToLower();
switch (item.name)
{
case "MARKAADI":
q = q.Where(
x =>
x.MARKAADI.ToLower().Contains(filterText)
);
break;
case "TIPADI":
q = q.Where(
x =>
x.TIPADI.ToLower().Contains(filterText)
);
break;
}
}
}
//order
//-------------------------------------------------------------------
foreach (var item in param.order)
{
string orderingFunction = "MARKAADI";
switch (item.column)
{
case 1: orderingFunction = "MARKAADI";
break;
case 2: orderingFunction = "TIPADI";
break;
}
q = OrderClass.OrderBy<VW_ARACMARKATIPI>(q, orderingFunction, item.dir.GetStringValue());
}
//result
//-------------------------------------------------------------------
var filteredCount = q.Count();
q = q.Skip(param.start).Take(param.length);
var data = q.ToList()
.Select(r => new[] {
r.ARACMARKAPK.ToString(),
r.MARKAADI,
r.TIPADI,
}
);
return Json(new
{
draw = param.draw,
recordsTotal = nonfilteredcount,
recordsFiltered = filteredCount,
data = data
}, JsonRequestBehavior.AllowGet);
}
}

Related

ASP.NET MVC Query not showing Distinct values

I am using the following query for use in google charts. It works well but it doesnt show distinct months. Is there a way to sum all the HoursTaken per MonthOfHoliday to avoid not having distinct values?
var querythpmpro = (from r in db.HolidayRequestForms
where r.EmployeeID == id
select new { Count = r.HoursTaken, Value = r.MonthOfHoliday.ToString() }).OrderBy(e => e.Value);
Error message from the console Uncaught (in promise) Error: Type mismatch. Value 1 does not match type string in column index 0
EDIT:
#region Total Hours Per Month
var querythpmpro = (from r in db.HolidayRequestForms
where r.EmployeeID == id
group r by r.MonthOfHoliday into g
select new { Value = g.Key, Sum = g.Sum(h => h.HoursTaken) }
).OrderBy(e => e.Value);
var resultthpmpro = querythpmpro.ToList();
var datachartthpmpro = new object[resultthpmpro.Count];
int Q = 0;
foreach (var i in resultthpmpro)
{
datachartthpmpro[Q] = new object[] { i.Value, i.Sum};
Q++;
}
string datathpmpro = JsonConvert.SerializeObject(datachartthpmpro, Formatting.None);
ViewBag.datajthpmpro = new HtmlString(datathpmpro);
#endregion
Model:
public partial class HolidayRequestForm
{
public int RequestID { get; set; }
public int EmployeeID { get; set; }
public System.DateTime StartDate { get; set; }
public System.DateTime FinishDate { get; set; }
public decimal HoursTaken { get; set; }
public string Comments { get; set; }
public int YearCreated { get; set; }
public int MonthCreated { get; set; }
public int DayCreated { get; set; }
public Nullable<int> YearOfHoliday { get; set; }
public Nullable<bool> Approved { get; set; }
public string SubmittedBy { get; set; }
public string ApprovedBy { get; set; }
public Nullable<int> WorkWeek { get; set; }
public Nullable<int> MonthOfHoliday { get; set; }
public virtual Employee Employee { get; set; }
}
Script:
function drawChartA() {
// Create the data table.
var data = new google.visualization.DataTable();
data.addColumn('string', 'Value');
data.addColumn('number', 'Count');
data.addRows(datassthpmpro);
// Set chart options
var options = {
'title': 'Holiday Hours Taken Per Month',
'width': 600,
'height': 350,
'hAxis': { title: 'Month Number' },
'vAxis': { title: 'Holiday Hours Taken' },
'is3D': true,
'legend': 'none'
};
How about grouping by MonthOfHoliday and doing the Sum on HoursTaken:
var querythpmpro = (from r in db.HolidayRequestForms
where r.EmployeeID == id
group r by r.MonthOfHoliday into g
select new { Value = g.Key, Sum = g.Sum(h => h.HoursTaken) }
).OrderBy(e => e.Value);

500 Internal Server Error Asp.net C# Datatables

I've MVC 5 asp.net C# Project Inventory and Restaurant, when I use Datatable inside my project here's my html:
<table class="table table-striped table-bordered table-hover" id="dataTables-example">
<thead>
<tr>
<th>
#Resources.Tokens_Admin.Name
</th>
<th>
#Resources.Tokens_Admin.Category
</th>
<th>
#Resources.Tokens_Admin.Price
</th>
<th>
#Resources.Tokens_Admin.Image
</th>
<th>
</th>
</tr>
</thead>
<tfoot>
</tfoot>
</table>
and JavaScripts:
<script>
$(document).ready(function () {
$("#dataTables-example").DataTable({
"ajax": {`enter code here`
"url": "/Meals/GetMealsList",
"type": "POST",
"datatype": "json"
},
"columns": [
{ "data": "Name", "name": "Name" },
{ "data": "CatId", "name": "CatId" },
{ "data": "Price", "name": "Price" },
{ "data": "Image", "name": "Image" },
{
"data": "Id", "render": function (Id, type, full, meta) {
debugger
return '<i class="glyphicon glyphicon-pencil"></i>'
}
}
],
"serverSide": "true",
"order": [0, "asc"],
"processing": "true",
"language": {
"processing": "processing...please wait"
}
});
});
</script>
and the Controller:
[HttpPost]
public ActionResult GetMealsList()
{
// server-side parameters
int start = Convert.ToInt32(Request["start"]);
int length = Convert.ToInt32(Request["length"]);
string searchval = Request["search[value]"];
string sortColumnName = Request["columns[" + Request["order[0][column]"] + "][name]"];
string sortDirection = Request["order[0][dir]"];
var MealList = db.Meals.ToList();
int totalrows = MealList.Count();
if (!string.IsNullOrEmpty(searchval))
{
MealList = MealList.Where(x => x.Price.ToString().Contains(searchval.ToLower()) || x.Category.Name.ToLower().Contains(searchval.ToLower())
|| x.Name.ToLower().Contains(searchval.ToLower())).ToList();
}
int totalrowsafterfiltering = MealList.Count();
// sorting
MealList = MealList.OrderBy(sortColumnName + " " + sortDirection).ToList();
//paging
MealList = MealList.Skip(start).Take(length).ToList();
return Json(new { data = MealList, draw = Request["draw"], recordsTotal = totalrows, recordsFiltered = totalrowsafterfiltering }, JsonRequestBehavior.AllowGet);
}
when I run the view Index I've an Internal Server Error 500.
The resource cannot be found.
Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.
Requested URL: /Meals/GetMealsList
can anyone help please?
First I think changing your line in Javascript:
"url": "/Meals/GetMealsList",
to
"url": "#Url.Action("GetMealsList", "Meals")",
should fix it. I'm assuming your controller is called MealsController?
Second, I'd recommend doing something like the following, where you create ViewModels that represent the data that datatables is passing back, that should make your life a lot easier than how you're referencing the Request object as it should, using model binding, map the json data to your model.
Note, you shouldn't need the Newtonsoft.Json.JsonProperty lines, I just copied this code from a project where it had that already (related to a webapi).
public class DataTablesSearchModel
{
// properties are not capital due to json mapping
[Newtonsoft.Json.JsonProperty(PropertyName = "draw")]
public int Draw { get; set; }
[Newtonsoft.Json.JsonProperty(PropertyName = "start")]
public int Start { get; set; }
[Newtonsoft.Json.JsonProperty(PropertyName = "length")]
public int Length { get; set; }
[Newtonsoft.Json.JsonProperty(PropertyName = "columns")]
public List<Column> Columns { get; set; }
[Newtonsoft.Json.JsonProperty(PropertyName = "search")]
public Search Search { get; set; }
[Newtonsoft.Json.JsonProperty(PropertyName = "order")]
public List<Order> Order { get; set; }
}
public class Column
{
[Newtonsoft.Json.JsonProperty(PropertyName = "data")]
public string Data { get; set; }
[Newtonsoft.Json.JsonProperty(PropertyName = "name")]
public string Name { get; set; }
[Newtonsoft.Json.JsonProperty(PropertyName = "searchable")]
public bool Searchable { get; set; }
[Newtonsoft.Json.JsonProperty(PropertyName = "orderable")]
public bool Orderable { get; set; }
[Newtonsoft.Json.JsonProperty(PropertyName = "search")]
public Search Search { get; set; }
}
public class Search
{
[Newtonsoft.Json.JsonProperty(PropertyName = "value")]
public string Value { get; set; }
[Newtonsoft.Json.JsonProperty(PropertyName = "regex")]
public string Regex { get; set; }
}
public class Order
{
[Newtonsoft.Json.JsonProperty(PropertyName = "column")]
public int Column { get; set; }
[Newtonsoft.Json.JsonProperty(PropertyName = "dir")]
public string Dir { get; set; }
}
Then your controller action looks like this:
[HttpPost]
public ActionResult GetMealsList(DataTablesSearchModel model)
{
//Access model for the data passed by datatables.
}

JavaScript Datatables ajax 404 error when I added one more colum

I have an ASP.NET MVC application which using JavaScript Datatables extension. The table has 7 columns.
When I add one more column to the table, ajax 404 error occurres.
I'm gonna try to explain error with my codes;
DbModel.cs
public class City
{
public int CityId { get; set; }
public string CityName { get; set; }
public string PlateNumber { get; set; }
}
public class State
{
public City City { get; set; }
public int StateId { get; set; }
public string StateName { get; set; }
public string OrderNumber { get; set; }
}
public class Site
{
public State State { get; set; }
public int SiteId { get; set; }
public string AboneNo { get; set; }
public string SiteName { get; set; }
public string Address { get; set; }
public int BoilerCount { get; set; }
public int BlockCount { get; set; }
public string Abc { get; set; }
public DateTime CreatedDate { get; set; }
}
SiteController.cs
public ActionResult Index()
{
return View();
}
public JsonResult GetSites()
{
DbManager dbManager = new DbManager();
DataTable dt = dbManager.GetSites();
List<Site> allSites = new List<Site>();
foreach (DataRow row in dt.Rows)
{
City city = new City
{
CityId = Convert.ToInt32(row["il_id"]),
CityName = row["il_adi"].ToString(),
PlateNumber = row["plaka"].ToString()
};
State state = new State
{
City = city,
StateId = Convert.ToInt32(row["ilce_id"]),
StateName = row["ilce_adi"].ToString(),
OrderNumber = row["sira_no"].ToString()
};
Site site = new Site
{
State = state,
AboneNo = row["abone_no"].ToString(),
Abc = row["aktif"].ToString(),
Address = row["adres"].ToString(),
BlockCount = Convert.ToInt32(row["blok_sayisi"]),
BoilerCount = Convert.ToInt32(row["kazan_sayisi"]),
SiteId = Convert.ToInt32(row["site_id"]),
SiteName = row["site_adi"].ToString()
};
allSites.Add(site);
}
return Json(new { data = allSites }, JsonRequestBehavior.AllowGet);
}
Index.cshtml
<table class="table table-striped- table-bordered table-hover table-checkable" id="tbl_site">
<thead>
<tr>
<th>SİTE ID</th>
<th>ABONE NO</th>
<th>İL</th>
<th>İLÇE</th>
<th>SİTE ADI</th>
<th>ADRES</th>
<th>KAZAN SAYISI</th>
<th>BLOK SAYISI</th>
<th>Abc</th>
</tr>
</thead>
</table>
#section scripts{
#Scripts.Render("~/res/js/datatables.bundle.js")
<script>
$('#tbl_site').DataTable({
ajax: {
url: "Site/GetSites",
type: "GET",
dataType: "json",
error: function (error) {
alert(error);
}
},
processing: true,
serverSide: true,
columns: [
{ data: 'SiteId', autoWidth: true },
{ data: 'AboneNo', autoWidth: true },
{ data: 'State.City.CityName', autoWidth: true },
{ data: 'State.StateName', autoWidth: true },
{ data: 'SiteName', autoWidth: true },
{ data: 'Address', autoWidth: true },
{ data: 'BoilerCount', autoWidth: true },
{ data: 'BlockCount', autoWidth: true },
//{ data: 'Abc', autoWidth: true }
]
});
</script>
}
The ajax 404 error occurred when I uncomment the commented line in Index.cshtml

Three Tables Cascading DropdownList in Asp.net MVC

I want to have a cascading dropdownlist in Asp.Net MVC. I have managed to do it with Two Tables Country and State, now I want to add City.
public class Country
{
[Key]
public int cId { get; set; }
public string cName { get; set; }
public ICollection<State> state { get; set; }
}
public class State
{
[Key]
public int sId { get; set; }
public string sname { get; set; }
public int cId { get; set; }
public Country country { get; set; }
}
//Get list of States
public JsonResult GetStateList(int cId)
{
db.Configuration.ProxyCreationEnabled = false;
List<State> listState = db.States.Where(x => x.cId == cId).ToList();
return Json(listState,JsonRequestBehavior.AllowGet);
}
//Script that invokes the Method
$(document).ready(function () {
$("#cId").change(function () {
$.get("/Home/GetStateList", { cId: $("#cId").val() }, function (data) {
$("#sId").empty();
$.each(data, function (index, row) {
$("#sId").append("<option value= '"+row.sId+"'>"+ row.sname+"</option>")
});
});
})
});
Well just add this:
public class City
{
[Key]
public int cityId { get; set; }
public string cityName { get; set; }
public int sId { get; set; } // stateId
public State state { get; set; }
}
public JsonResult GetCityList(int sId)
{
db.Configuration.ProxyCreationEnabled = false;
List<City> listCity = db.Cities.Where(x => x.sId == sId).ToList();
return Json(listCity,JsonRequestBehavior.AllowGet);
}
$(document).ready(function () {
$("#sId").change(function () {
$.get("/Home/GetCityList", { sId: $("#sId").val() }, function (data) {
$("#cityId").empty();
$.each(data, function (index, row) {
$("#cityId").append("<option value= '"+row.cityId+"'>"+ row.cityName+"</option>")
});
});
})
});

KendoUI treeview children are displayed as undefined

I have a treeview in kendoUI in which main nodes are calling into an mvc controller and that controller looks to whether there is an nullable id passed in and then uses a different model.
What I hit the url : http://localhost:2949/Report/GetReportGroupAssignments
I see this JSON
[
{"Id":1,"ReportGroupName":"Standard Reports","ReportGroupNameResID":null,"SortOrder":1},
{"Id":2,"ReportGroupName":"Custom Reports","ReportGroupNameResID":null,"SortOrder":2},
{"Id":3,"ReportGroupName":"Retail Reports","ReportGroupNameResID":null,"SortOrder":3},
{"Id":4,"ReportGroupName":"Admin Reports","ReportGroupNameResID":null,"SortOrder":5},
{"Id":5,"ReportGroupName":"QA Reports","ReportGroupNameResID":null,"SortOrder":4}
]
Now my mvc controller looks like this
public JsonResult GetReportGroupAssignments(int? id)
{
var model = new List<ReportGroup>();
var defModel = new List<ReportDefinition>();
try
{
if (id == null)
{
model = _reportService.GetReportGroups("en-us").ToList();
return Json(model, JsonRequestBehavior.AllowGet);
}
else
{
defModel = _reportService.GetReportDefinitions().Where(e=>e.ReportGroupID ==Convert.ToInt32(id)).ToList();
return Json(defModel, JsonRequestBehavior.AllowGet);
}
}
catch (Exception ex)
{
Logger.Error(ex, "Error loading LoadReportList.");
return null;
}
}
My Kendo javascript looks like the following:
var serviceRoot = "/Report"; // "//demos.telerik.com/kendo-ui/service";
homogeneous = new kendo.data.HierarchicalDataSource({
transport: {
read: {
url: serviceRoot + "/GetReportGroupAssignments", //"/LoadReportTree", // "/Employees",
dataType: "json"
}
},
schema: {
model: {
id: "Id" //"ReportGroupName"
,hasChildren: "Id"
}
}
});
var treeview = $("#treeview").kendoTreeView({
expanded: true,
dragAndDrop: true,
dataSource: homogeneous,
dataTextField: "ReportGroupName"
}).data("kendoTreeView");
Seems that the calls (which I discovered that children records have a "load" method that it called behind the seens, so basically I pass in the ID in order to get the data from the other model ( table in db)
(Id is mapped with automapper to ReportGroupID )
So when i click to the left of "Standard Rports" I am getting all of these children as undefined, How do I get these to show up properly?
Update: My ReportDefinition class:
public class ReportDefinition {
public override int Id { get; set; }
public string ReportKey { get; set; }
public string ReportName { get; set; }
public int? ReportNameResID { get; set; }
public string ReportDef { get; set; }
public int? ReportDefinitionResID { get; set; }
public string ReportAssembly { get; set; }
public string ReportClass { get; set; }
public int ReportGroupID { get; set; }
public int AppID { get; set; }
public int SortOrder { get; set; }
public bool IsSubReport { get; set; }
}
I think your problem is that the class ReportDefinition does not have a property called: ReportGroupName. That is why TreeView displays 'undefined'.
Try adding this Property to your ReportDefinition class like:
public class ReportDefinition {
// Other Properties
// I guess this property is missing
public string ReportGroupName { get; set; }
}

Categories

Resources