Newtonsoft JSON - json

I have created a New MVC4 Application and by default Newton JSON added to the Package.
I read that it is useful for serializing and deserializing JSON. Is this all it does ?
By default we can send JSON in MVC using JSONResult. and using Stringify in JQuery i can receive as a class in C#.
I know there should be some reason why they added Newton JSON.
As i am new to MVC and starting off new project want to know some insight of which serialize/deserialize to go for ?
Thanks

They added Newtonsoft so that your WebAPI controller can magically serialize your returned object. In MVC 3 we used to return our object like so:
public ActionResult GetPerson(int id)
{
var person = _personRepo.Get(id);
return Json(person);
}
In a Web API project you can return person and it will be serialized for you:
public Person GetPerson(int id)
{
var person = _personRepo.Get(id);
return person
}

Use JsonResult and return Json(yourObject) on a post operation, or Json(yourObject, JsonRequestBehavior.AllowGet) if you're doing a GET operation.
If you want to deserialize Json with the Newton Json.NET, check out http://www.hanselman.com/blog/NuGetPackageOfTheWeek4DeserializingJSONWithJsonNET.aspx

If your project was just an MVC project with no WebApi, then Newtonsoft.Json was not added for returning JsonResults as the JsonResult returned by MVC uses the JavaScriptSerializer as below:
public override void ExecuteResult(ControllerContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
if (JsonRequestBehavior == JsonRequestBehavior.DenyGet &&
String.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase))
{
throw new InvalidOperationException(MvcResources.JsonRequest_GetNotAllowed);
}
HttpResponseBase response = context.HttpContext.Response;
if (!String.IsNullOrEmpty(ContentType))
{
response.ContentType = ContentType;
}
else
{
response.ContentType = "application/json";
}
if (ContentEncoding != null)
{
response.ContentEncoding = ContentEncoding;
}
if (Data != null)
{
JavaScriptSerializer serializer = new JavaScriptSerializer();
if (MaxJsonLength.HasValue)
{
serializer.MaxJsonLength = MaxJsonLength.Value;
}
if (RecursionLimit.HasValue)
{
serializer.RecursionLimit = RecursionLimit.Value;
}
response.Write(serializer.Serialize(Data));
}
}
In this case it was added because WebGrease has a dependency on it. And the bundling and minification services provided by MVC in System.Web.Optimization have a dependency on WebGrease.
So a default MVC app with no WebApi will have Newtonsoft.Json installed for bundling and minification services not WebApi.
To be clear the JsonResult returned by WebApi in System.Web.Http does use Newtonsoft.Json for it's serialization as below:
using Newtonsoft.Json;
using System;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http;
namespace System.Web.Http.Results
{
/// <summary>
/// Represents an action result that returns an <see cref="F:System.Net.HttpStatusCode.OK"/> response with JSON data.
/// </summary>
/// <typeparam name="T">The type of content in the entity body.</typeparam>
public class JsonResult<T> : IHttpActionResult
But Newtonsoft.Json is not included in a non WebApi, default MVC project just in case you might decide to use some WebApi, it's there because, as above, WebGrease needs it. Not sure what they're doing in vNext, probably Newtonsoft.Json.

Related

WCF custom serialization

I'm using .Net Framework WCF. This application receive json requests and response json string.
I would like to use my own serialization library for the serialization and deserialization actions.
In asp.net I used to do it in Global.asax file:
IJsonSerializer serializer = new Serializer();
GlobalConfiguration.Configuration.Formatters.Add(new CustomFormatter(serializer));
Here is my customer formatter class:
using System.Text;
using System;
using System.IO;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Net;
using System.Threading.Tasks;
namespace Test.Formatters
{
public class CustomFormatter: MediaTypeFormatter
{
private readonly IJsonSerializer _serializer;
public CustomFormatter(IJsonSerializer serializer)
{
_serializer = serializer;
SupportedMediaTypes.Add(new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"));
SupportedMediaTypes.Add(new System.Net.Http.Headers.MediaTypeHeaderValue("text/json"));
SupportedMediaTypes.Add(new System.Net.Http.Headers.MediaTypeHeaderValue("application/xml"));
SupportedMediaTypes.Add(new System.Net.Http.Headers.MediaTypeHeaderValue("text/xml"));
SupportedEncodings.Add(Encoding.UTF8);
SupportedEncodings.Add(Encoding.Unicode);
}
public override bool CanReadType(Type type)
{
return true;
}
public override bool CanWriteType(Type type)
{
return true;
}
public override async Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
{
StreamReader reader = new StreamReader(readStream);
string text = await reader.ReadToEndAsync();
var serializedObj = _serializer.Deserialize(type, text);
return serializedObj;
}
public override async Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)
{
var serializedObj = _serializer.Serialize(value);
var encoding = Encoding.GetEncoding(content.Headers.ContentType.CharSet);
await writeStream.WriteAsync(encoding.GetBytes(serializedObj), 0, encoding.GetBytes(serializedObj).Length);
}
}
}
In .NetFramework WebAPI ReadFromStreamAsync and WriteToStreamAsync are triggered perfectly.
However, in WCF they are not triggered even though content-type is "application/json".
How can I handle WCF serialization by myself?

Can't see the JSON result of a Get request in postman and shows empty string array

I have an ASP.NET CORE application that sends a POST/GET request to a REST (Orthanc Rest API). The issue is I receive the result and convert it to a JSON, but postman shows as an empty array. here is my code:
// GET Method
public class PACSController : ControllerBase
{
// GET: api/PACS
[HttpGet]
public async Task<object> Get()
{
var result = await Orthanc.Orthanc.InstanceAsync();
return result;
}
}
public class Orthanc
{
public static string baseUrl = "https://demo.orthanc-server.com/";
public static async Task<object> InstanceAsync()
{
string url = baseUrl + "instances";
using (HttpClient client = new HttpClient())
using (HttpResponseMessage res = await client.GetAsync(url))
using (HttpContent content = res.Content)
{
string data = await content.ReadAsStringAsync();
if (data != null)
{
Console.WriteLine(data);
}
var jData = JsonConvert.DeserializeObject(new string[] { data }[0]);
return jData;
}
}
}
The result of request inside the code
Postman result
As part of the work to improve the ASP.NET Core shared framework, Newtonsoft.Json has been removed from the ASP.NET Core shared framework for asp.net core 3.x.
Follow the steps:
Install the Microsoft.AspNetCore.Mvc.NewtonsoftJson package on nuget.
Install-Package Microsoft.AspNetCore.Mvc.NewtonsoftJson
Update Startup.ConfigureServices to call AddNewtonsoftJson.
services.AddControllersWithViews().AddNewtonsoftJson();
Reference:
https://learn.microsoft.com/en-us/aspnet/core/migration/22-to-30?view=aspnetcore-3.1&tabs=visual-studio#use-newtonsoftjson-in-an-aspnet-core-30-mvc-project

Swagger /v2/api-docs JSON Generated Incorrectly

I have a new Spring Boot project that I'm setting up and have modeled it after another similar project. For the swagger-ui.html page for the new project we get a generic "No operations defined in spec!" message and no Swagger documentation.
I've tracked the issue down to the generated v2/api-docs JSON file.
For my working project, we have the expected swagger JSON and the HTML page is generated correctly
{
swagger: "2.0",
info: {},
basePath: "/",
tags: [],
paths: {},
definitions: {}
}
For the new, broken project, there is a value key and all the usual swagger JSON is a stringified value for that key.
{
value: "{"swagger":"2.0","info":{"...}"
}
The projects all have effectively the same version of Gradle, Java, Swagger, and any other versions that I've looked at. SwaggerConfigs look to be identical as well.
Is there some undocumented setting or API interaction that would cause this swagger JSO to generate incorrectly?
You can re-config the JsonSerializer,like something below described:
adapter:
public class SpringfoxJsonToGsonAdapter implements JsonSerializer<Json> {
#Override
public JsonElement serialize(Json json, Type type, JsonSerializationContext context) {
final JsonParser parser = new JsonParser();
return parser.parse(json.value());
}
}
Gson config:
#Configuration
public class GsonHttpMessageConverterConfig {
#Bean
public GsonHttpMessageConverter gsonHttpMessageConverter() {
GsonHttpMessageConverter converter = new GsonHttpMessageConverter();
converter.setGson(gson());
return converter;
}
private Gson gson() {
final GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(Json.class, new SpringfoxJsonToGsonAdapter());
return builder.create();
}
}

