Creating JSON object from Ienumerable using LINQ - c#

I am trying to use LINQ to JSON to create a JSON object using the http://james.newtonking.com/json (JSON.NET) framework.
Basically I am trying to create a certain structure from the IEnumerable output. Have something like Products-> Actual,forecast,Target.
The LINQ to XML statement works fine and I can see the result. Is it due to deferred execution and lazy evaluation in LINQ to XML? If yes, how do I solve it.
This is what my LINQ to XML method looks like
IEnumerable resultSet = (xmlDoc.Root.Descendants(ns + "Row").Select(result => new
{
MonthYearShortName = (DateTime)result.Element(ns + "Column0"),
Product = (String)result.Element(ns + "Column1"),
Actual = (decimal)result.Element(ns + "Column2"),
Forecast = (decimal)result.Element(ns+"Column3"),
Target = (decimal)result.Element(ns + "Column4"),
}));
And this is my LINQ to JSON. The example I am using comes from http://james.newtonking.com/json/help/index.html?topic=html/CreatingLINQtoJSON.htm
JObject rss =
resultSet.Select(p => new JObject(p.Product,
new JProperty("MonthYearShortName", p.MonthYearShortName),
new JProperty("Actual", p.Actual),
new JProperty("Forecast", p.Forecast),
new JProperty("Target", p.Target)));
Console.WriteLine(rss.ToString());
When I execute the LINQ to JSON statements I get the below error message
Error 5 'System.Collections.IEnumerable' does not contain a definition for 'Select' and no extension method 'Select' accepting a first argument of type 'System.Collections.IEnumerable' could be found
My usings
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using Extensions = System.Xml.Linq.Extensions;
Not really sure why I am unable to do a select in the second LINQ to JSON statement.
Any help would be great.
Thanks!

The Select extension method is defined on the generic IEnumerable<T> interface (not the non-generic IEnumerable).
For the code to compile, you will need to first call Cast<>()
JObject rss =
resultSet.Cast<XElement>().Select(p => new JObject(p.Product,
new JProperty("MonthYearShortName", p.MonthYearShortName),
new JProperty("Actual", p.Actual),
new JProperty("Forecast", p.Forecast),
new JProperty("Target", p.Target)));
Console.WriteLine(rss.ToString());
(or convert to a generic IEnumerable<resultSet> in some other way)

This code should work if you are trying to get the JSON string:
var resultSet = (xmlDoc.Root.Descendants("Row").Select(result => new
{
MonthYearShortName = (DateTime)result.Element(ns + "Column0"),
Product = (String)result.Element("Column1"),
Actual = (decimal)result.Element("Column2"),
Forecast = (decimal)result.Element("Column3"),
Target = (decimal)result.Element("Column4"),
}));
var json = JsonConvert.SerializeObject(resultSet);
Console.WriteLine(json);

Related

AutoMapper - Using ProjectTo method

I am using AutoMapper in my code and I wanna use ProjectTo for the mappings like this:
var queryable = await _unitOfWork.ProductRepository
.GetList(query);
return new Paging<ProductListDto>
{
Data = queryable.Data.ProjectTo<ProductListDto>(_mapper.ConfigurationProvider).ToList()
};
but I got the following error while using ProjectTo:
ProjectTo method only supports IQueryable but not IEnumerable.
You should use the basic _mapper.Map<T>(/* source */).
return new Paging<ProductListDto>
{
Data = _mapper.Map<List<ProductListDto>>(queryable.Data)
};

ASP.NET Core MVC + Entity Framework + GET + Array

I'm doing some tests to take a project. I have been working with ASP.NET Core MVC and Entity Framework relatively recently. I have a simple database in SQL Server to prove how it is:
In the test project I have a controller TestController; the code is this:
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using WEBAPPHTTP.Models;
namespace WEBAPPHTTP.Controllers
{
[Route ("api/controller[]")]
public class TestController: Controller
{
[HttpGet("/api/values")]
public IEnumerable<string> Get()
{
using (TareasContext db = new TareasContext())
{
var listar = db.Tareas;
var n = listar.Count();
string[] array = new string[n+1];
int i = 0;
foreach (var otareas in listar)
{
array[i] = otareas.Tarea.ToString();
i = i++;
}
return array;
}
}
}
}
Obviously I'm doing something wrong but the output is this:
in localhost/api/values:
["ahora",null,null,null,null]
It only shows me the last record of the database followed by a few NULL, this test the idea is that all the results are loaded in the array.
I'm sure it's a very early mistake, I hope you can guide me.
I dont know what you want to do after this, but if you just want to list out your items, you should be able to do something like this:
using (TareasContext db = new TareasContext())
{
return db.Tareas.ToList();
}
That will give you the full list with all items in it with all properties, if you want just a part of your properties I would suggest to do a .Select as well.
Remember to do a where as well so you dont always return the full list (if it gets enourmus big)
Peace!
You code is not efficient. This is the much cleaner version that does the same:
using (TareasContext db = new TareasContext())
{
var result = db.Tareas.Select(x => x.Tarea).ToList();
return result;
}
As I see the Tarea column is of varchar or nvarchar type. So, you don't need to cast it to string.

