asp.net mvc json result format - json

public class JsonCategoriesDisplay
{
public JsonCategoriesDisplay() { }
public int CategoryID { set; get; }
public string CategoryTitle { set; get; }
}
public class ArticleCategoryRepository
{
private DB db = new DB();
public IQueryable<JsonCategoriesDisplay> JsonFindAllCategories()
{
var result = from c in db.ArticleCategories
select new JsonCategoriesDisplay
{
CategoryID = c.CategoryID,
CategoryTitle = c.Title
};
return result;
}
....
}
public class ArticleController : Controller
{
ArticleRepository articleRepository = new ArticleRepository();
ArticleCategoryRepository articleCategoryRepository = new ArticleCategoryRepository();
public string Categories()
{
var jsonCats = articleCategoryRepository.JsonFindAllCategories().ToList();
//return Json(jsonCats, JsonRequestBehavior.AllowGet);
return new JavaScriptSerializer().Serialize(new { jsonCats});
}
}
This results with following:
{"jsonCats":[{"CategoryID":2,"CategoryTitle":"Politika"},{"CategoryID":3,"CategoryTitle":"Informatika"},{"CategoryID":4,"CategoryTitle":"Nova
kategorija"},{"CategoryID":5,"CategoryTitle":"Testna
kategorija"}]}
If I use line that is commented and place JsonResult instead of returning string, I get following result:<
[{"CategoryID":2,"CategoryTitle":"Politika"},{"CategoryID":3,"CategoryTitle":"Informatika"},{"CategoryID":4,"CategoryTitle":"Nova
kategorija"},{"CategoryID":5,"CategoryTitle":"Testna
kategorija"}]
But, I need result to be formatted like this:
{'2':'Politika','3':'Informatika','4':'Nova
kateorija','5':'Testna kategorija'}
Is there a simple way to accomplish this or I will need to hardcode result?

Have a look at the Json.Net library
The Json.NET library makes working
with JavaScript and JSON formatted
data in .NET simple. Quickly read and
write JSON using the JsonReader and
JsonWriter or serialize your .NET
objects with a single method call
using the JsonSerializer.
I have successfully used it within a .net mvc project.

ile,
you really should look at the json.net lib, i was in a similar dilemma recently with json/jquery and mvc and tried my own hand-rolled version but hit the many limitations in my own implemetation. the newton json lib is quite simply a no-brainer - simple to use and always being updated. the current version works fantastically with nested structures, thus making that particular json formatting issue a non-issue.
give it a look, will take you 15 mins to get to grips with.

Try returning it as an Array, Also if you return a JsonResult you can save alot of code (looks like you were attempting to get the formatting you wanted)
public class ArticleController : Controller
{
ArticleRepository articleRepository = new ArticleRepository();
ArticleCategoryRepository articleCategoryRepository = new ArticleCategoryRepository();
public JsonResult Categories()
{
var jsonCats = articleCategoryRepository.JsonFindAllCategories().ToArray();
return Json(jsonCats, JsonRequestBehavior.AllowGet);
}
}
in my test I got a result of
[{"Id":1,"Name":"Cat 1"},{"Id":2,"Name":"Cat 2"}]

Related

Simply load JSON file and expose it on WebAPI's endpoint

I have created WebAPI. In it's GET method I want to load local JSON file and pass it as response. So that when someone accesses this endpoint he will get said JSON response. As I'm total newb with WebAPI and JSON I don't know where to start. Even though I searched a lot through web.
I need something like this (don't know actual functions and classes):
// GET api/values
public JSON Get()
{
var json = File.Load(pathtoJSON.json);
return json;
}
As a newb you can tackle this problem in three steps.
STEP I - Go through some basic tutorial on youtube like these.
STEP II - Create s basic controller (get method) and return a simple String like "Hello World!". Try it and see if you are getting the response.
STEP III - Now you got something working then try to read JSON file and send them as response.
EDIT: if still you got issues, here is some very basic code for you reference:
using Newtonsoft.Json;
using System;
using System.IO;
using System.Web.Http;
public class ValuesController : ApiController
{
public UserData Get()
{
UserData userData = null;
using (StreamReader r = new StreamReader(#"C:\testjson.json"))
{
string json = r.ReadToEnd();
userData = JsonConvert.DeserializeObject<UserData>(json);
}
return userData;
}
public class UserData {
[JsonProperty("first_name")]
public string FirstName;
[JsonProperty("last_name")]
public string LastName;
[JsonProperty("age")]
public String Age;
}
}
and testjson.json
{
"first_name":"FirstTest1",
"last_name":"LastTest1",
"age":"25"
}
and the response

Struts2 Convert json array to java object array - not LinkedHashmap

First off my question is very similar to below however I'm not sure if the answers are applicable to my specific problem or whether I just need clarification about how to approach it:
Convert LinkedHashMap<String,String> to an object in Java
I am using struts2 json rest plugin to convert a json array into a java array. The array is sent through an ajax post request and the java receives this data. However instead of being the object type I expect it is received as a LinkedHashmap. Which is identical to the json request in structure.
[
{advance_Or_Premium=10000, available=true},
{advance_Or_Premium=10000, available=true},
{advance_Or_Premium=10000, available=true}
]
The data is all present and correct but just in the wrong type. Ideally I want to send the data in my object type or if this is not possible convert the LinkedHashMap from a list of keys and values into the object array. Here is the class I am using, incoming data is received in the create() method:
#Namespace(value = "/rest")
public class OptionRequestAction extends MadeAbstractAction implements ModelDriven<ArrayList<OptionRequestRest>>
{
private String id;
ArrayList<OptionRequestRest> model = new ArrayList<OptionRequestRest>();
public HttpHeaders create()
{
// TODO - need to use model here but it's a LinkedHashmap
return new DefaultHttpHeaders("create");
}
public String getId()
{
return this.id;
}
public ArrayList<OptionRequestRest> getModel()
{
return this.model;
}
public ArrayList<OptionRequestRest> getOptionRequests()
{
#SuppressWarnings("unchecked")
ArrayList<OptionRequestRest> lReturn = (ArrayList<OptionRequestRest>) this.getSession().get("optionRequest");
return lReturn;
}
// Handles /option-request GET requests
public HttpHeaders index()
{
this.model = this.getOptionRequests();
return new DefaultHttpHeaders("index").lastModified(new Date());
}
public void setId(String pId)
{
this.id = pId;
}
public void setModel(ArrayList<OptionRequestRest> pModel)
{
this.model = pModel;
}
// Handles /option-request/{id} GET requests
public HttpHeaders show()
{
this.model = this.getOptionRequests();
return new DefaultHttpHeaders("show").lastModified(new Date());
}
}
One of the things which is confusing me is that this code works fine and returns the correct object type if the model is not an array. Please let me know if my question is not clear enough and needs additional information. Thanks.

Change the json DateTime serialization in WCF 4.0 REST Service

I need to replace the DateTime serialization for JSON in WCF REST Self Hosted service. Right now, I'm using something like the following code to do it, but it's definitely not the way to go since it requires manipulating each class.
[DataContract]
public class Test
{
[IgnoreDataMember]
public DateTime StartDate;
[DataMember(Name = "StartDate")]
public string StartDateStr
{
get { return DateUtil.DateToStr(StartDate); }
set { StartDate = DateTime.Parse(value); }
}
}
where my utility function DateUtil.DateToStr does all the formatting work.
Is there any easy way to do it without having to touch the attributes on my classes which have the DataContract attribute? Ideally, there would be no attributes, but a couple of lines of code in my configuration to replace the serializer with one where I've overridden DateTime serialization.
Everything that I've found looks like I have to replace huge pieces of the pipeline.
This article doesn't appear to apply because in I'm using WebServiceHost not HttpServiceHost, which not part of the 4.5.1 Framework.
JSON.NET Serializer for WCF REST Services
By default WCF uses DataContractJsonSerializer to serialize data into JSON. Unfortunatelly date from this serializer is in very difficult format to parse by human brain.
"DateTime": "\/Date(1535481994306+0200)\/"
To override this behavior we need to write custom IDispatchMessageFormatter. This class will receive all data which should be returned to requester and change it according to our needs.
To make it happen to the operations in the endpoint add custom formatter - ClientJsonDateFormatter:
ServiceHost host=new ServiceHost(typeof(CustomService));
host.AddServiceEndpoint(typeof(ICustomContract), new WebHttpBinding(), Consts.WebHttpAddress);
foreach (var endpoint in host.Description.Endpoints)
{
if (endpoint.Address.Uri.Scheme.StartsWith("http"))
{
foreach (var operation in endpoint.Contract.Operations)
{
operation.OperationBehaviors.Add(new ClientJsonDateFormatter());
}
endpoint.Behaviors.Add(new WebHttpBehavior());
}
}
ClientJsonDateFormatter is simple class which just applies formatter ClientJsonDateFormatter
public class ClientJsonDateFormatter : IOperationBehavior
{
public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters) { }
public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation) { }
public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
{
dispatchOperation.Formatter = new ResponseJsonFormatter(operationDescription);
}
public void Validate(OperationDescription operationDescription) { }
}
In the formatter we took imput and serialize it with the changed Serializer:
public class ResponseJsonFormatter : IDispatchMessageFormatter
{
OperationDescription Operation;
public ResponseJsonFormatter(OperationDescription operation)
{
this.Operation = operation;
}
public void DeserializeRequest(Message message, object[] parameters)
{
}
public Message SerializeReply(MessageVersion messageVersion, object[] parameters, object result)
{
string json=Newtonsoft.Json.JsonConvert.SerializeObject(result);
byte[] bytes = Encoding.UTF8.GetBytes(json);
Message replyMessage = Message.CreateMessage(messageVersion, Operation.Messages[1].Action, new RawDataWriter(bytes));
replyMessage.Properties.Add(WebBodyFormatMessageProperty.Name, new WebBodyFormatMessageProperty(WebContentFormat.Raw));
return replyMessage;
}
}
And to send information to client we need data writer - RawDataWriter. Its implementation is simple:
class RawDataWriter : BodyWriter
{
byte[] data;
public RawDataWriter(byte[] data)
: base(true)
{
this.data = data;
}
protected override void OnWriteBodyContents(XmlDictionaryWriter writer)
{
writer.WriteStartElement("Binary");
writer.WriteBase64(data, 0, data.Length);
writer.WriteEndElement();
}
}
Applying all code will result in returning date in more friendly format:
"DateTime":"2018-08-28T20:56:48.6411976+02:00"
To show it in practice I created example in the github branch DateTimeFormatter.
Please check also this answer as very likely you also will need it.
There is a limitation in JSON to convert DateTime, specially according to your case.
Please see http://msdn.microsoft.com/en-us/library/bb412170(v=vs.110).aspx
and read the section Dates/Times and JSON
To resolve this problem, I simply changed the type of serialization from JSON to XML for all the calls including DateTime.
After long time discussion ,I have find out the solution for it.
Please Use the following Code to Solve serialized date..
[IgnoreDataMember]
public DateTime? PerformanceDate { get; set; }
[DataMember(EmitDefaultValue = false, Name = "PerformanceDate")]
public string UpdateStartDateStr
{
get
{
if (this.PerformanceDate.HasValue)
return this.PerformanceDate.Value.ToUniversalTime().ToString("s", CultureInfo.InvariantCulture);
else
return null;
}
set
{
// should implement this...
}
}

GXT 3.0 JsonReader with multiple root objects

I'm starting out with GXT and am a bit confused on how to use the JsonReader to parse a valid json string with multiple root objects. I have a set of selection boxes to build the sql statement to display records in a grid. I'm getting the values for the selections from the database as well. What I'm attempting to do is a single request to my php database functions to build the json with all the values for the selection boxes in one string. My first thought was the JsonReader.
Here's an example of the json I'm working with:
"categories":[{"id":"1","value":"categoryValue1"},{"id":"2","value":"categoryValue2"}], "frequencies":[{"id":"1","value":"frequencyValue1"},{"id":"2","value":"frequencyValue2"}]
Building off the cityList example in the api, this is what I've got so far.
JsonRootObject interface:
public interface JsonRootObject {
List<SelectionProperties> getCategories();
List<SelectionProperties> getFrequencies();
}
JsonRootObjectAutoBeanFactory:
public interface JsonRootObjectAutoBeanFactory extends AutoBeanFactory {
AutoBean<JsonRootObject> jsonRootObject();
}
I created a SelectionProperties interface as all are single int/string value pairs:
public interface SelectionProperties {
String getId();
String getValue();
}
Now, according to the api:
// To convert from JSON data, extend a JsonReader and override
// createReturnData to return the desired type.
So I created a reader for both categories and frequencies;
CategoryReader:
public class CategoryReader
extends
JsonReader<ListLoadResult<SelectionProperties>, JsonRootObject> {
public CategoriesReader(AutoBeanFactory factory, Class<JsonRootObject> rootBeanType) {
super(factory, rootBeanType);
}
protected ListLoadResult<SelectionProperties> createReturnData(Object loadConfig, JsonRootObject incomingData) {
return new ListLoadResultBean<SelectionProperties>(incomingData.getCategories());
}
}
FrequencyReader:
public class FrequencyReader extends
JsonReader<ListLoadResult<SelectionProperties>, net.apoplectic.testapps.client.JsonRootObject> {
public FrequencyReader(AutoBeanFactory factory, Class<JsonRootObject> rootBeanType) {
super(factory, rootBeanType);
}
protected ListLoadResult<SelectionProperties> createReturnData(Object loadConfig, JsonRootObject incomingData) {
return new ListLoadResultBean<SelectionProperties>(incomingData.getFrequencies());
}
}
This doesn't feel quite right. I'm creating multiple instances of basically the same code and parsing the actual json string twice (at this point. I may have more options for the grid once I dig in). My question is am I missing something or is there a more efficient way to parse the response string? From my onSuccessfulResponse:
JsonRootObjectAutoBeanFactory factory = GWT.create(JsonRootObjectAutoBeanFactory.class);
CategoryReader catReader = new CategoriesReader(factory, JsonRootObject.class);
FrequencyReader freqReader = new FrequenciesReader(factory, JsonRootObject.class);
categories = catReader.read(null, response);
frequencies = freqReader.read(null, response);
List<SelectionProperties> categoriesList = categories.getData();
List<SelectionProperties> frequenciesList = frequencies.getData();
ListBox cateBox = new ListBox(false);
ListBox freqBox = new ListBox(false);
for (SelectionProperties category : categoriesList )
{
cateBox.addItem(category.getValue(), category.getId());
}
for (SelectionProperties frequency : frequenciesList)
{
freqBox.addItem(frequency.getValue(), frequency.getId());
}
The above does work, both the ListBoxes are populated correctly. I just wonder if this is the correct approach. Thanks in advance!

MVC repository and interface returning Json

I'm new at MVC and can't get this to work. I basically have a Users class, a UserRepository, and a IUser interface.
This is my code:
public class Users
{
public string UserName { get; set; }
public string Department { get; set; }
public string UserType { get; set; }
}
public class UsersRepository : TimeAttendanceMVC.Models.IUsers
{
public Users Return_UserName_Dept()
{
Users U = new Users();
List<Users> LoggedInUser = new List<Users>();
U.UserName = "TestUser";
U.Department = "Finance";
U.UserType = "Administrator";
LoggedInUser.Add(U);
//string json = JsonConvert.SerializeObject(LoggedInUser, Formatting.Indented);
//return json;
return Json(LoggedInUser.ToArray(), JsonRequestBehavior.AllowGet);
}
}
namespace TimeAttendanceMVC.Models
{
public class IUsers
{
List<Users> Return_UserName_Dept();
}
}
There are a few errors that I get. In UsersRepository.cs where i'm returning Json, the error says that "The name Json does not exist in the current context". The error from IUsers.cs is that "Return_UserName_Dept() must declare a body because it is not marked abstract...".
Can anybody please help me with this. I just don't know how this is supposed to work and i'm trying to learn MVC by working on this application. It's actually the FullCalendar application found here - link to FullCalendar. I'm trying to turn it into an MVC application.
EDIT:
Maybe I need to do this:
public JsonResult Return_UserName_Dept()
instead of public Users Return_UserName_Dept()
You should be doing this on your controller in some method which returns a json action (jsonresult). The repository should be returning your data only and all the operations you need to do, whether you're converting data to json or any other logic should happen at the controller or at some helper class which would be called by the controller..
Edit:
In order to have a method which returns a JsonResult, you need to have a reference to System.Web.Mvc.ActionResult and since the repository is usually at the model, you won't have this reference.. another thing is that you might be breaking your design the logic should be available at the controller for what you want
Edit 2:
The code below is from an old post you can see here. Note how the action PopulateDetails gets the user object from the repository and that's all the repository does.. the actual logic is happening inside this method, such as populate the rest of the UserModel class, and then it returns the JsonResult:
public JsonResult PopulateDetails(UserModel model)
{
UserResultModel userResultModel = new UserResultModel();
if (String.IsNullOrEmpty(model.UserId))
{
userResultModel.Message = "UserId can not be blank";
return Json(userResultModel);
}
User user = _userRepository.GetUser(model.UserId);
if (user == null)
{
userResultModel.Message = String.Format("No UserId found for {0}", model.UserId);
return Json(userResultModel);
}
userResultModel.LastName = user.LastName;
userResultModel.FirstName = user.FirstName;
userResultModel.Message = String.Empty; //success message is empty in this case
return Json(userResultModel);
}