How to send serializable request object with httpClient in .net core?

I'm new in .net and I'm looking for a way (if exists) to be able to pass a request object to a http client without "manually" serialize it to json. I did some java implementations in the past and there it was done under the hood and I thought that it should be possible also in .netCore
This is the request object:
public class Request
{
[JsonProperty("number", NullValueHandling = NullValueHandling.Ignore)]
public int Number { get; set; }
}
and I'm looking for something like:
var request = new Request {Number=2};
client.PostAsync("url", request)
I found a similar implementation, but that does not seems to be .netcore compatible:
https://www.nuget.org/packages/Microsoft.AspNet.WebApi.Client/5.2.4-preview1
Is there anything similar for .netcore?
Thanks
You will still need to serialize the object to a JSON string.
The referenced Microsoft.AspNet.WebApi.Client library in question would have the PostAsJsonAsync extension method along with many others for extending HttpClient.
Which internally may have looked like this.
public static Task<HttpResponseMessage> PostAsJsonAsync<T>(this HttpClient client, string requestUri, T obj) {
var json = JsonConvert.SerializeObject(obj);
var content = new StringContent(json, Encoding.UTF8, "application/json");
return client.PostAsync(requestUri, content);
}
and used like
using System.Net.Http;
//...
var request = new Request { Number = 2 };
var response = await client.PostAsJsonAsync("url", request);

