Create Json in Asp.Net Mvc? - asp.net-mvc

I want to create like this:
[
['date', 'T1', 'T2', 'T3'],
['2000', 1, 1, 0.5],
['2001', 2, 0.5, 1],
['2002', 4, 1, 0.5],
['2003', 8, 0.5, 1],
['2004', 7, 1, 0.5]
]
from my model
public partial class AylikOkumaIstatistik
{
public string sno { get; set; }
public string date{ get; set; }
public Nullable<decimal> TotalUsageValue { get; set; }
public string UsageType { get; set; } // T1,T2,T3
}
This is possible with using json? If it is possible, is there any code example or tutorial about this topic.How can I convert data that is from database to json?
Thanks.

This is possible with using json?
Of course, you could use the object[] type as view model (where each element is itself an object[]):
public ActionResult Index()
{
object[] model = new[]
{
new object[] { "date", "T1", "T2", "T3" },
new object[] { "2000", 1, 1, 0.5 },
new object[] { "2001", 2, 0.5, 1 },
new object[] { "2002", 4, 1, 0.5 },
new object[] { "2003", 8, 0.5, 1 },
new object[] { "2004", 7, 1, 0.5 },
};
return Json(model, JsonRequestBehavior.AllowGet);
}
As far as converting the data that is in your database to this view model is concerned, well, you will have to give an example of how is your data represented in the database. Ideally provide a hardcoded example of how your model will look like. But it will be a simple matter of projecting your domain model to an object[].

If you can use Mvc 4? you can add WebApi controller to manage json requests. You will need just to return your entity in WepApi controller method and it will be automatically converted into json object and vice versa. It will work even if you have json objects in post requests body, they will also map to you .net entities and come into controller method as incoming params. If you need i can give any examples you need.

Related

How to create dynamic menu using tree

I have an Angular project but this is not directly related to Angular and I just need the logic of create dynamic menu using tree that can also be similar as in ASP.NET MVC project. So, your suggestion for ASP.NET MVC, etc. will also be helpfu for me.
I use PrimeNG Tree and want to obtain menu from a table in MSSQL database:
Menu Table (the data was changed for example usage):
Id | Order | ParentId | Name |
1 1 0 Documents
2 1 1 Work
3 1 2 Expenses.doc
4 2 2 Resume.doc
5 2 1 Home
6 1 5 Invoices.txt
...
In order to populate the menu items, I need to generate a JSON string as shown below:
{
"data":
[
{
"label": "Documents",
"data": "Documents Folder",
"expandedIcon": "fa-folder-open",
"collapsedIcon": "fa-folder",
"children": [{
"label": "Work",
"data": "Work Folder",
"expandedIcon": "fa-folder-open",
"collapsedIcon": "fa-folder",
"children": [{"label": "Expenses.doc", "icon": "fa-file-word-o", "data": "Expenses Document"}, {"label": "Resume.doc", "icon": "fa-file-word-o", "data": "Resume Document"}]
},
{
"label": "Home",
"data": "Home Folder",
"expandedIcon": "fa-folder-open",
"collapsedIcon": "fa-folder",
"children": [{"label": "Invoices.txt", "icon": "fa-file-word-o", "data": "Invoices for this month"}]
}]
},
... //omitted for brevity
]
}
So, I have really no idea about the logic and database table design (menus). Should I generate the JSON above on the Controller or another place? Could you please post suggestions and sample approaches regarding to this issue?
Your database Menu table is fine to generate the treeview using the PrimeNG Tree plugin except that you may want to include an additional property for the data property if you want. I would however suggest you make the ParentId property nullable so that your top level item (Documents) has a null value rather that 0.
In order to pass json in that format, your model need to be
public class MenuVM
{
public int Id { get; set; } // this is only used for grouping
public string label { get; set; }
public string expandedIcon { get; set; }
public string collapsedIcon { get; set; }
public string icon { get; set; }
public IEnumerable<MenuVM> children { get; set; }
}
You might also include other properties such as
public string data { get; set; }
to match the properties in the api
You also need a parent model for the data property
public class TreeVM
{
public IEnumerable<MenuVM> data { get; set; }
}
To generate the model, you controller code would be (note this is based on the ParentId field being null for the top level item as noted above)
// Sort and group the menu items
var groups = db.Menus
.OrderBy(x => x.ParentId).ThenBy(x => x.Order)
.ToLookup(x => x.ParentId, x => new MenuVM
{
Id = x.Id,
label = x.Name
});
// Assign children
foreach (var item in groups.SelectMany(x => x))
{
item.children = groups[item.Id].ToList();
if (item.children.Any())
{
.... // apply some logic if there a child items, for example setting
// the expandedIcon and collapsedIcon properties
}
else
{
.... // apply some logic if there are no child items, for example setting
// the icon properties - e.g. item.icon = "fa-file-word-o";
}
}
// Initialize model to be passed to the view
TreeVM model = new TreeVM
{
data = groups[null].ToList();
}
return Json(model, JsonRequestBehavior.AllowGet);
For your icons, you should consider some const values or an enum rather than hard-coding strings.

