Asp.Net Controller action returning unexpected JSON data - asp.net

I'm looking into some old code and I am seeing something I cannot figure out. The code is a controller action that returns a dynamic object:
return new
{
Result = true,
Count = data.Count(),
Students = data.Select(s => string.Format("{0}, {1}", s.LastName, s.FirstName))
};
However, the resulting JSON in the browser is not coming back as I would expect:
{
"$id":"1",
"Result":true,
"Count":1,
"Students":
{
"$id":"2",
"$values":["USER, ACTIVE"]
}
}
What I would expect, and what I normally get any other time I do this sort of thing, is more like this:
{
"Result":true,
"Count":1,
"Students":
{
["USER, ACTIVE"]
}
}
I have no idea where the $id and $values properties are coming from. I haven't seen this happen before with .Net, so I'm not sure what is causing this. It's not the dynamic object return that's causing the problem because I switched it to a named type just to test it out and it still does the same thing.

You need add this line of code to Global.asax to avoid append $id
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.PreserveReferencesHandling
= Newtonsoft.Json.PreserveReferencesHandling.None;

You need to have a .ToList() at the end of the students.
{
Result = true,
Count = data.Count(),
Students = data.Select(s => string.Format("{0}, {1}", s.LastName, s.FirstName)).ToList()
};

Related

Suitescript 2.0 - log.debug repeating value lines

I'm working on a client script, but when I do a simple getValue() on the customer field and log.debug, I get repeating output lines and I'm not sure why. Is this normal?
Output
This my fieldChanged code:
function fieldChanged(context) {
var newRec = context.currentRecord;
if(newRec.fieldId = 'entity') {
var custId = newRec.getValue ({
fieldId: 'entity'
});
log.debug({
title: 'id: ' + custId
});
}
}
Change the line below:
if(newRec.fieldId = 'entity')
To something like
if(context.fieldId === 'entity')
You're getting repeating output lines because whenever a field is changed, you're not doing a check on the current fieldId in the context object instead checking the context.currentRecord.fieldId which I'm not sure what evaluates to.
Check this out for more info: fieldChanged(scriptContext)

Trouble with LINQ Returning Results Set from Object[] Array Within Object

Consider the following code:
var articlesDisplay = from product in db.ProductSearchData
select product.articles;
articlesDisplay = articlesDisplay.Where(a => a[].body.Contains(searchString));
I'm trying to load a results set, but get a compiler error using the array notation in the Where clause. How should I be going about this?
The desired end result is a var articlesDisplay object that can be used in ASP.NET MVC pagination.
Thanks to any/all for your assistance!
remove the array notation
var articlesDisplay = from product in db.ProductSearchData
select product.articles;
articlesDisplay = articlesDisplay.Where(a => a.body.Contains(searchString));
A lambda expression is just like a function declaration, but instead of method name(paramters){body } it takes the form of parameters => body. So this:
a => a[].body.Contains(searchString)
Is the same as this:
bool Method(Article article)
{
return article[].body.Contains(searchString);
}
That is obviously not valid, since it won't compile. You need a Func<T,bool>, or a function that accepts a single element and returns true or false depending on whether it is to be included. So you probably want this:
bool Method(Article article)
{
return article.body.Contains(searchString);
}
Which translates to this:
a => a.body.Contains(searchString).

How do I determine, if Observable has never received anything?

How do I determine, if the Observable is "empty"?
Better, that it has never received anything.
My code looks like this:
spots: Observable<Spot[]>;
And I've tried several things I found on Google like:
spots.isEmpty();
spots.length;
spots.length();
spots().length;
spots.first();
But none of them works like I want..
I need this functionality, to fill a list in Ionic2 with No items found until the first item is loaded.
This is how I solve it in my code:
if ( arrayOfItems && arrayOfItems.length > 0 ) {
// display the list
return arrayOfItems.map((item) => { return item; })
} else {
// show a message that nothing was found
return "Nothing to see here...";
}
This will check that the variable has some sort of positive value (ie. it is not null, false or undefined) and that the array has at least one value. If that is not the case then display a message that nothing was found.
I solved it like this:
I have an variable let isEmpty=true; and set it to false when I receive the first Object in the Observable:
spots.subscribe(() => {
this.empty = false;
...
});

KendoUI Grid serverpaging

