WebApi Newtonsoft.Json.JsonConvert.DeserializeObject <Class> Error - c#

I am doing a WebApi Method in Visual Studio 2013 and I want to Deserialize a Class Type. My Class is like this
[JsonObject]
class JOTA
{
[JsonProperty("ProductId")]
public int ProductId { get; set; }
[JsonProperty("Name")]
public string Name { get; set; }
}
My call is like this.
public void ReturnListProd(JOTA PP)
{
JOTA product = Newtonsoft.Json.JsonConvert.DeserializeObject<JOTA>(PP);
}
I have a compile error
'Network.Json.Json.Converter[] has some invalid argument'
But, if a define an ArrayList
public void ReturnListProd(ArrayList PP)
{
JOTA product = Newtonsoft.Json.JsonConvert.DeserializeObject<JOTA>(PP[0].ToString());
}
I have no error. But in this case, it does not help on what I need.
What I am missing?
Thanks

If you want a JOTA object to become a string representation of itself (serialize it) then you should be using
string serialized = Newtonsoft.Json.JsonConvert.SerializeObject(PP);
If you want the string to become a JOTA object then you are using
JOTA product = Newtonsoft.Json.JsonConvert.DeserializeObject<JOTA>(serialized);
the problem is that you are trying to deserialize an object that is not serialized (already deserialized).

You don't need the attributes if the property names are not different.
public class JOTA
{
public int ProductId { get; set; }
public string Name { get; set; }
}
public void ReturnListProd(JOTA PP)
{
var product = PP; //not really needed you can just use PP directly
}
You only need to deserialize if you are receiving a json string. Because you are using WebAPI I would suggest changing your API endpoint to a proper REST endpoint. Example:
[HttpPost, Route("api/products/add")]
public IHttpActionResult ReturnListProd([FromBody]JOTA PP)
{
try
{
//do something with passed in data
var name = PP.Name;
//always at minimum return a status code
return Ok();
}
catch
{
//returns 500
return InternalServerError();
}
}
Then change your ajax url from:
url: "yourController/ReturnListProd"
to:
url: "/api/products/add"

Related

Custom Property name for FromUrl Model

I have a model which is used to bind QueryString, that follows the naming conversation of c# but the QueryString is in a different naming conversation. How to provide a custom property name for model properties that are assigned vis FromUrl?
// Will NOT work
public class FormatDatabaseRequest
{
[JsonProperty("_type")]
public string Type { get; set; }
[JsonProperty(Name = "awef_flag")]
public string AwefFlag { get; set; }
}
// Controller.cs
[HttpPost]
public async Task<HttpResponseMessage> FormatDatabaseAsync([FromUri] FormatDatabaseRequest request) {}
// Sample URL (QueryString MUST be named _type and awef_flag)
// https://localhost:43521/myControllerName?_type=asdfa&awef_flag=asdf
If you want to get fields from URL like that, I recommend using [FromQuery] attribute, like so:
public async Task<HttpResponseMessage> Get([FromQuery] FormatDatabaseRequest data)
Then, such URL
https://localhost:43521/myControllerName?type=asdfa&awefflag=asdf
Will be parsed correctly to your object :)
json has nothing to do with query string. I don't understand why you don't like underscore properties, but you can hide them like this
public class FormatBaseRequest
{
public string _Type { get; set; }
public string Awef_flag{ get; set; }
}
public class FormatDatabaseRequest:FormatBaseRequest
{
public string Type
{
get { return _Type; }
set { _Type=value ; } //or leave just get
}
public string AwefFlag
{
get { return Awef_flag; }
set { Awef_flag=value ; } //or leave just get
}
}
you can use it for query string and for c#

Get value from Json url with a changing variable

