Return Entity Framework Objects as JSON - c#

I try to return Entity Framework Objects as Json with the following method in my Controller:
public JsonResult EventList() {
var results = from s in db.Events
select new
{
OrderID = s.EventID,
OrderTitle =s.EventType,
OrderDate = s.Title
};
return Json(results);
}
I get a server error 500 when entering the page /events/EventList/. Also a Jquery get request returns no data. What is the correct way to return the results in Json format?
Update:
This seems to work. But I need results from the database.
public ActionResult EventList() {
Event test = new Event
{
EventID = 1,
Title = "test",
Description = "test"
};
return Json(new { event = test }, JsonRequestBehavior.AllowGet);
}

Edit: 2019
This answer still gets upvotes - if you're going down this road I really really suggest you just save yourself the future headaches and use a DTO. Serializing your entity is probably faster for now but (and I have learned this the hard way) - you are going to hate yourself in a years time.
New answer - updated for 2018:
The original answer below will work every time and if you're using lazy loading, it may still be the best solution. Without lazy loading though, you can do the following with Newtonsoft.JSON:
var settings = new JsonSerializerSettings()
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
Error = (sender, args) =>
{
args.ErrorContext.Handled = true;
},
};
using(var context = new myContext())
{
var myEntity = myContext.Foos.First();
return JsonConvert.SerializeObject(myEntity, settings);
}
Which basically will serialize anything that's been included in the entity framework request, while ignoring any errors and reference loops.
The drawback to this method is that controlling what gets serialized is harder and if you're performance conscious, you may need to start decorating your generated Entity Framework classes with a pattern like
// a new partial class extending the Foo generated class, allowing us to apply an interface
[MetadataType(typeof(IFooMetaData))]
public partial class Foo : IFooMetaData
{
}
// meta data interface, forcing json ignore on Foo.Bars
public interface IFooMetaData
{
[JsonIgnore]
ICollection<Bar> Bars {get;set;}
}
Original answer - 2015:
Can get this response:
[
{
"OrderID": 1
},
{
"OrderID": 2
},
{
"OrderID": 3
}
]
from this:
public JsonResult Test()
{
var events = new List<Event>()
{
new Event() {EventId = 1},
new Event() {EventId = 2},
new Event() {EventId = 3}
};
var results = events.Select(e => new
{
OrderID = e.EventId
}).ToList();
return new JsonResult() { Data = results, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}
So yours should be something like
public JsonResult Test()
{
var results = db.Events.Select(e => new
{
OrderID = e.EventId
}).ToList();
return new JsonResult() { Data = results, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}
edit
re-posted with tested code

In the controller:
for example
List<categories> data = context.categories.toList(); //to here all right
now, the problem with the serialization for "data" for send the json result...
i just used a struct to replace the List how???
just watch:
in the same controller ...
struct categories_struct{
public fieldname {get;set;}
//the same for others firelds (same the model)
}
now, in the ActionResult or maybe in jsonresult :
List<categorias> data = contexto.categorias.ToList(); //I use the EF
List<catego> data2 = new List<catego>(); //create the struct var
foreach (categorias item in data) //fill the struct with data
{
catego item2 = new catego();
item2.codcat = item.codcat;
item2.nomcat = item.nombrecat;
item2.descripcion = item.descripcion;
data2.Add(item2);
}
//here, Data contains all data2
return Json(new { Data = data2 }, JsonRequestBehavior.AllowGet);
in the view:
$.ajax({
url: "/Categorias/getTabla",
dataType: "JSON",
type: "POST",
}).done(function (respuesta) {
var data = JSON.parse(JSON.stringify(respuesta));
console.log(respuesta);
alert('exito');
}).fail(function () {
alert('oh no, again!');
});
///
is my solution for this problem

Related

How to return a single DataRow object from Asp Web API?

So I am writing some Asp.Net WebApi code to hook with old C# back-end code where there is no model class used. (Pure dataTable returned from DataAccess, Crazy right? I know)
Following is the code I put on the Server side.
public IHttpActionResult GetProduct(int campaignID, int productID)
{
var so = new SearchOptions(campaignID)
{
ProductID = productID
};
var result = SearchManager.Search(so);
if (result == null || result.Rows.Count == 0)
return NotFound();
return Ok(result.Rows[0]);
}
I am expecting to have the response like this:
{
Field1: "field1",
Field2: "field2",
...
}
But Actually I am having this:
{
"rowError": "",
"rowState": 2,
"table": [
{
Field1 : "field1",
Field2 : "field2",
...
}
],
"itemArray": ["field1","field2"],
"hasErrors": false
}
I don't want all these rowError, rowState...etc
If I am doing this on the server side:
public IHttpActionResult GetProduct(int campaignID, int productID)
{
var so = new SearchOptions(campaignID)
{
ProductID = productID
};
var result = SearchManager.Search(so);
if (result == null || result.Rows.Count == 0)
return NotFound();
return Ok(result);
}
I am receiving this:
[{Field1: "field1", Field2: "field2"..}]
which is unfortunately rejected by ngResource get method since it is an array rather than a single Json Object.
What should I do? If I just want to return a single dataRow as a Json string.
Ideally I want to avoid go down to the path of creating an Response Object as suggested by Manoz. (Thank you for your answer Manoz though)
Thanks
You can convert your DataRow to Dictionary using LINQ:
public IHttpActionResult GetProduct(int campaignID, int productID)
{
var so = new SearchOptions(campaignID)
{
ProductID = productID
};
var result = SearchManager.Search(so);
if (result == null || result.Rows.Count == 0)
return NotFound();
var row = result.Rows[0];
return Ok(row.Table.Columns
.Cast<DataColumn>()
.ToDictionary(c => c.ColumnName, c => row[c]));
}
That action returns JSON as you want: { Field1: "field1", Field2: "field2", ... }
Did you try deserializing it?
Using NewtonSoft.Json
Create a separate class matching your response. I believe response's format will remain same always.
public class Response{
public List<response> table{ get;set; }
}
public class response {
public string Field1 { get;set; }
public string Field2 { get;set; }
}
Now deserializing response using Newtonsoft.Json
var entities = SearchManager.Search(so);
var result= JsonConvert.DeserializeObject<Response>(entities)
var endResult= result.table[0] //will get you result
Help source - https://www.nuget.org/packages/newtonsoft.json/
Since this posted just a few months ago, assume you're using API 2.x. This version handles return format automatically and intelligently, particularly no need to implement explicit CAST. You just need to specify the type you want. For example in AngularJS, this will tell API what you're expecting:
$http({
method: 'GET',
responseType: 'json'
url: ...
}).then(function mySuccess(response){
$scope.theRow = response.data;
})
At server API, just keep your code. During execution, it will auto-return result in JSON format.

Translating a GET with Entity Framework to a GET without Entity Framework

I am following a tutorial online for ASP.NET MVC & Angular, but the author(Sourav Mondal) uses Entity to query the database. Unfortunately, I am using SQL Server 2000, and EF is not an option. The following is the code which I am attempting to transpose:
// GET: /Data/
//For fetch Last Contact
public JsonResult GetLastContact()
{
Contact c = null;
//here MyDatabaseEntities our DBContext
using (MyDatabaseEntities dc = new MyDatabaseEntities())
{
c = dc.Contacts.OrderByDescending(a => a.ContactID).Take(1).FirstOrDefault();
}
return new JsonResult { Data = c, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}
This is my current speculation for an EF-less solution, supposing the Contacts have three fields in the database,ContactID, Name, and Password:
Models/Contact.cs class:
public class Contact
{
public string Name { get; set; }
public string Password { get; set; }
}
Controllers/DataController.cs,GetLastContact():
public class DataController : Controller
{
// GET: /Data/
public JsonResult GetLastContact()
{
Contact c = null;
using (SqlConnection cnxn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["TheConnectionString"].ConnectionString))
{
using (SqlCommand sqlQuery = new SqlCommand("SELECT TOP 1 ContactID FROM Northwind ORDER BY ContactID DESC "))
{
cnxn.Open();
SqlDataReader reader = sqlQuery.ExecuteReader();
while (reader.Read())
{
string contact_ID = (string)reader["ContactID"];
string first_name = (string)reader["Name"];
string password = (string)reader["Password"];
}
// Some magic here
reader.Close();
cnxn.Close();
}
}
return new JsonResult { Data = c, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}
}
And Sourav's Angular code:
angular.module('MyApp') //extending from previously created angular module in the previous part
.controller('Part2Controller', function ($scope, ContactService) { //inject ContactService
$scope.Contact = null;
ContactService.GetLastContact().then(function (d) {
$scope.Contact = d.data; // Success
}, function () {
alert('Failed'); // Failed
});
})
.factory('ContactService', function ($http) { // here I have created a factory which is a populer way to create and configure services
var fac = {};
fac.GetLastContact = function () {
return $http.get('/Data/GetLastContact');
}
return fac;
});
I feel like although my solution is probably spaghetti, it cannot be too far off from working. Any little nudge anyone could give this code would be awesome! Or any constructive advice as to how one should proceed in stripping Entity of its Entity.
// Some magic here
c = new Contact
{
Name = first_name,
Password = password
};
// end of magic
I am not sure that you want what you want.
For me its sounds more like you want to make your own entity for your database (which does not support EF)
So just make some class of the table and get a List of it so thats it.
Little Example:
SomeClass
List allContactsInDatabase;
To Keep your Data updated use polling or just call a refresh every 30 seconds or faster/slower how you need it.
Hope thats helps

How do I populate a view model with static data

I have a Controller that I am using to pass a list of JSON data to my view. Currently I'm using Linq to Entities to populate the Viewmodel now but since it is a static list of only 15 pairs, I want to hard code the Viewmodel but I'm not sure how to do that. Here is my Controller
public JsonResult GetSites()
{
var sites = context.vAaiomsSites.Select(s => new vAaiomsSitesVM
{
ID = s.ID,
SiteName = s.SiteName
}).OrderBy(s => s.SiteName);
return Json(sites, JsonRequestBehavior.AllowGet);
}
I just need an array like this:
SiteID: 1, SiteName : Barter Island
SiteID: 2, SiteName: Cape Lisburne
....12 more times.
Use collection initializer to create an array (or List<T>) of the ViewModels:
public JsonResult GetSites()
{
var sitesArray = new vAaiomsSitesVM[]
{
new vAaiomsSitesVM
{
ID = 1,
SiteName = "Barter Island"
},
new vAaiomsSitesVM
{
ID = 2,
SiteName = "Cape Lisburne"
}
// And so on...
};
var sites = sitesArray.OrderBy(s => s.SiteName);
return Json(sites, JsonRequestBehavior.AllowGet);
}
If you really want to hardcode it, you can do it like this.
Create a class for your ViewModel
public class Site
{
public int SiteID { set;get;}
public string SiteName { set;get;}
}
and in your Action method
public JsonResult GetSites()
{
var list=new List<Site>();
list.Add(new Site{ SiteID=1, SiteName="SiteName 1" } );
list.Add(new Site{ SiteID=2, SiteName="SiteName 2" } );
//13 more times !!!!
return Json(list, JsonRequestBehavior.AllowGet);
}
But Why do you want to HardCode it ? I recommend you to avoid this if at possible.If you are worried about querying your database everytime, you may think about storing the data in a middle Caching Layer and fetch it from there thus avoiding call to database. Think twice.

Returning anonymous types with Web API

When using MVC, returning adhoc Json was easy.
return Json(new { Message = "Hello"});
I'm looking for this functionality with the new Web API.
public HttpResponseMessage<object> Test()
{
return new HttpResponseMessage<object>(new { Message = "Hello" }, HttpStatusCode.OK);
}
This throws an exception as the DataContractJsonSerializer can't handle anonymous types.
I have replaced this with this JsonNetFormatter based on Json.Net.
This works if I use
public object Test()
{
return new { Message = "Hello" };
}
but I don't see the point of using Web API if I'm not returning HttpResponseMessage, I would be better off sticking with vanilla MVC. If I try and use:
public HttpResponseMessage<object> Test()
{
return new HttpResponseMessage<object>(new { Message = "Hello" }, HttpStatusCode.OK);
}
It serializes the whole HttpResponseMessage.
Can anyone guide me to a solution where I can return anonymous types within a HttpResponseMessage?
This doesn't work in the Beta release, but it does in the latest bits (built from http://aspnetwebstack.codeplex.com), so it will likely be the way for RC. You can do
public HttpResponseMessage Get()
{
return this.Request.CreateResponse(
HttpStatusCode.OK,
new { Message = "Hello", Value = 123 });
}
This answer may come bit late but as of today WebApi 2 is already out and now it is easier to do what you want, you would just have to do:
public object Message()
{
return new { Message = "hello" };
}
and along the pipeline, it will be serialized to xml or json according to client's preferences (the Accept header). Hope this helps anyone stumbling upon this question
In web API 2 you can use the new IHttpActionResult which is a replacement for HttpResponseMessage and then return a simple Json object: (Similiar to MVC)
public IHttpActionResult GetJson()
{
return Json(new { Message = "Hello"});
}
you can use JsonObject for this:
dynamic json = new JsonObject();
json.Message = "Hello";
json.Value = 123;
return new HttpResponseMessage<JsonObject>(json);
You could use an ExpandoObject. (add using System.Dynamic;)
[Route("api/message")]
[HttpGet]
public object Message()
{
dynamic expando = new ExpandoObject();
expando.message = "Hello";
expando.message2 = "World";
return expando;
}
You may also try:
var request = new HttpRequestMessage(HttpMethod.Post, "http://leojh.com");
var requestModel = new {User = "User", Password = "Password"};
request.Content = new ObjectContent(typeof(object), requestModel, new JsonMediaTypeFormatter());
In ASP.NET Web API 2.1 you can do it in a simpler way:
public dynamic Get(int id)
{
return new
{
Id = id,
Name = "X"
};
}
You can read more about this on https://www.strathweb.com/2014/02/dynamic-action-return-web-api-2-1/
public IEnumerable<object> GetList()
{
using (var context = new DBContext())
{
return context.SPersonal.Select(m =>
new
{
FirstName= m.FirstName ,
LastName = m.LastName
}).Take(5).ToList();
}
}
}
You should be able to get this to work if you use generics, as it will give you a "type" for your anonymous type. You can then bind the serializer to that.
public HttpResponseMessage<T> MakeResponse(T object, HttpStatusCode code)
{
return new HttpResponseMessage<T>(object, code);
}
If there are no DataContract or DataMebmer attributes on your class, it will fall back on serializing all public properties, which should do exactly what you're looking for.
(I won't have a chance to test this until later today, let me know if something doesn't work.)
You can encapsulate dynamic object in returning object like
public class GenericResponse : BaseResponse
{
public dynamic Data { get; set; }
}
and then in WebAPI; do something like:
[Route("api/MethodReturingDynamicData")]
[HttpPost]
public HttpResponseMessage MethodReturingDynamicData(RequestDTO request)
{
HttpResponseMessage response;
try
{
GenericResponse result = new GenericResponse();
dynamic data = new ExpandoObject();
data.Name = "Subodh";
result.Data = data;// OR assign any dynamic data here;//
response = Request.CreateResponse<dynamic>(HttpStatusCode.OK, result);
}
catch (Exception ex)
{
ApplicationLogger.LogCompleteException(ex, "GetAllListMetadataForApp", "Post");
HttpError myCustomError = new HttpError(ex.Message) { { "IsSuccess", false } };
return Request.CreateErrorResponse(HttpStatusCode.OK, myCustomError);
}
return response;
}

How to create JSON string in C#

I just used the XmlWriter to create some XML to send back in an HTTP response. How would you create a JSON string. I assume you would just use a stringbuilder to build the JSON string and them format your response as JSON?
Using Newtonsoft.Json makes it really easier:
Product product = new Product();
product.Name = "Apple";
product.Expiry = new DateTime(2008, 12, 28);
product.Price = 3.99M;
product.Sizes = new string[] { "Small", "Medium", "Large" };
string json = JsonConvert.SerializeObject(product);
Documentation: Serializing and Deserializing JSON
You could use the JavaScriptSerializer class, check this article to build an useful extension method.
Code from article:
namespace ExtensionMethods
{
public static class JSONHelper
{
public static string ToJSON(this object obj)
{
JavaScriptSerializer serializer = new JavaScriptSerializer();
return serializer.Serialize(obj);
}
public static string ToJSON(this object obj, int recursionDepth)
{
JavaScriptSerializer serializer = new JavaScriptSerializer();
serializer.RecursionLimit = recursionDepth;
return serializer.Serialize(obj);
}
}
}
Usage:
using ExtensionMethods;
...
List<Person> people = new List<Person>{
new Person{ID = 1, FirstName = "Scott", LastName = "Gurthie"},
new Person{ID = 2, FirstName = "Bill", LastName = "Gates"}
};
string jsonString = people.ToJSON();
Simlpe use of Newtonsoft.Json and Newtonsoft.Json.Linq libraries.
//Create my object
var myData = new
{
Host = #"sftp.myhost.gr",
UserName = "my_username",
Password = "my_password",
SourceDir = "/export/zip/mypath/",
FileName = "my_file.zip"
};
//Tranform it to Json object
string jsonData = JsonConvert.SerializeObject(myData);
//Print the Json object
Console.WriteLine(jsonData);
//Parse the json object
JObject jsonObject = JObject.Parse(jsonData);
//Print the parsed Json object
Console.WriteLine((string)jsonObject["Host"]);
Console.WriteLine((string)jsonObject["UserName"]);
Console.WriteLine((string)jsonObject["Password"]);
Console.WriteLine((string)jsonObject["SourceDir"]);
Console.WriteLine((string)jsonObject["FileName"]);
This library is very good for JSON from C#
http://james.newtonking.com/pages/json-net.aspx
This code snippet uses the DataContractJsonSerializer from System.Runtime.Serialization.Json in .NET 3.5.
public static string ToJson<T>(/* this */ T value, Encoding encoding)
{
var serializer = new DataContractJsonSerializer(typeof(T));
using (var stream = new MemoryStream())
{
using (var writer = JsonReaderWriterFactory.CreateJsonWriter(stream, encoding))
{
serializer.WriteObject(writer, value);
}
return encoding.GetString(stream.ToArray());
}
}
If you need complex result (embedded) create your own structure:
class templateRequest
{
public String[] registration_ids;
public Data data;
public class Data
{
public String message;
public String tickerText;
public String contentTitle;
public Data(String message, String tickerText, string contentTitle)
{
this.message = message;
this.tickerText = tickerText;
this.contentTitle = contentTitle;
}
};
}
and then you can obtain JSON string with calling
List<String> ids = new List<string>() { "id1", "id2" };
templateRequest request = new templeteRequest();
request.registration_ids = ids.ToArray();
request.data = new templateRequest.Data("Your message", "Your ticker", "Your content");
string json = new JavaScriptSerializer().Serialize(request);
The result will be like this:
json = "{\"registration_ids\":[\"id1\",\"id2\"],\"data\":{\"message\":\"Your message\",\"tickerText\":\"Your ticket\",\"contentTitle\":\"Your content\"}}"
Hope it helps!
You can also try my ServiceStack JsonSerializer it's the fastest .NET JSON serializer at the moment. It supports serializing DataContracts, any POCO Type, Interfaces, Late-bound objects including anonymous types, etc.
Basic Example
var customer = new Customer { Name="Joe Bloggs", Age=31 };
var json = JsonSerializer.SerializeToString(customer);
var fromJson = JsonSerializer.DeserializeFromString<Customer>(json);
Note: Only use Microsofts JavaScriptSerializer if performance is not important to you as I've had to leave it out of my benchmarks since its up to 40x-100x slower than the other JSON serializers.
Take a look at http://www.codeplex.com/json/ for the json-net.aspx project. Why re-invent the wheel?
If you want to avoid creating a class and create JSON then Create a dynamic Object and Serialize Object.
dynamic data = new ExpandoObject();
data.name = "kushal";
data.isActive = true;
// convert to JSON
string json = Newtonsoft.Json.JsonConvert.SerializeObject(data);
Read the JSON and deserialize like this:
// convert back to Object
dynamic output = Newtonsoft.Json.JsonConvert.DeserializeObject(json);
// read a particular value:
output.name.Value
ExpandoObject is from System.Dynamic namespace.
If you can't or don't want to use the two built-in JSON serializers (JavaScriptSerializer and DataContractJsonSerializer) you can try the JsonExSerializer library - I use it in a number of projects and works quite well.
If you're trying to create a web service to serve data over JSON to a web page, consider using the ASP.NET Ajax toolkit:
http://www.asp.net/learn/ajax/tutorial-05-cs.aspx
It will automatically convert your objects served over a webservice to json, and create the proxy class that you can use to connect to it.
Encode Usage
Simple object to JSON Array EncodeJsObjectArray()
public class dummyObject
{
public string fake { get; set; }
public int id { get; set; }
public dummyObject()
{
fake = "dummy";
id = 5;
}
public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append('[');
sb.Append(id);
sb.Append(',');
sb.Append(JSONEncoders.EncodeJsString(fake));
sb.Append(']');
return sb.ToString();
}
}
dummyObject[] dummys = new dummyObject[2];
dummys[0] = new dummyObject();
dummys[1] = new dummyObject();
dummys[0].fake = "mike";
dummys[0].id = 29;
string result = JSONEncoders.EncodeJsObjectArray(dummys);
Result:
[[29,"mike"],[5,"dummy"]]
Pretty Usage
Pretty print JSON Array PrettyPrintJson() string extension method
string input = "[14,4,[14,\"data\"],[[5,\"10.186.122.15\"],[6,\"10.186.122.16\"]]]";
string result = input.PrettyPrintJson();
Results is:
[
14,
4,
[
14,
"data"
],
[
[
5,
"10.186.122.15"
],
[
6,
"10.186.122.16"
]
]
]
The DataContractJSONSerializer will do everything for you with the same easy as the XMLSerializer. Its trivial to use this in a web app. If you are using WCF, you can specify its use with an attribute. The DataContractSerializer family is also very fast.
I've found that you don't need the serializer at all. If you return the object as a List.
Let me use an example.
In our asmx we get the data using the variable we passed along
// return data
[WebMethod(CacheDuration = 180)]
public List<latlon> GetData(int id)
{
var data = from p in db.property
where p.id == id
select new latlon
{
lat = p.lat,
lon = p.lon
};
return data.ToList();
}
public class latlon
{
public string lat { get; set; }
public string lon { get; set; }
}
Then using jquery we access the service, passing along that variable.
// get latlon
function getlatlon(propertyid) {
var mydata;
$.ajax({
url: "getData.asmx/GetLatLon",
type: "POST",
data: "{'id': '" + propertyid + "'}",
async: false,
contentType: "application/json;",
dataType: "json",
success: function (data, textStatus, jqXHR) { //
mydata = data;
},
error: function (xmlHttpRequest, textStatus, errorThrown) {
console.log(xmlHttpRequest.responseText);
console.log(textStatus);
console.log(errorThrown);
}
});
return mydata;
}
// call the function with your data
latlondata = getlatlon(id);
And we get our response.
{"d":[{"__type":"MapData+latlon","lat":"40.7031420","lon":"-80.6047970}]}
Include:
using System.Text.Json;
Then serialize your object_to_serialize like this:
JsonSerializer.Serialize(object_to_serialize)

Categories

Resources