How to respond via an JsonResult from Asp.Net Core middleware?

I would like to respond via a JsonResult from a piece of Asp.Net Core middleware but it's not obvious how to accomplish that. I have googled around alot but with little success. I can respond via a JsonResult from a global IActionFilter by setting the ActionExecutedContext.Result to the JsonResult and that's cool. But in this case I want to effectively return a JsonResult from my middleware. How can that be accomplished?
I framed the question with regard to the JsonResult IActionResult but ideally the solution would work for using any IActionResult to write the response from the middleware.
Middleware is a really low-level component of ASP.NET Core. Writing out JSON (efficiently) is implemented in the MVC repository. Specifically, in the JSON formatters component.
It basically boils down to writing JSON on the response stream. In its simplest form, it can be implemented in middleware like this:
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
// ...
public async Task Invoke(HttpContext context)
{
var result = new SomeResultObject();
var json = JsonConvert.SerializeObject(result);
await context.Response.WriteAsync(json);
}
For others that may be interested in how to return the output of a JsonResult from middleware, this is what I came up with:
public async Task Invoke(HttpContext context, IHostingEnvironment env) {
JsonResult result = new JsonResult(new { msg = "Some example message." });
RouteData routeData = context.GetRouteData();
ActionDescriptor actionDescriptor = new ActionDescriptor();
ActionContext actionContext = new ActionContext(context, routeData, actionDescriptor);
await result.ExecuteResultAsync(actionContext);
}
This approach allows a piece of middleware to return output from a JsonResult and the approach is close to being able to enable middleware to return the output from any IActionResult. To handle that more generic case the code for creating the ActionDescriptor would need improved. But taking it to this point was sufficient for my needs of returning the output of a JsonResult.
As explained by #Henk Mollema, I have also made use of Newtonsoft.Json JsonConvert class to serialize the object into JSON through SerializeObject method. For ASP.NET Core 3.1 I have used JsonConvert inside the Run method. Following solution worked for me:
Startup.cs
using Newtonsoft.Json;
// ...
public class Startup
{
public void Configure(IApplicationBuilder app)
{
app.Run(async context =>
{
context.Response.StatusCode = 200;
context.Response.ContentType = "application/json";
await context.Response.WriteAsync(JsonConvert.SerializeObject(new
{
message = "Yay! I am a middleware"
}));
});
}
}
As of ASP.NET Core 5.0, you can use WriteAsJsonAsync to write JSON to the response stream. This method handles serialization and setting the content type header appropriately.
For example
using Microsoft.AspNetCore.Http;
// ..
public async Task InvokeAsync(HttpContext context)
{
var result = new SomeResultObject();
await context.Response.WriteAsJsonAsync(result);
}