I want to get the price of any crypto coin from BitZ api.
I have the code like this:
string coinName;
string jsonURL = "https://apiv2.bitz.com/Market/coinRate?coins=" + coinName;
I will give the variable coinName the value I want for example coinName = "btc" and I want the price in USDT
The problem here is the Json structure it contains the coin name I will end up with tons of code lines if do this for every coin,
public class Btc
{
public string usdt { get; set; }
}
public class Data
{
public Btc btc { get; set; }
}
public class Root
{
public int status { get; set; }
public string msg { get; set; }
public Data data { get; set; }
public int time { get; set; }
public string microtime { get; set; }
public string source { get; set; }
}
Unlike Bittrex api for example which is easier to read using JsonDotNet asset from unity store and :
BittrexJsonUrl = "https://api.bittrex.com/api/v1.1/public/getticker?market=USDT-" + coinName;
and then I use this code to get the data:
private IEnumerator GetData()
{
/////bittrex
UnityWebRequest request = UnityWebRequest.Get(BittrexJsonUrl);
yield return request.SendWebRequest();
if (request.error == null)
{
Bittrex_proccessJsonData(request.downloadHandler.text);
}
else
{
Debug.Log("Something went wrong!!");
}
}
private void Bittrex_proccessJsonData (string _url) {
var _bittrexJsonData = JsonConvert.DeserializeObject<BittrexJsonData>(_url);
bittrexPrice = _bittrexJsonData.result.Last;
}
this works perfectly with with bittrex's Json structure, since it doesnt contain the coin name all I do is change the Json URL.
Now I want to do like the same thing for BitZ's if you have any idea how to please help :) thank you in advance.
For such thing you could use good old SimpleJson.
Here you don't need to implement the entire c# structure but rather access the data field by field via it's ID. You can imagine it like a nested Dictionary like thing.
Simply create that file with given content from the link somewhere in your project and do e.g.
var json = JSON.Parse(the_JSON_string);
var usdt = json["Data"]["bst"]["usdt"].AsFloat;

How to read/parse Content from OkNegotiatedContentResult?

In one of my API actions (PostOrder) I may be consuming another action in the API (CancelOrder). Both return a JSON formatted ResultOrderDTO type, set as a ResponseTypeAttribute for both actions, which looks like this:
public class ResultOrderDTO
{
public int Id { get; set; }
public OrderStatus StatusCode { get; set; }
public string Status { get; set; }
public string Description { get; set; }
public string PaymentCode { get; set; }
public List<string> Issues { get; set; }
}
What I need is reading/parsing the ResultOrderDTO response from CancelOrder, so that I can use it as response for PostOrder. This is what my PostOrder code looks like:
// Here I call CancelOrder, another action in the same controller
var cancelResponse = CancelOrder(id, new CancelOrderDTO { Reason = CancelReason.Unpaid });
if (cancelResponse is OkNegotiatedContentResult<ResultOrderDTO>)
{
// Here I need to read the contents of the ResultOrderDTO
}
else if (cancelResponse is InternalServerErrorResult)
{
return ResponseMessage(Request.CreateResponse(HttpStatusCode.InternalServerError, new ResultError(ErrorCode.InternalServer)));
}
When I use the debugger, I can see that the ResultOrderDTO it is there somewhere in the response (looks like the Content) as shown in the pic below:
but cancelResponse.Content does not exist (or at least I don't have access to it before I cast my response to something else) and I have no idea about how to read/parse this Content. Any idea?
Simply cast the response object to OkNegotiatedContentResult<T>. The Content property is object of type T. which in your case is object of ResultOrderDTO.
if (cancelResponse is OkNegotiatedContentResult<ResultOrderDTO>)
{
// Here's how you can do it.
var result = cancelResponse as OkNegotiatedContentResult<ResultOrderDTO>;
var content = result.Content;
}

Parse a Json String to create a new custom object c#

I am returning a json string to a WebMethod in WebForms and I want to take the json string and parse it into custom Order objects.
I have a class:
public class Order
{
public string Item { get; set; }
public string Color { get; set; }
public string Qty { get; set; }
public string Size { get; set; }
}
And a WebMethod:
[WebMethod]
public static string SendOrder(string json)
{
List<Order> orders = new List<Order>();
return json;
}
I am passing this string:
{
json: [
{
"Item":"Nike Polo #286772 - Women's Dri-FIT Micro Pique Short Sleeved Polo",
"Size":"XL",
"Color":"Light Blue",
"Quantity":"3"
},
{
"Item":"Port Authority Women's Jacket #L790 - Black",
"Size":"Medium",
"Color":"Black",
"Quantity":"3"
}
]
}
I want to loop through this string and creating new Orders.
What is the best way to do this?
That JSON is a little oddly formatted as it maps to the following classes (using http://json2csharp.com):
public class Json
{
public string Item { get; set; }
public string Size { get; set; }
public string Color { get; set; }
public string Quantity { get; set; }
}
public class RootObject
{
public List<Json> json { get; set; }
}
I'm not sure why you have a top-level variable named json, but whatever.
At this point just use JSON.NET to deserialize into the structure.
JsonConvert.DeserializeObject<RootObject>(yourJsonString);
If you want to rename the object from Json to Order you'll need to use an attribute for that. I don't recall the name off the top of my head but it should be easy to find in the JSON.NET documentation.
I recently completed a Windows Phone app that retrieved info from a Web API-based server as Json strings. I ended up using the JsonConvert class to convert my lists of objects from Json strings to my custom objects. Here's an example of one of my client-side methods that receives and converts the Json strings:
public async void GetGames()
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("base url");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = await client.GetAsync("specific url extention (like api/Order)");
if (response.IsSuccessStatusCode)
{
string s = await response.Content.ReadAsStringAsync();
var deserializedResponse = JsonConvert.DeserializeObject<List<Order>>(s);
//rest of code
}
}
}
Also, make sure that your web method is actually doing something. The example web method you posted creates creates a new list then just returns the parameter you passed in. Using Web API, you could return a list of all Order objects in your database via a method similar to the following:
public IQueryable<Order> GetOrders()
{
return db.Orders; //db is an instance of your DbContext class
}
I hope this is helpful. Let me know if you have any questions.

