I am creating an API. Where I have to accept JSON data. I found the JSON not properly fit with my property class. In this scenario how should I get data from post request?
I have tried with WEB API but it's showing null error
System.NullReferenceException: 'Object reference not set to an instance of an object.'
You cannot always change the class like #GuruStron suggests. Because it could have dependencies on other parts of the program.
What you should do : Customize your JSON parser
You probably already use Newtonsoft to parse your incoming body request into your class. Now what you need is to customize that parser so it fit your need.
Here is the doc: How to create a custom JsonCoverter
If you don't use Newtonsoft you probably use default System.TextJson in that case here are the docs
No matter which "parser" you use, you'll probably find an equivalent on the web
Please provide more details (and some code) for a more precise answer.
I don't know if you are receiving the json via an HttpClient, but in the case you can use ExpandoObject or dynamic as read target from the content.
es.
var response = await httpClient.GetAsync(url);
var result = await response.Content.ReadFromJsonAsync<dynamic>();
or
var result = await response.Content.ReadFromJsonAsync<ExpandoObject>();
In any case, case the deserialization to dynamic or ExpandoObject could work also from a string (see this).
Related
We're using ServiceStack to build a web API. I have a situation where I want to be able to return a response of 400 (BadRequest) from an API endpoint with some additional data indicating the specific cause(s) of the error.
The two ways I know about to return a specific status code are:
Throw an exception.
Return an instance of HttpResult.
I'd rather not return an instance of HttpResult. It would require me to make the method return type more generic (currently the return type is the specific response DTO), and there are other reasons (having to do with our use of ServiceStack) why that is problematic.
The situation with throwing an exception is weird. Based on the form of the response, ServiceStack is using the custom DTO even in the exception case (and the docs confirm this). And the HttpError exception class has a Response property which corresponds to the DTO used to issue the response, but setting the Response property to an instance of the custom DTO does not have the intended effect. It only affects the value of the ResponseStatus property on the response DTO. The other properties on the DTO are uninitialized as though ServiceStack generated a fresh instance of of the response DTO and used that instead (but set its ResponseStatus property from the provided DTO.
Is everything I've said actually correct? Is there another option for forming the response that doesn't have the drawbacks I've mentioned above?
If you want to decorate a Response with additional metadata, return the response in a HttpResult - that's the entire purpose of the class. There's no visible difference to the HTTP Response body of a Response DTO returned directly vs wrapped in a HttpResult.
Alternatively you can just modify the base.Response directly, see the docs on Customizing HTTP Responses.
Throwing an Exception is only returning a HTTP Error Response. ServiceStack has implicit structured error handling where it captures the Error in a ResponseStatus which is extracted from any Response DTO.
I've got a controller action that just displays a JSON result: http://pkssblog-stage.azurewebsites.net/BlogPosts/GetAll. The object has a property called Content which is basically the HTML content of a post.
The problem is I always get invalid JSON exceptions when parsing it using the JsonObject.Parse in WinRT, the JSON.parse within a browser console or even JSON validators online.
The weird thing is that I don't get issues when I turn it into a javascript object via the console through var x = jsonstringarray;
I get in trouble with this specific property (as noted by the online validators):
"Content":"\u003cbr\u003eMicrosoft Azure Storage provides many services...
Any ideas?
I have a small WinRT client app to my online service (Azure Web Service). The server sends a JSON encoded object with (with potential additional metadata) to the client and the client's responsibility would be to deserialize this data properly into classes and forward it to appropriate handlers.
Currently, the objects received can be deserialized with a simple
TodoItem todo = JsonConvert.DeserializeObject<TodoItem>(message.Content);
However, there can be multiple types of items received. So what I am currently thinking is this:
I include the type info in the header serverside, such as "Content-Object: TodoItem"
I define attributes to TodoItem on the client side (see below)
Upon receiving a message from the server, I find the class using the attribute I defined.
I call the deserialization method with the resolved type
(Example of the attribute mentioned in 2.)
[BackendObjectType="TodoItem"]
public class TodoItem
My problem with this approach however is the Type to Generics in the deserialization as I can't call:
Type t = ResolveType(message);
JsonConvert.DeserializeObject<t>(message.Content);
I tried finding some solutions to this and getting method info for the DeserializeObject and calling it using reflection seemed to be the way to go. However, GetMethod() does not exist in WinRT and I was not able to find an alternative I could use to retrieve the generic version of the DeserializeObject (as fetching by the name gives me the non-generic overload). I don't mind using reflection and GetMethod as I can cache (?) the methods and call them every time a message is received without having to resolve it every time.
So how do I achieve the latter part and/or is there another way to approach this?
Alright, I feel like this was not really a problem at all to begin with as I discovered the DeserializeObject(string, Type, JsonSerializerSettings) overload for the method. It works splendidly. However, I would still like to hear some feedback on the approach. Do you think using attributes as a way to resolve the type names is reasonable or are there better ways? I don't want to use the class names directly though, because I don't want to risk any sort of man-in-the-middle things be able to initialize whatever.
Just a few minutes ago we have posted the alternative way to do what you want. Please look here, if you will have any questions feel free to ask:
Prblem in Deserialization of JSON
Try this
http://json2csharp.com/
Put your Json string here it will generate a class
then
public static T DeserializeFromJson<T>(string json)
{
T deserializedProduct = JsonConvert.DeserializeObject<T>(json);
return deserializedProduct;
}
var container = DeserializeFromJson<ClassName>(JsonString);
I believe that my .NET 4.5 DateTime object is being incorrectly serialized by its ApiController in my ASP.NET MCV 4 web app. After retrieving a DataRow object from an SQL Server database I assign it to a DateTime member object in my CarrierObject.
StartTime = (DateTime)row["start_time"]
After this I add the CarrierObject to a list and return the list when all relevant entries have been processed. The ApiController converts the list to a JSON string for transmission.
When I perform the API call on the client and read the JSON output I get output in the form of 2013-06-03T22:49:21.66
While this looks fine at first glance, attempting to parse this on the client side with
var client = new HttpClient();
var uri = new Uri("http://555.55.55.55/test4/api/values");
Stream respStream = await client.GetStreamAsync(uri);
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(List<CarrierObject>));
List<CarrierObject> feeds = (List<CarrierObject>)ser.ReadObject(respStream);
it fails with the exception
System.Runtime.Serialization.SerializationException was unhandled by user code
HResult=-2146233076
Message=There was an error deserializing the object of type System.Collections.Generic.List ... PublicKeyToken=null]]. DateTime content '2013-06-03T22:49:21' does not start with '\/Date(' and end with ')\/' as required for JSON.
It seems to be wanting something in the format /Date(1224043200000)/. While I could manually write a converter to produce the correct JSON format that would seem to defeat the purpose of the automatic serialization performed by the API controller and automatic deserialization performed by the DataContractJsonSerializer. Is there a way to make the DataContractJsonSerializer accept the format being produced by the API Controller or the opposite? Is there a different parser that I should be using?
Thank you for your time,
-- Techrocket9
Date serialization has always been a rough point for DataContractJsonSerializer. Try JSON.NET instead.
This is one of the reasons that WebAPI decided to use JSON.NET by default, rather than the older DataContractJsonSerializer.
Looks like it's really a gotcha in DataContractJsonSerializer. You can try to implement what this guy did here. Or this answer for a similar question raised before.
I'm trying to serialize a Request object for logging purposes. The code
System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(obj.GetType());
// obj is a Request object
gives me the following exception:
To be XML serializable, types which inherit from ICollection must have an implementation of Add(System.String) at all levels of their inheritance hierarchy. System.Web.HttpValueCollection does not implement Add(System.String).
How to solve the problem? Thanks.
In short, trying to serialize a http request object may not end well; even if you get past the current issue, I would expect it to fail in a few more places.
You should construct your own object model that includes those parts of the request you care about, in a simple form. In the case of the HttpValueCollection, you may need to add a basic collection of some type that is a name/value pair.
Then: populate your new model from the actual request, and serialize your model.
If you're interested in the request as a whole (ie: bytes), you can use the HttpRequest.Filter Property. It allows to install a filter (an object that derives from Stream) that can read and write from the raw input HTTP request.
Here is an article on the subject: Filtering HTTP Requests with .NET
I didn't try it but this would likely work and would be available to serialize.
HttpContext.Current.Request.GetType()
.GetProperties()
.Select(
a =>
new KeyValuePair<object, object>(a, HttpContext.Current.Request.GetType().GetProperty(a.GetType().Name)))
.ToList();