I have a list where I put in some values to different class properties, and then I am use a linq query to sort out specific value.
List<Artikel> Minlista = new List<Artikel>();
Minlista.Add(new Artikel { Varonamn = "Mjölk", Pris = 14.90, kategori = new Kategori {Namn = "Mejeri"}, });
Minlista.Add(new Artikel { Varonamn = "Apelsin", Pris = 7.90, kategori = new Kategori { Namn = "Frukt" } });
Minlista.Add(new Artikel { Varonamn = "Skinka", Pris = 20, kategori = new Kategori { Namn = "Kött" }, });
Minlista.Add(new Artikel { Varonamn = "Räkost", Pris = 33, kategori = new Kategori { Namn = "Mejeri" }, });
Minlista.Add(new Artikel { Varonamn = "Köttfärs", Pris = 45, kategori = new Kategori { Namn = "Kött" }, });
var specifikvara = from item in Minlista
where item.Pris < 34
select item;
foreach (var item in specifikvara)
{
Console.WriteLine("{0}", item);
}
This is supposed to find a price (Pris in swedish) that is less then 34. I get 4 "values" into my var specifikvara, and then I print it out. But I want to print out the name of the artikel (Varonamn) but I only recieve this message on the console "Consoleapplikation1.Artikel". How can I change it so it writes out "Skinka" or "Räkost" or any of them?
You are selecting bunch of Artikel type objects, that's why you are getting the default ToString() value. You can either:
1. select item.Varonamn
2. Console.WriteLine("{0}", item.Varonamn);
3 override ToString in Artikel object
In your example, item in the loop is of type Artikel. If you need to print its name, print the attribute that has the name:
Console.WriteLine("{0}", item.Varonamn);
You can reference other attributes, too:
Console.WriteLine("{0} : {1}", item.Varonamn, item.Pris);
Related
I want to have ActionLink "Details", "Edit" and "Delete" according to ID with an Ajax list, I managed to get my list out with datatable without having my columns in the script as you can see in my code, I would like to add the 3 links at the end of my table.
This is my controller:
[HttpGet]
public string Loadregistrationslist(int draw, int? start, int? length)
{
try
{
int IdFilter = 0;
string textFilter = "";
if (start == null)
{
start = 0;
}
else
{
start -= 1;
}
if (start < 1)
start = 0;
if (length == null)
{
length = 10;
}
var QueryString = HttpContext.Request.QueryString;
var orderBy = QueryString.Get("order[0][column]");
var orderByDir = QueryString.Get("order[0][dir]");
var search = QueryString.Get("search[value]");
var query = db.Registrations.Select(r => new RegistrationsList()
{
ID = r.ID,
FullName = r.LastName + " " + r.FirstName,
Email = r.Email,
BirthDate = r.BirthDate
});
if (search != null) {
int n;
search = search.Trim();
var isNumeric = int.TryParse(search, out n);
if (isNumeric)
{
IdFilter = n;
query = query.Where(x => x.ID == IdFilter);
}
else if (search != "")
{
textFilter = search;
query = query.Where(x => x.FullName.Contains(textFilter) || x.Email.Contains(textFilter));
}
}
string sortOrder = $"{orderBy}_{orderByDir.ToUpper()}";
switch (sortOrder)
{
//FullName
case "1_DESC":
query = query.OrderByDescending(s => s.FullName);
break;
case "1_ASC":
query = query.OrderBy(s => s.FullName);
break;
//Email
case "2_DESC":
query = query.OrderByDescending(s => s.Email);
break;
case "2_ASC":
query = query.OrderBy(s => s.Email);
break;
//ID
case "0_DESC":
query = query.OrderByDescending(s => s.ID);
break;
default: // ID ascending
query = query.OrderBy(s => s.ID);
break;
}
var data = query.Skip((int)start).Take((int)length).ToList<RegistrationsList>();
var lstData = new List<List<string>>();
foreach (var dataRow in data) {
var row = new List<string>() {
dataRow.ID.ToString(), dataRow.FullName, dataRow.Email, dataRow.BirthDate.ToString()
};
lstData.Add(row);
}
var recordsTotal = db.Registrations.Select(x => x.ID).Count();
var recordsFiltered = query.Count();
var response = new DataTablesResponse()
{
draw = draw,
recordsTotal = recordsTotal,
recordsFiltered = recordsFiltered,
data = lstData
};
return JsonConvert.SerializeObject(response, _jsonSerializerSettings);
}
catch (AjaxFunctionalException ex)
{
return JsonConvert.SerializeObject(new DataTablesResponse()
{
draw = draw,
recordsTotal = 0,
recordsFiltered = 0,
data = new List<List<string>>()/*,
errcode = ex.code,
errmessage = ex.Message,
errdata = ex.data*/
}, _jsonSerializerSettings);
}
catch (Exception ex)
{
return JsonConvert.SerializeObject(new DataTablesResponse()
{
draw = draw,
recordsTotal = 0,
recordsFiltered = 0,
data = new List<List<string>>()
/*code = 5000,
message = ex.Message,
data = null*/
}, _jsonSerializerSettings);
}
}
This is my ajax call:
$(document).ready(function ()
{
$("#registrationTable").DataTable({
"processing": true,
"serverSide": true,
"ajax": {
"url": "/Home/Loadregistrationslist",
"type": "GET",
"datatype": "json"
}
});
});
And this is my html for the table:
<table id="registrationTable" class="table table-striped dt-responsive display datatable dtr-inline" role="grid" aria-describedby="example-1_info">
<thead>
<tr>
<th>
ID
</th>
<th>
#Resource.FullName
</th>
<th>
#Resource.Email
</th>
<th class="sorting_desc_disabled sorting_asc_disabled">
#Resource.BirthDate
</th>
#*<th>
Edit
</th>
<th>
Delete
</th>*#
</tr>
</thead>
</table>
I found the solution, my controller changes a little bit, so here is my new code:
In my controller:
[HttpGet]
public string Loadregistrationslist(int draw, int? start, int? length)
{
try
{
int IdFilter = 0;
string textFilter = "";
if (start == null)
{
start = 0;
}
else
{
start -= 1;
}
if (start < 1)
start = 0;
if (length == null)
{
length = 10;
}
string orderByDir, search;
int orderByIdx;
List<string> cols = ExtractDataSortAndFilter(out orderByIdx, out orderByDir, out search);
var query = db.Registrations.Select(r => new RegistrationsList()
{
ID = r.ID,
FullName = r.LastName + " " + r.FirstName,
Email = r.Email,
BirthDate = r.BirthDate
});
if (search != null)
{
int n;
search = search.Trim();
var isNumeric = int.TryParse(search, out n);
if (isNumeric)
{
IdFilter = n;
query = query.Where(x => x.ID == IdFilter);
}
else if (search != "")
{
textFilter = search;
query = query.Where(x => x.FullName.Contains(textFilter) || x.Email.Contains(textFilter));
}
}
string sortOrder = $"{cols[orderByIdx]}_{orderByDir.ToUpper()}";
switch (sortOrder)
{
//FullName
case "FullName_DESC":
query = query.OrderByDescending(s => s.FullName);
break;
case "FullName_ASC":
query = query.OrderBy(s => s.FullName);
break;
//Email
case "Email_DESC":
query = query.OrderByDescending(s => s.Email);
break;
case "Email_ASC":
query = query.OrderBy(s => s.Email);
break;
//ID
case "ID_DESC":
query = query.OrderByDescending(s => s.ID);
break;
default: // ID ascending
query = query.OrderBy(s => s.ID);
break;
}
var data = new List<RegistrationsList>();
if (length > -1)
{
data = query.Skip((int)start).Take((int)length).ToList<RegistrationsList>();
}
else
{
data = query.Skip((int)start).ToList<RegistrationsList>();
}
/*var lstData = new List<List<string>>();
foreach (var dataRow in data) {
var row = new List<string>() {
dataRow.ID.ToString(), dataRow.FullName, dataRow.Email, dataRow.BirthDate.ToString()
};
lstData.Add(row);
}*/
var recordsTotal = db.Registrations.Select(x => x.ID).Count();
var recordsFiltered = query.Count();
var response = new DataTablesResponse()
{
draw = draw,
recordsTotal = recordsTotal,
recordsFiltered = recordsFiltered,
data = data
};
return JsonConvert.SerializeObject(response, _jsonSerializerSettings);
}
catch (AjaxFunctionalException ex)
{
return JsonConvert.SerializeObject(new DataTablesResponse()
{
draw = draw,
recordsTotal = 0,
recordsFiltered = 0,
data = new List<RegistrationsList>()/*,
errcode = ex.code,
errmessage = ex.Message,
errdata = ex.data*/
}, _jsonSerializerSettings);
}
catch (Exception ex)
{
return JsonConvert.SerializeObject(new DataTablesResponse()
{
draw = draw,
recordsTotal = 0,
recordsFiltered = 0,
data = new List<RegistrationsList>()
/*code = 5000,
message = ex.Message,
data = null*/
}, _jsonSerializerSettings);
}
}
private List<string> ExtractDataSortAndFilter(out int orderByIdx, out string orderByDir, out string search)
{
List<string> cols;
var QueryString = HttpContext.Request.QueryString;
cols = new List<string>();
string colName = null, colNamePath = "";
int colIdx = 0;
do
{
colNamePath = "columns[" + colIdx + "][data]";
colName = QueryString.Get(colNamePath);
cols.Add(colName);
colIdx++;
} while (colName != null);
string orderBy = QueryString.Get("order[0][column]");
orderByDir = QueryString.Get("order[0][dir]");
search = QueryString.Get("search[value]");
orderByIdx = orderBy == null ? 0 : int.Parse(orderBy);
orderByDir = orderByDir == null ? "asc" : orderByDir;
search = search == null ? "" : search;
return cols;
}
and this is my script:
$(document).ready(function () {
$("#registrationTable").DataTable({
"lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]],
"processing": true,
"serverSide": true,
"ajax": {
"url": "/Home/Loadregistrationslist",
"type": "GET",
"datatype": "json"
},
"columns": [
{
data: null,
title: "<input type=\"checkbox\" id=\"btnSelAllStudents\">",
render: function (data, type, row, meta) {
return '<input type="checkbox" id="cbxRegStudent_' + row.ID + '" value="' + row.ID + '">';
},
targets: "no-sort",
orderable: false
},
{ data: "ID", title: "ID" },
{ data: "FullName", title: "#Resource.FullName" },
{ data: "Email", title: "#Resource.Email" },
{ data: "BirthDate", title: "#Resource.BirthDate" },
{
data: null, title: "Actions",
render: function (data, type, row, meta) {
/*return '<input type="button" class="btn-print printrec" id="' + row.ID + '" value="Print"/>';*/
return '#Resource.Profile | #Resource.Edit';
},
targets: "no-sort",
orderable: false
}
],
order: [],
});
$("#btnSelAllStudents").on("change", function (e) {
$("input[id^='cbxRegStudent_']").prop("checked", $(this).prop("checked"));
});
$('#registrationTable').on('processing.dt', function (e, settings, processing) {
$("#btnSelAllStudents").prop("checked", false);
}).dataTable();
});
New to MVC and Stackoverflow so sorry for not having enough reputation to post images...
Trying to render a ListBox with pre selected values
My SQL Database:
http://i.imgur.com/bcdXyqE.png
My Entity Framework
http://i.imgur.com/wYWXuAq.png
My Controller
public ActionResult AccessRights(int id)
{
var user = db.User.Find(id);
var roles = db.Role;
var newList = new List<SelectListItem>();
foreach (var role in roles)
{
newList.Add(
new SelectListItem()
{
Value = role.Id.ToString(),
Text = role.RoleName,
Selected = user.Role.Contains(role)
}
);
}
ViewBag.x = new SelectList(newList, "Value", "Text");
ViewBag.Roles = new SelectList(db.Role, "Id", "RoleName", user.Role);
return View(user);
}
My View
<p>try1:</p>
#Html.ListBox("Roles", null, new { #class = "form-control", #size = 6, #style = "height: initial" })
<p>try2:</p>
#Html.ListBox("x", null, new { #size = 6, #style = "height: initial" })
Non of the 2 tries renders with pre selected values?
got it working.
public ActionResult AccessRights(int id)
{
var user = db.User.Find(id);
IEnumerable<SelectListItem> roles = db.Role.Select(c => new SelectListItem{ Value = c.Id.ToString(), Text = c.RoleName, Selected = true});
var rolesSelected = new int[user.Role.Count];
var i = 0;
foreach (var role in user.Role)
{
rolesSelected[i] = role.Id;
i++;
}
ViewBag.Roles = roles.ToList();
ViewBag.RolesSelected = rolesSelected;
return View(user);
}
#Html.ListBox("RolesSelect", new MultiSelectList(ViewBag.Roles, "Value", "Text", ViewBag.RolesSelected), new { #class = "form-control", #size = 6, #style = "height: initial" })
I have that lambda:
var Ids = profileExample.CostCenters
.Where(CostCentre => CostCentre != null)
.Select(CostCentre => CostCentre.Id);
Then i convert to that expression tree
static IEnumerable<Int64> AboveLambdaConvertedToExpressionTree(Profile profileExample)
{
//Begin var Ids = profileExample.CostCenters.Where(CostCentre => CostCentre != null).Select(CostCentre => CostCentre.Id);
var property = profileExample.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(x => x.Name != "Id").First();
var collection = ((IEnumerable)property.GetValue(profileExample, null)).AsQueryable();
var collectionType = property.PropertyType.GetGenericArguments()[0];
var collectionTypeName = collectionType.Name;
var keyType = typeof(Int64);
var keyName = "Id";
//BeginWhere
var parameter = Expression.Parameter(collectionType, collectionTypeName);
var profileExampleWhere = Expression.Lambda(
Expression.NotEqual(parameter, Expression.Constant(null)),
parameter);
var profileExampleWhereCall = Expression.Call(typeof(Enumerable),
"Where",
new Type[] { collectionType },
collection.Expression,
profileExampleWhere);
//EndWhere
//BeginSelect
var profileExampleSelect = Expression.Lambda(Expression.PropertyOrField(parameter, keyName),
parameter);
var profileExampleSelectCall = Expression.Call(typeof(Enumerable),
"Select",
new Type[] { collectionType, keyType },
profileExampleWhereCall,
profileExampleSelect);
var Ids = Expression.Lambda(profileExampleSelectCall).Compile().DynamicInvoke();
//EndSelect
//End var Ids = profileExample.CostCenters.Where(CostCentre => CostCentre != null).Select(CostCentre => CostCentre.Id);
return ((IEnumerable)Ids).Cast<Int64>();
}
Now i want to do the same with bellow lambda
var result = Set.AsQueryable()
.Where(Profile => Profile.CostCenters.Select(CostCentre => CostCentre.Id)
.Any(Id => Ids.Contains(Id))).ToList();
But i stuck in .Any(Id => Ids.Contains(Id))....
var id = Expression.Parameter(typeof(long), "Id");
var costCentre = Expression.Parameter(typeof(CostCentre), "CostCentre");
var profile = Expression.Parameter(typeof(Profile), "Profile");
var selectLambda = Expression.Lambda(Expression.PropertyOrField(costCentre, "Id"), costCentre);
var selectCall = Expression.Call(typeof(Enumerable),
"Select",
new Type[] { typeof(CostCentre), typeof(long) },
Expression.PropertyOrField(profile, "CostCenters"),
selectLambda);
How can i call Any from selectCall and call Ids.Contains...
Full code to run as console application bellow:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
namespace ExpressionTrees
{
class Program
{
static void Main(string[] args)
{
var Ids = profileExample.CostCenters.Where(CostCentre => CostCentre != null).Select(CostCentre => CostCentre.Id);
Ids = AboveLambdaConvertedToExpressionTree(profileExample);
var result = Set.AsQueryable().Where(Profile => Profile.CostCenters.Select(CostCentre => CostCentre.Id).Any(Id => Ids.Contains(Id))).ToList();
//Expression<Func<Profile, bool>> lambda = (Profile) => Profile.CostCenters.Select(CostCentre => CostCentre.Id).Any(Id => Ids.Contains(Id));
var id = Expression.Parameter(typeof(long), "Id");
var costCentre = Expression.Parameter(typeof(CostCentre), "CostCentre");
var profile = Expression.Parameter(typeof(Profile), "Profile");
var selectLambda = Expression.Lambda(Expression.PropertyOrField(costCentre, "Id"), costCentre);
var selectCall = Expression.Call(typeof(Enumerable),
"Select",
new Type[] { typeof(CostCentre), typeof(long) },
Expression.PropertyOrField(profile, "CostCenters"),
selectLambda);
}
static IEnumerable<Int64> AboveLambdaConvertedToExpressionTree(Profile profileExample)
{
// I show that as example of what i need to do
var keyType = typeof(Int64);
var keyName = "Id";
//Begin var Ids = profileExample.CostCenters.Where(CostCentre => CostCentre != null).Select(CostCentre => CostCentre.Id);
var property = profileExample.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(x => x.Name != keyName).First();
var collection = ((IEnumerable)property.GetValue(profileExample, null)).AsQueryable();
var collectionType = property.PropertyType.GetGenericArguments()[0];
var collectionTypeName = collectionType.Name;
//BeginWhere
var parameter = Expression.Parameter(collectionType, collectionTypeName);
var profileExampleWhere = Expression.Lambda(
Expression.NotEqual(parameter, Expression.Constant(null)),
parameter);
var profileExampleWhereCall = Expression.Call(typeof(Enumerable),
"Where",
new Type[] { collectionType },
collection.Expression,
profileExampleWhere);
//EndWhere
//BeginSelect
var profileExampleSelect = Expression.Lambda(Expression.PropertyOrField(parameter, keyName),
parameter);
var profileExampleSelectCall = Expression.Call(typeof(Enumerable),
"Select",
new Type[] { collectionType, keyType },
profileExampleWhereCall,
profileExampleSelect);
var Ids = Expression.Lambda(profileExampleSelectCall).Compile().DynamicInvoke();
//EndSelect
//End var Ids = profileExample.CostCenters.Where(CostCentre => CostCentre != null).Select(CostCentre => CostCentre.Id);
return ((IEnumerable)Ids).Cast<Int64>();
}
public partial class Profile
{
public virtual Int64 Id { get; set; }
public virtual ICollection<CostCentre> CostCenters { get; set; }
}
public partial class CostCentre
{
public virtual Int64 Id { get; set; }
}
public static Profile profileExample
{
get
{
return new Profile()
{
Id = 1,
CostCenters = new List<CostCentre>() { new CostCentre() { Id = 2 } }
};
}
}
public static IList<Profile> Set
{
get
{
return new List<Profile>() { new Profile() { Id = 1,
CostCenters = new List<CostCentre>() { new CostCentre() { Id = 1 },
new CostCentre() { Id = 2 } }
},
new Profile() { Id = 2,
CostCenters = new List<CostCentre>() { new CostCentre() { Id = 2 },
new CostCentre() { Id = 3 } }
},
new Profile() { Id = 3,
CostCenters = new List<CostCentre>() { new CostCentre() { Id = 3 } }
} };
}
}
}
}
Since Any is a Generic Method you need to create it for a specific type. The method below gets the Any<T> method from the Enumerable type.
public static MethodInfo GetAnyExtensionMethod(Type forType)
{
MethodInfo method =
typeof(Enumerable).GetMethods()
.First(m => m.Name.Equals("Any") &&
m.GetParameters().Count() == 2);
return method.MakeGenericMethod(new[] { forType });
}
Its solved with help of Mads from MS
class Program
{
static void Main(string[] args)
{
//var Ids = profileExample.CostCenters.Where(CostCentre => CostCentre != null).Select(CostCentre => CostCentre.Id);
var Ids = AboveLambdaConvertedToExpressionTree(profileExample);
//var result = Set.AsQueryable().Where(Profile => Profile.CostCenters.Select(CostCentre => CostCentre.Id).Any(Id => Ids.Contains(Id))).ToList();
var id = Expression.Parameter(typeof(long), "Id");
var costCentre = Expression.Parameter(typeof(CostCentre), "CostCentre");
var profile = Expression.Parameter(typeof(Profile), "Profile");
var selectLambda = Expression.Lambda(Expression.PropertyOrField(costCentre, "Id"), costCentre);
var selectCall = Expression.Call(typeof(Enumerable),
"Select",
new Type[] { typeof(CostCentre), typeof(long) },
Expression.PropertyOrField(profile, "CostCenters"),
selectLambda);
//var id2 = Expression.Parameter(typeof(long), "Id");
var containsCall = Expression.Call(typeof(Enumerable),
"Contains",
new Type[] { typeof(long) },
Expression.Constant(Ids),
id);
var anyLambda = Expression.Lambda(containsCall, id);
var anyCall = Expression.Call(typeof(Enumerable),
"Any",
new Type[] { typeof(long) },
selectCall,
anyLambda);
var whereLambda = Expression.Lambda(anyCall, profile);
var callExpression = Expression.Call(typeof(Queryable),
"Where",
new Type[] { typeof(Profile) },
Set.AsQueryable().Expression,
whereLambda);
var result = Expression.Lambda(callExpression).Compile().DynamicInvoke();
}
I have to display a treeview .But it will take much time, that's why I want to load this treeview on demand.At the first I want just display first level, and repeating that level by level.
This is the view
$("#onflycheckboxes").jstree({
json_data: {
"ajax": {
"url": function (node) {
var nodeId = "";
var url = ""
if (node == -1) {
url = "/TreeView/GetCollectionWS/source";
}
else {
nodeId = node.attr('id');
url = "/TreeView/GetCollectionWS/" + nodeId;
}
return url;
},
"type": "POST",
"dataType": "json",
"contentType": "application/json charset=utf-8"
}
},
checkbox: {
real_checkboxes: true,
checked_parent_open: true
},
plugins: ["themes", "json_data", "ui", "checkbox"]
});
this is the controller
public virtual ActionResult GetCollectionWS(string root)
{
int? nodeId = (root == source) ? (int?)null : Convert.ToInt32(root);
Object[] liste = new Object[100];
liste = DSClient.Views.Traitement.getTop(nodeId);
List<TreeViewNode> nodes = new List<TreeViewNode>();
for (int i = 0; (i < liste.Length && liste.ElementAt(i) != null);i++ )
{
bool leaf = false;
nodes.Add(new TreeViewNode()
{
id = Convert.ToString(DSClient.Views.Traitement.GetNodeId(liste.ElementAt(i))),
text = liste.ElementAt(i).Handle,
classes = leaf ? "file" : "folder",
hasChildren = !leaf
});
}
return Json(nodes);
}
when I try a breakpoint on the line return Json(nodes); I remarque that nodes contains
at the first {id=0,text=Collection-10,classes=folder,haChildren=false}
the view display nothing.Please, can any one help me??
public virtual string GetCollectionWS(string id)
{
Object[] liste = new Object[100];
client = new DSServiceClient();
if (id == "source")
{
Collection[] _top = new Collection[100];
client.Open();
_top = client.GetTopCollections();
client.Close();
for (int i = 0; i < _top.Length; i++)
{
DSClient.Controllers.Object obji = new DSClient.Controllers.Object();
obji.Handle = _top[i].Handle;
obji.Name = _top[i].Title;
liste[i] = obji;
}
}
else
{
client = new DSServiceClient();
client.Open();
Tree tree = client.GetTreeView(id);
client.Close();
liste = tree.listObjects;
}
var recursiveObjects = FillRecursive(liste);
string myjsonmodel = new JavaScriptSerializer().Serialize(recursiveObjects);
return myjsonmodel;
}
private static List<RecursiveObject> FillRecursive(Object[] flatObjects)
{
List<RecursiveObject> recursiveObjects = new List<RecursiveObject>();
for (int i = 0; (i < flatObjects.Length && flatObjects.ElementAt(i) != null); i++)
{
recursiveObjects.Add(new RecursiveObject()
{
data = flatObjects.ElementAt(i).Name,
id = flatObjects.ElementAt(i).Handle,
attr = new FlatTreeAttribute { id = flatObjects.ElementAt(i).Handle, selected = false },
children = null,
state = "closed"
});
}
return recursiveObjects;
}
Now I want to send the text and Id of nodes selected to my controller.
<script type="text/javascript">
var divId = [];
var divText = [];
$('#idjstree').value=function GetIDs() {
divId = [];
divText = [];
$("#onflycheckboxes").jstree("get_checked", null, true).each
(function () {
divId.push(this.id);
divText.push($(this).children('a').text());
});
return (divId);
}</script
and this is in the view
#:<div id="onflycheckboxes"></div>
#:<input type="hidden" id="idjstree" name="idjstree" value="" />
but always I get idjstree="" when I do a breakpoint on the post of create.But the function GetIDs() is correct.
What can I do please?
I am using .NET Web API and of course returning classes that are serialized to JSON. Up Until now I have not had to use the Data Contract attribute for any classes, but for this class below I do and I have no idea why. Intellitrace just says the class is unable to be serialized and to try adding a DataContract Attribute. I will but want to know why.
public class Card : BaseGridVM
{
private IEnumerable<Pc> _pcCards;
private IEnumerable<Pt> _ptCards;
private IEnumerable<MembershipCard> _membershipCards;
public Grid.Result Pt
{
get { return GetPtCardGrid(); }
}
public Grid.Result Pc
{
get { return GetPcCardGrid(); }
}
public Grid.Result Membership
{
get { return GetMembershipCardGrid(); }
}
public Card(IEnumerable<Pc> pcCards, IEnumerable<Pt> ptCards, IEnumerable<MembershipCard> membershipCards)
{
_pcCards = pcCards;
_ptCards = ptCards;
_membershipCards = membershipCards;
}
private Grid.Result GetPtCardGrid()
{
var headers = new List<Grid.Header>
{
new Grid.Header() {label = "Card Name", width = 250},
new Grid.Header() {label = "Pts", width = 50},
new Grid.Header() {label = "Activation Date", width = 50}
};
var rows = new List<Grid.Row>();
foreach (var card in _ptCards)
{
var row = new Grid.Row
{
id = card.id,
enabled = card.active.HasValue && (bool)card.active,
cell = new string[3]
};
row.cell[0] = card.cardName;
row.cell[1] = card.pts.HasValue ? card.pts.ToString() : "0";
row.cell[2] = card.activationDate.HasValue ? card.activationDate.ToString() : "-";
rows.Add(row);
}
return buildGrid(rows, headers, 1, 3);
}
private Grid.Result GetPcCardGrid()
{
var headers = new List<Grid.Header>
{
new Grid.Header() {label = "Offer Title", width = 200},
new Grid.Header() {label = "Pces Required", width = 70},
new Grid.Header() {label = "Activation Date", width = 50}
};
var rows = new List<Grid.Row>();
foreach (var card in _pcCards)
{
var row = new Grid.Row
{
id = card.id,
enabled = card.active.HasValue && (bool)card.active,
cell = new string[3]
};
row.cell[0] = card.cardName;
row.cell[1] = card.pces.HasValue ? card.pces.ToString() : "0";
row.cell[2] = card.creationDate.HasValue ? card.creationDate.ToString() : "-";
rows.Add(row);
}
return buildGrid(rows, headers, 1, 3);
}
private Grid.Result GetMembershipCardGrid()
{
var headers = new List<Grid.Header>
{
new Grid.Header() {label = "Card Name", width = 200},
new Grid.Header() {label = "Members", width = 70}
};
var rows = new List<Grid.Row>();
foreach (var card in _membershipCards)
{
var row = new Grid.Row
{
id = card.id,
enabled = card.active.HasValue && (bool)card.active,
cell = new string[2]
};
row.cell[0] = card.cardName;
row.cell[1] = card.membersCount.HasValue ? card.membersCount.ToString() : "0";
rows.Add(row);
}
return buildGrid(rows, headers, 1, 3);
}
}
This is Base GridVM
public abstract class BaseGridVM
{
protected static Grid.Result buildGrid(IEnumerable<Grid.Row> rows, IEnumerable<Grid.Header> headers, int page, int steps)
{
var row_array = rows.ToArray();
var result = new Grid.Result
{
rows = row_array,
page = page,
records = row_array.Count(),
steps = steps,
headers = headers.ToArray()
};
return result;
}
}
And this is another Class where a Data Contract is not requested
public class DashboardVM : IDashboardVM
{
public IResults_Dashboard results { get; private set; }
public Grid.Result topCompaniesGrid
{
get { return BuildTopCompanies(); }
}
public Grid.Result topAdsGrid
{
get { return BuildTopAds(); }
}
public DashboardVM(IResults_Dashboard results)
{
this.results = results;
}
private static Grid.Result buildGrid(IEnumerable<Grid.Row> rows, IEnumerable<Grid.Header> headers, int page, int steps)
{
var row_array = rows.ToArray();
var result = new Grid.Result
{
rows = row_array,
page = page,
records = row_array.Count(),
steps = steps,
headers = headers.ToArray()
};
return result;
}
private Grid.Result BuildTopCompanies()
{
var headers = new List<Grid.Header>
{
new Grid.Header() {label = "Company Name", width = 150, click = true},
new Grid.Header() {label = "Coupon Views", width = 50, click = true},
new Grid.Header() {label = "Coupon Clicks", width = 50},
new Grid.Header() {label = "Coupon Redemptions", width = 50},
new Grid.Header() {label = "Ad Views", width = 50, click = true},
new Grid.Header() {label = "Ad Clicks", width = 50},
new Grid.Header() {label = "Reward Cards", width = 50},
new Grid.Header() {label = "Fees", width = 50}
};
var rows = new List<Grid.Row>();
foreach (var company in results.companies)
{
var row = new Grid.Row {id = Convert.ToInt32(company.companyId), cell = new string[8]};
row.cell[0] = company.companyName;
row.cell[1] = company.couponViews.ToString();
row.cell[2] = company.couponClicks.ToString();
row.cell[3] = company.couponRedemptions.ToString();
row.cell[4] = company.adViews.ToString();
row.cell[5] = company.adClicks.ToString();
row.cell[6] = company.rewardCards.ToString();
row.cell[7] = company.revenue.ToString();
rows.Add(row);
}
return buildGrid(rows, headers, 1, 3);
}
private Grid.Result BuildTopAds()
{
var headers = new List<Grid.Header>
{
new Grid.Header() {label = "Company Name", width = 150, click = true},
new Grid.Header() {label = "Ad Name", width = 150, click = true},
new Grid.Header() {label = "Views", width = 50},
new Grid.Header() {label = "Clicks", width = 50},
new Grid.Header() {label = "Fees", width = 50}
};
var rows = new List<Grid.Row>();
foreach (var ad in results.ads)
{
var row = new Grid.Row {id = Convert.ToInt32(ad.Id), cell = new string[5]};
row.cell[0] = ad.companyName;
row.cell[1] = ad.name;
row.cell[2] = ad.views.ToString();
row.cell[3] = ad.clicks.ToString();
row.cell[4] = ad.fees.ToString();
rows.Add(row);
}
return buildGrid(rows, headers, 1, 3);
}
}
I solved this problem without the Data Contract by adding a parameterless constructor and adding set methods to the properties.
What I gathered from this is that the serializer creates a new object using the parameterless constructor and then copies the public values over. I say this because when I did not add the set methods to the properties it gave me an empty object. Once I added the set methods the values were returned within the object.
I think it could be a little more sophisticated. I don't know why it creates another object vs using the one I gave, but that's another topic!