Json.Net custom serialization

[
{
"articles": [
[
"2016-03-04",
6
],
[
"2016-03-05",
10
],
[
"2016-03-06",
11
]
],
"accession": "00000446-201301000-00018"
},
{
"articles": [
[
"2016-03-04",
1
],
[
"2016-03-08",
17
],
[
"2016-03-09",
10
]
],
"accession": "00000446-201301000-00019"
}]
List is input { "Accession"= "00000446-201301000-00018", "Date"= "635926464000000000","Rank" =2},{ "Accession" = "00000446-201301000-00019", "Date" = "635931648000000000","Rank" = 2}
I want json data exactly like this,data is coming from list and list is dynamically growing.Form list, I want all dates and rank club to gether for the same accession number.
I want to use newtonsoft json custom serlization to convert my list to json.
What you want to do does not need any Custom Formatter, you just have to re-structure your data, Here is an example for restructuring a list based on Entity class to the new required one.
class Entity
{
public string Accession { get; set; }
public string Date { get; set; }
public int Rank { get; set; }
}
Add this line if you need to read the list from Json
var list = JsonConvert.DeserializeObject<List<Entity>>(input);
Here is the code for changing the structure of data to array based articles.
var translatedAsArray = list.GroupBy(e => e.Accession)
.Select(g =>
new {
//change new 'object[]' to 'new' to make the article an object
//you can convert i.Date, i.Rank and g.Key to anything you want here
Articles = g.Select(i => new object[] { i.Date , i.Rank }),
Accessing = g.Key
}
);
var json = JsonConvert.SerializeObject(translatedAsArray, Formatting.Indented);
Model
public class FinalList
{
public string accession {get;set;}
public List<ArticlesDetails> Articles{get;set;}
}
public class ArticlesDetails
{
public DateTime Date{get;set;}
public int number{get;set;}
}
Use ObjectContent instead of StringContent so we let the formatter (i.e. JsonMediaTypeFormatter) to deal with the serialization and deserialization
In config
config.Formatters.Insert(0, new YourCustomFormatter());
config.Formatters.Insert(1, new JsonMediaTypeFormatter());
and disable post in your custom formatter so that JsonMediaTypeFormatter desrializes the complex data

ASP MVC 4 Web Api wraps my json result

My WebApi action returns a dynamic object built from JObject.parse(jsonString);
I have GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
But that object is wrapped inside a default result message in the response.
According to this article returning anonymous objects is fine and should give the expected result
I am using an async controller because I have to await some ReadAsStringAsync() here the protoype of my action:
public async Task<dynamic> Pics(string flavor, int pagesize)
Expected result :
{"flavor":"","maxFeedSize":0,"mediaContent":[]}
Result I have when returning the dynamic object:
{
"Result": {
"flavor": "",
"maxFeedSize": 0,
"mediaContent": []
},
"Id": 1,
"Exception": null,
"Status": 5,
"IsCanceled": false,
"IsCompleted": true,
"CreationOptions": 0,
"AsyncState": null,
"IsFaulted": false
}
As I thought and as mentioned in comments. I was returning a Task<Task<dynamic>> because of a naive method overload.
public async Task<dynamic> Pics(string flavor, string pagesize)
{
return Pics(flavor, pagesize, null);
}
Edit:
I tried this because unlike MVC routes ommit a string parameter throws an error even if string is nullable
public async Task<dynamic> Pics(string flavor, string pagesize, string startid =null)
works fine :)

MVC 3 - jquery data key value pair $.ajax with JSON results in 500 internal error - how do I do this?