I'm trying to populate a KendoUI grid with JSON data where the server returns the total number of rows along with the data, but I'm having some trouble getting serverPaging to work properly. I create and assign the dataSource of the grid as follows:
var oDS = new kendo.data.DataSource({
schema: {
data: "data",
total: "total"
},
data: self.grdTableData,
serverPaging: true,
pageSise: 50,
total: joOutput["TotalRecords"]
});
grdTableResults.setDataSource(oDS);
and the first page shows the first 50 of 939 records but there is only ever 1 page (the navigation arrows never respond to anything) and I see NaN - NaN of 939 items and the rotating circle of dots in the centre of the grid that never goes away.
One thing that is different in all the examples I've looked at is that my $.ajax call and the the processing of the JSON data in .done doesn't use "transport: read" but I'm thinking how I send the data and get it back shouldn't matter (or does it because every page request is a new server read?). But I don't think I'm doing enough to handle the server paging properly even though it seems I'm setting data source values similar to those set in the example at http://jsfiddle.net/rusev/Lnkug/. Then there's the "take" and "skip" values that I'm not sure about, but I do have "startIndex" and "rowsPerPage" that I'm sending to the server that can be used there. I assume the grid can tell me what page I'm on show I can set my "startIndex" appropriately and if I have an Items per Page" drop down I can reset my "rowsPerPage" value?
Anyway, sorry for all the newbie questions. Any help and suggestions is genuinely appreciated. Thanks!
transport: read
You should be able to use "transport: read" even if you have custom logic by setting the value to a function. I have created a JS Fiddle to demonstrate this functionality.
dataSource: {
serverPaging: true,
schema: {
data: "data",
total: "total"
},
pageSize: 10,
transport: {
read: function(options) {
var data = getData(options.data.page);
options.success(data);
}
},
update: function() {}
}
Your read function contains a parameter that contains the following paging properties: page, pageSize, skip, take. Keep in mind that all transport operations need to be functions if one operation contains a function.
startIndex and rowsPerPage
If your server accepts these parameters, you should be able to submit them in the read function. Create a new ajax call that post customized data
var ajaxPostData = { startIndex: options.data.skip, rowsPerPage: options.data.pageSize }
This is the code for server side wrapper that I'm using to implement server paging with kendo grid:
#(Html.Kendo().Grid<IJRayka.Core.Utility.ViewModels.ProductDto>()
.Name("productList")
.Columns(columns =>
{
columns.Bound(prod => prod.Name);
columns.Bound(ord => ord.Brand);
columns.Bound(ord => ord.UnitPackageOption);
columns.Bound(ord => ord.CategoryName);
columns.Bound(ord => ord.Description);
})
.Pageable(pager => pager.PageSizes(true))
.Selectable(selectable => selectable.Mode(GridSelectionMode.Multiple))
.PrefixUrlParameters(false)
.DataSource(ds => ds.Ajax()
.Model(m => m.Id(ord => ord.ID))
.PageSize(5)
.Read(read => read
.Action("FilterProductsJson", "ProductManagement")
.Data("getFilters"))
)
)
Where getFilters is a javascript function that passes my custom filter parameters to the grid when it wants to get data from url/service:
function getFilters() {
return {
brand: $("#Brand").val(),
name: $("#Name").val(),
category: $("#CategoryName").val()
};
}
In addition you should implement your controller's action method using kendo's DataSourceRequest class like below, or otherwise it won't work the way you want:
public JsonResult FilterProductsJson([DataSourceRequest()] DataSourceRequest request,
// three additional paramerters for my custom filtering
string brand, string name, string category)
{
int top = request.PageSize;
int skip = (request.Page - 1) * top;
if(brand != null)
brand = brand.Trim();
if(name != null)
name = name.Trim();
if(category != null)
category = category.Trim();
var searchResult = new ManageProductBiz().GetPagedFilteredProducts(brand, name, category, top, skip);
// remove cyclic references:
searchResult.Items.ForEach(prd => prd.Category.Products = null);
return Json(new DataSourceResult { Data = searchResult.Items, Total = searchResult.TotalCount }, JsonRequestBehavior.AllowGet);
}

In MVC app using JQGrid - how to set user data in the controller action

How do you set the userdata in the controller action. The way I'm doing it is breaking my grid. I'm trying a simple test with no luck. Here's my code which does not work. Thanks.
var dataJson = new
{
total =
page = 1,
records = 10000,
userdata = "{test1:thefield}",
rows = (from e in equipment
select new
{
id = e.equip_id,
cell = new string[] {
e.type_desc,
e.make_descr,
e.model_descr,
e.equip_year,
e.work_loc,
e.insp_due_dt,
e.registered_by,
e.managed_by
}
}).ToArray()
};
return Json(dataJson);
I don't think you have to convert it to an Array. I've used jqGrid and i just let the Json function serialize the object. I'm not certain that would cause a problem, but it's unnecessary at the very least.
Also, your user data would evaluate to a string (because you are sending it as a string). Try sending it as an anonymous object. ie:
userdata = new { test1 = "thefield" },
You need a value for total and a comma between that and page. (I'm guessing that's a typo. I don't think that would compile as is.)
EDIT:
Also, i would recommend adding the option "jsonReader: { repeatitems: false }" to your javascript. This will allow you to send your collection in the "rows" field without converting it to the "{id: ID, cell: [ data_row_as_array ] }" syntax. You can set the property "key = true" in your colModel to indicate which field is the ID. It makes it a lot simpler to pass data to the grid.

Resources