servicestack.text deserializing array to object

I have a REST-Service build with ServicStack and in one call the user can send different types of values. So I made the property in C# of type object.
The JSON that is sent looks like this:
{"name":"ffff","params":[{"pId":1,"value":[624,625]},{"pId":2,"value":"xxx"}]}
The part "value":[624,625] results in a string object filled with "[624,625]". I was hoping to get an int-array or at least a string array, but it is plain string.
I set JsConfig.TryToParsePrimitiveTypeValues = true, but that doesn't seem to have any effect.
I tried the latest sources from github.
Can this be done with any combination of switches or must I parse this myself?
Thanks
EDIT:
Here is some testcode:
[TestMethod]
public void JsonTest()
{
string json = "{\"name\":\"ffff\",\"params\":[{\"pId\":1,\"value\":[624,625]},{\"pId\":2,\"value\":\"xxx\"}]}";
var x = JsonSerializer.DeserializeFromString<xy>(json);
Assert.AreEqual(x.Params[0].Value.GetType(), typeof(int[]));
}
public class xy
{
public string Name { get; set; }
public List<Param> Params { get; set; }
}
public class Param
{
public int PId { get; set; }
public object Value { get; set; }
}
If you change the type of "Value" to int array as follows, then ServiceStack will serialize to array of int.
public class Param
{
public int PId { get; set; }
public int[] Value { get; set; }
}
The following unit test passes:
[TestMethod]
public void JsonTest()
{
string json = "{\"name\":\"ffff\",\"params\":[{\"pId\":1,\"value\":[624,625]},{\"pId\":2,\"value\":\"xxx\"}]}";
var x = JsonSerializer.DeserializeFromString<xy>(json);
Assert.AreEqual(x.Params[0].Value.GetType(), typeof(int[]));
// Show that we have some integers
Assert.IsTrue(x.Params[0].Value.Count()>0);
}
If you cannot change the type of Value for any reason, then you can use ServiceStack.Text to serialize the string into an array as needed.

Categories