Edit: I've got the solution and have described it a bit more at the end of the post
Using: MVC 3, C#
Problem: A key/value obj array sent to controller via $.post/$.ajax results in a 500 internal server error at the controller (because the value passed to the method in the C# controller is null)
I have an array that's in the format:
{
"q_1": {
"qid": "1",
"tmr": 0
},
"q_2": {
"qid": "2",
"tmr": 0
}
}
I get this via $("#myid").data() - and this is all fine.
I need to send this to my controller, and tried both post and $.ajax
var d = $("#q_data").data();
$.post("/run/submit", d, function(data) { alert(data);}, "application/json");
and
$.ajax({
url: '/run/submit',
data: d,
contentType: 'application/json',
dataType: 'json',
success: function (data) { alert(data); }
});
The method on the C# side is
public ActionResult Submit(List<PerfObj> dict)
{
int x = dict.Count;
return PartialView("_DummyPartial");
}
Where PerfObj is my model
public class PerfObj
{
public string id { get; set; }
Perfvar perfVar;
}
public class PerfVar
{
public string qid { get; set; }
/* note I've tried both int and string for the tmr param */
public string tmr { get; set; }
}
When I execute this, the call goes to the controller correctly - i.e. it hits the submit method. However, the method parameter dict, in
List<PerfObj> dict
is null.
Why? It seems to be something with my model, can't figure out how else to design it so it extracts the values correctly to the method parameter.
When I print the JSON.Stringify on the console, it shows the key/value pair correctly so I'm thinking it's going correctly to the server but the server/MVC3 doesn't like it for some reason or can't map it to the List of PerfObjs.
EDIT: Solution
Maciej's answer to my post was how I solved it. What I did eventually was to create a arrays of perfObj at the client side
$("#q_data").data(e,{key: e, perfVar: { qid: e, tmr: 0 }})
(ps - ignore redundant usage of 'e', I've got other plans, this is a dummy case)
And then I mapped it to a JSON friendly array
var arr = [];
$.each($('#q_data').data(), function (i, e) {
var p = $(this).data(i);
var obj = { key: i, perfVar: { id: e.perfVar.qid, tmr: e.perfVar.tmr}};
arr.push(obj);
});
Then stringified it
var q = JSON.stringify(arr);
$.ajax'd it as described in Maciej's post.
I redefined my classes properly
public class PerfObj
{
public string key { get; set; }
public PerfVar perfVar { get; set; }
}
public class PerfVar
{
public string id { get; set; }
public int tmr { get; set; }
}
and changed the signature of my controller method
[HttpPost]
public ActionResult Submit(PerfObj[] dict)
{
return PartialView("_DummyPartial");
}
This now works perfectly and I can extend my classes fairly easily to do what I want.
Thank you all!
There are 3 things wrong with your code:
A. The property PerfVar must be made public and there must be a get and set on it:
public class PerfObj
{
public string id { get; set; }
public Perfvar perfVar { get; set; }
}
B. Your JSON representation of the list is incorrect. It should be:
var e = [
{ "id": "foo", "perfVar": { "qid": "a", "tmr": "b"}},
{ "id": "foo", "perfVar": { "qid": "a", "tmr": "b"}}
];
C. You have to stringify the array and specify type: 'POST' to pass it to your MVC controller via ajax:
$.ajax({
url: '/run/submit',
data: JSON.stringify(e),
contentType: 'application/json, charset=utf-8',
dataType: 'json',
type: 'POST',
success: function (data) { alert(data); }
});
You can't directly map a key/value pair to a flat sequence. MVC has no idea how to do that.
You either need a custom model binder, or a better/easier option would be to change how you create the JSON on the client-side, so it actually matches up to your model.
Something like this:
var perfObjs =
{
{ id: 1, perfVar: { qId: 1, tmr: 0 }},
{ id: 2, perfVar: { qId: 2, tmr: 0 }},
}
$.post("/run/submit", perfObjs, function(data) { alert(data);}, "application/json");
Because the controller does not recognize the json value as List.
Why not just pass the raw string to your controller and let your controller convert the json string to object? that will be much more easier.

How to return JSON in specific format in ASP.NET MVC using Json() with no property names

I am using a charting javascript library that expects its data in a specific JSON format - without property names.
I have an object in my Model that I am using to return the data to the charts. This looks as follows:
public class ChartData
{
public string Key { get; set; }
public int Value { get; set; }
}
An action looks as follows:
public ActionResult AssetsPerFloor(Guid id)
{
var results = from a in surveyRepository.GetAssetsForBuidling(id)
group a by a.Room.Floor into g
select new ChartData{ Key = g.Key.ToString(), Value = g.Count() };
return Json(results);
}
This returns JSON in the format [{"Key":"Main Building","Value":1}]
However, the chart requires no property names, eg: [[5, 2], [6, 3], [8, 2]]
Is there anyway I can return the results in this format. I'm sure there's a simple trick to it, but I cant think of it.
As far as I understand, it needs to return a multi-dimensional array. Try this :
var results =
(from a in surveyRepository.GetAssetsForBuidling(id)
group a by a.Room.Floor into g
select new ChartData{ Key = g.Key.ToString(), Value = g.Count() })
.Select(x => new string[] { x.Key, x.Value.ToString() };
return Json(results);

Resources