convert dynamic object to C# object

I’m looking to take a dynamic object from a third party API & convert to my C# object with minimal code.
Sort of like what Dapper does with a SQL statement results to a C# object. Is there a library that would do this?
I can do it manually like below, but it seems like alot of code to write everytime I want to retrieve from this API.
public IEnumerable<Requirement> Get()
{
dynamic requirementsSelect;
requirementsSelect = _RequirementsRepository.GetRequirements();
IList<Requirement> Requirements = new List<Requirement>();
foreach (var req in requirementsSelect)
{
Requirement requirement = new Requirement();
requirement.Text = req.Text;
requirement.Number = req.Number;
Requirements.Add(requirement);
foreach (var node in req.Phrases)
{
Requirement reqNode = new Requirement();
reqNode.Text = node.Text;
reqNode.Number = node.Number;
requirement.Nodes.Add(reqNode);
}
return Requirements;
}
Thanks
I ended up returning the third party as JSON as follows. In my specific case the JSON wasn't showing the properties. I resolved by changing the dynamic object to IEnumerable and I was then able to specify which properties I wanted to retrieve using .Select.
IEnumerable<dynamic> requirements = _RequirementsRepository.GetRequirements();
return JsonConvert.SerializeObject(new
{
Requirement = requirements.Select(x => x.Text),
Number = requirements.Select(x => x.Number),
});
Thanks!

Cannot convert lambda expression to type 'System.Collections.IDictionary' because it is not a delegate type

I have the following code:
using System.Data;
using System.Linq;
using System.Data.Entity;
....
client.ContactService.AddWithDupCheck(setter =>
{
setter.Set(c => c.FirstName, fKvp.Value);
setter.Set(c => c.LastName, lKvp.Value);
setter.Set(c => c.Email, eKvp.Value);
}, "Email");
However I get the error indication on the first 'setter' after the opening bracket:
Cannot convert lambda expression to type
'System.Collections.IDictionary' because it is not a delegate type.
The AddWithDupCheck method accepts a first argument that can be either
Action<IFieldSetter<Contact>>
or
IDictionary
It thinks I'm trying to pass an IDictionary, so what do I need to do to fix the error?
I didn't solve the specific issue (I'm trying to add a subscriber to the Infusionsoft system), however I got it working by using this:
XmlRpcStruct subscriberData = new XmlRpcStruct();
subscriberData.Add("FirstName", fKvp.Value);
subscriberData.Add("LastName", lKvp.Value);
subscriberData.Add("Email", eKvp.Value);
// add or update (update if subscriber Email matches existing record)
client.ContactService.AddWithDupCheck(subscriberData, "Email");

converting list to json format - quick and easy way

Let's say I have an object MyObject that looks like this:
public class MyObject
{
int ObjectID {get;set;}
string ObjectString {get;set;}
}
I have a list of MyObject and I'm looking to convert it in a json string with a stringbuilder. I know how to create a JavascriptConverter and create a json string by passing a list and having the converter build the string but in this particular case I'm looking to avoid the overhead and go straight to a json string with a foreach loop on the list like this:
StringBuilder JsonString = new StringBuilder();
foreach(MyObject TheObject in ListOfMyObject)
{
}
I've tried to use this method by appending with commas and quotes but it hasn't worked out (yet).
Thanks for your suggestions.
I've done something like before using the JavaScript serialization class:
using System.Web.Script.Serialization;
And:
JavaScriptSerializer jss = new JavaScriptSerializer();
string output = jss.Serialize(ListOfMyObject);
Response.Write(output);
Response.Flush();
Response.End();
3 years of experience later, I've come back to this question and would suggest to write it like this:
string output = new JavaScriptSerializer().Serialize(ListOfMyObject);
One line of code.
For me, it worked to use Newtonsoft.Json:
using Newtonsoft.Json;
// ...
var output = JsonConvert.SerializeObject(ListOfMyObject);
I would avoid rolling your own and use either:
System.Web.Script.JavascriptSerializer
or
JSON.net
Both will do an excellent job :)
why reinvent the wheel? use microsoft's json serialize or a 3rd party library such as json.NET
I prefer using linq-to-json feature of JSON.NET framework. Here's how you can serialize a list of your objects to json.
List<MyObject> list = new List<MyObject>();
Func<MyObject, JObject> objToJson =
o => new JObject(
new JProperty("ObjectId", o.ObjectId),
new JProperty("ObjectString", o.ObjectString));
string result = new JObject(new JArray(list.Select(objToJson))).ToString();
You fully control what will be in the result json string and you clearly see it just looking at the code. Surely, you can get rid of Func<T1, T2> declaration and specify this code directly in the new JArray() invocation but with this code extracted to Func<> it looks much more clearer what is going on and how you actually transform your object to json. You can even store your Func<> outside this method in some sort of setup method (i.e. in constructor).
You could return the value using
return JsonConvert.SerializeObject(objName);
And send it to the front end
If you are using WebApi, HttpResponseMessage is a more elegant way to do it
public HttpResponseMessage Get()
{
return Request.CreateResponse(HttpStatusCode.OK, ListOfMyObject);
}

Categories

Resources