I have a webservice where I need to receive multiple parameters, one of which is a list.
This is the webservice method:
[HttpPost("complete/{requestId}")]
public IActionResult CompleteRequest([FromBody] RequestComplete requestComplete, int requestId)
{
if (requestId == 0)
{
return BadRequest();
}
if (requestComplete == null)
{
return BadRequest();
}
// execute code
}
The RequestComplete class looks like this:
public class RequestComplete
{
public int RequestId { get; set; }
public int UserId { get; set; }
public string emailCC { get; set; }
public string emailSubject { get; set; }
public string calcsNeeded { get; set; }
public string ssiComment { get; set; }
public List<CompleteFileUpload> completeFiles { get; set; }
}
And the CompleteFileUpload class like this:
public class CompleteFileUpload
{
public int RequestFileId { get; set; }
}
From PostMan I use a post body like this:
{
"calcsNeeded" : "4",
"completeFiles": {"RequestFileId": "384"},
"emailCC" : "test#email.com",
"emailSubject": "subject here",
"ssiComment":"Thanks for your request."
}
My expectation is that the json posted by Postman will be formatted properly to be accepted by the CompleteRequest method. However, it does not. If I remove the completeFiles section of the json, it runs fine.
What am I missing?
The definition of "completeFiles" in the JSON does not define a JSON array, it defines a single object. That JSON would be valid if the definition was:
public class RequestComplete
{
...
public CompleteFileUpload completeFiles { get; set; }
}
Try changing the JSON to:
{
"calcsNeeded" : "4",
"completeFiles": [ {"RequestFileId": "384"}, {"RequestFileId": "123"} ],
"emailCC" : "test#email.com",
"emailSubject": "subject here",
"ssiComment":"Thanks for your request."
}
Hope this helps
Related
I am calling a Solr Apache search url and it turns Json data format. However, when I parse the Json, I receive null data. My Json format is like below:
responseHeader:
status: 0
QTime: 1
params:
q: "mykeyword"
response:
numFound: 67
start: 0
docs:
0:
tstamp: "xxxxx.xxxx.xxxx"
digest: "xxxxxxxxxxxxxxx"
boost: 0.010186654
id: "https://myserer/faq.html"
title: "xxxx"
url: "xxxxxx"
_version_:"xxxxxx"
content: "xxxxxxxxxx"
1:
tstamp: "xxxx"
.....
so I created dataModel to map the json data format:
public class ResponseModel
{
public ResponseHeader responseheader { get; set; }
public Response_ responsedata { get; set; }
}
public class Response_
{
public int numFound { get; set; }
public int start { get; set; }
public Doc doc { get; set; }
}
public class Params
{
public string q { get; set; }
}
public class Page
{
public string tstamp { get; set; }
public string digest { get; set; }
public string boost { get; set; }
public string id { get; set; }
public string title { get; set; }
public string url { get; set; }
public string _version_ { get; set; }
public string content { get; set; }
}
public class Doc
{
public List<Page> pages { get; set; }
}
my code to retrieve json search results:
string baseURL = "http://myserver:8983/solr/nutch/select?q=" + keyword;
string responseBody = string.Empty;
keyword = Request.Form["txtSearchTerm"];
if (!string.IsNullOrEmpty(keyword))
{
responseBody = getJSONString(baseURL);
}
var myData = JsonConvert.DeserializeObject<ResponseModel>(responseBody);
var Response = myData.responsedata.doc; //The Response is null here
// ...
private static string getJSONString(string apiURL)
{
// it returns json string
}
Where is the problem? BTW, there are a lot of \n line break in the json data. Is that the problem and how to deal with it? Thanks
add json data sample below:
{
"responseHeader": {
"status": 0,
"QTime": 0,
"params": {
"q": "Intranet"
}
},
"response": {
"numFound": 19,
"start": 0,
"docs": [
{
"tstamp": "2020-05-20T01:23:56.427Z",
"digest": "d615d21052125d3023a6ea5a244a6be0",
"boost": 0.043801095,
"id": "https://myserver/services/index.html",
"title": "Office of Services",
"url": "https://myserver/services/index.html",
"content": "Office of Services\nWelcome to the xxxx Website\nAccessibility Navigation:\nSkip to the header\nSkip to the main content\nSkip to the footer\nIt appears that you are viewing this site with an outdated browser.\nUpdate your browser for the best viewing experience by downloading the latest version below:\nInternet Explorer\nGoogle Chrome\nFirefox\nSafari\nMenu\nSearch\nSearch\n ...\nTop\n",
"_version_": 1667170768636608512
},
{
"tstamp": "2020-05-20T01:23:56.426Z",
"digest": "16cc4c01acd01d15ddbc59b7d43b435f",
"boost": 0.045213405,
"id": "https://myserver/media/index.html",
"title": "Library Technical",
"url": "https://myserver/media/index.html",
"content": "Library Technical Services Website\nAccessibility Navigation:\nSkip to the header\nSkip to the main content\nSkip to the footer\nIt appears that you are viewing this site with an outdated browser.\nUpdate your browser for the best viewing experience by downloading the latest version below:\nInternet Explorer\nGoogle Chrome\nFirefox\nSafari\nMenu\nSearch\nSearch\n ... INTRANET\Top\n",
"_version_": 1667170768619831298
}
]
}
}
The problem is that you have an object in your json namely response and in your c# classes, you have created the property named responseData which won't map because they differ in the name, Either you would have to set the JsonProperty name to response or you should entirely change the name of your property to response. Besides, there is a web application that will correctly parse your json and will generate the C# classes for you relevantly. Here is the code that I have generated for you for the response you have shared:
public partial class WebRequestResult
{
[JsonProperty("responseHeader")]
public ResponseHeader ResponseHeader { get; set; }
[JsonProperty("response")]
public Response Response { get; set; }
}
public class Response
{
[JsonProperty("numFound")]
public long NumFound { get; set; }
[JsonProperty("start")]
public long Start { get; set; }
[JsonProperty("docs")]
public List<Doc> Docs { get; set; }
}
public class Doc
{
[JsonProperty("tstamp")]
public DateTimeOffset Tstamp { get; set; }
[JsonProperty("digest")]
public string Digest { get; set; }
[JsonProperty("boost")]
public double Boost { get; set; }
[JsonProperty("id")]
public Uri Id { get; set; }
[JsonProperty("title")]
public string Title { get; set; }
[JsonProperty("url")]
public Uri Url { get; set; }
[JsonProperty("content")]
public string Content { get; set; }
[JsonProperty("_version_")]
public double Version { get; set; }
}
public class ResponseHeader
{
[JsonProperty("status")]
public long Status { get; set; }
[JsonProperty("QTime")]
public long QTime { get; set; }
[JsonProperty("params")]
public Params Params { get; set; }
}
public class Params
{
[JsonProperty("q")]
public string Q { get; set; }
}
And you should parse your json data to C# like this:
var myData = JsonConvert.DeserializeObject<WebRequestResult>(responseBody);
You can generate your C# classes from app.quicktype.io
I would like to ask how do I get the data using the JSON. I am using the Web API and deploy using request and response.
Class1.cs
This is calling the web API by using the request and response.
public static string Test()
{
string strReq = "{ \"header\": { \"Token\": \"ba42d11f - e0ae - 4d6c - 800a - 1564485b7ccb\"},\"body\": { \"SOHeaders\": [{ \"WarehouseCode\": \"W001\", \"CompanyCode\": \"C001\", \"SONo\": \"SO001\"}]}}";
UploadToBCSSoftSCM a = new UploadToBCSSoftSCM();
string strRes = a.GetSOSts(strReq);
return strRes;
}
HomeController.cs
I can get the response from here but I don't know how to split or parse the data.
public ActionResult Index()
{
// ViewBag.Title = "Home Page";
string r = Class1.Test();
Debug.WriteLine(r);
return View();
}
The result of response is
{
"header": {
"Token": "7c6cbeba-ff57-40d2-8759-84ccb59235fd",
"DtTime": "2020-02-20 13:10:34.365",
"ResultCode": "S",
"ResultMsg": ""
},
"body": [
{
"WarehouseCode": "W001",
"CompanyCode": "C001",
"SONo": "SO001",
"SOSts": "New"
}
]
}
O site json2csharp.com you can generate classes necessary to deserialize JSON.
public class Header
{
public string Token { get; set; }
public string DtTime { get; set; }
public string ResultCode { get; set; }
public string ResultMsg { get; set; }
}
public class Body
{
public string WarehouseCode { get; set; }
public string CompanyCode { get; set; }
public string SONo { get; set; }
public string SOSts { get; set; }
}
public class RootObject
{
public Header header { get; set; }
public List<Body> body { get; set; }
}
Then using JSON.NET you can deserialize your response into objects.
var data = JsonConvert.DeserializeObject<RootObject>(json);
and then in loop you can reach all records
foreach(var d in data.body)
{
}
I'm trying to replicate the functionality in one of MoshHamedani's course on Xamarin Forms.
Here's my code (with a valid, working _url, that returns a json object with escape characters):
public partial class PartnersListPage : ContentPage
{
private const string _url = "xyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyz";
private HttpClient _httpClient = new HttpClient();
private ObservableCollection<Partner> _partners;
public PartnersListPage()
{
InitializeComponent();
}
protected override async void OnAppearing()
{
var jsonObject = await _httpClient.GetStringAsync(_url);
var dotNetObject = JsonConvert.DeserializeObject<List<Partner>>(jsonObject);
_partners = new ObservableCollection<Partner>(dotNetObject);
partnersListView.ItemsSource = _partners;
base.OnAppearing();
}
Partner.cs looks like this:
public class Partner
{
//public int Id { get; set; }
//public string Name { get; set; }
public string ImageUrl { get; set; }
public string WebUrl { get; set; }
}
Postman returns the following:
{
"partners": [
{
"imageUrl": "http://www.abcdefgh.xy//media/1007/3.jpg",
"webUrl": "http://www.abcdefgh.xy/"
},
{
"imageUrl": "http://www.ijklmnop.xy//media/1009/5.jpg",
"webUrl": "https://www.ijklmnop.xy/xy"
},
{
"imageUrl": "http://www.qrstuvxy.xy//media/2623/slsp.svg",
"webUrl": "https://www.qrstuvxy.xy/"
}
]
}
When I hit the JsonConvert.DeserializeObject line, I get the following:
An unhandled exception occured. Why is it not working?
You are deserializing with incorrect type (List<Partner>)
I'm using Json to c# converter in order to determine the class I need - just paste in your json text/data and in will generate the classes for you. For the example for your json text/data you need:
public class Partner
{
public string imageUrl { get; set; }
public string webUrl { get; set; }
}
public class RootObject
{
public List<Partner> partners { get; set; }
}
........
var result = JsonConvert.DeserializeObject<RootObject>(jsonObject);
controller returning single object but you are trying to array deserialize
public class Partner
{
//public int Id { get; set; }
//public string Name { get; set; }
public string ImageUrl { get; set; }
public string WebUrl { get; set; }
}
public class ApiResult
{
List<Partner> Partners {get;set;}
}
and..
var dotNetObject = JsonConvert.DeserializeObject<ApiResult>(jsonObject);
I have below json received from mailgun API.
{
"items": [{
"delivery-status": {
"message": null,
"code": 605,
"description": "Not delivering to previously bounced address",
"session-seconds": 0
},
"event": "failed",
"log-level": "error",
"recipient": "test#test.com"
},
{
//some other properties of above types
}]
}
Now I was trying to create a class structure for above json to auto-map the properties after deserializing.
public class test
{
public List<Item> items { get; set; }
}
public class Item
{
public string recipient { get; set; }
public string #event { get; set; }
public DeliveryStatus delivery_status { get; set; }
}
public class DeliveryStatus
{
public string description { get; set; }
}
This is how I deserialize and try to map the properties.
var resp = client.Execute(request);
var json = new JavaScriptSerializer();
var content = json.Deserialize<Dictionary<string, object>>(resp.Content);
test testContent = (test)json.Deserialize(resp.Content, typeof(test));
var eventType = testContent.items[0].#event;
var desc = testContent.items[0].delivery_status.description; //stays null
Now in the above class Item, recipient and #event gets mapped properly and since it was a keyword I was suppose to use preceding # character and it works well. But the delivery-status property from json, does not get mapped with delevery_status property in class DeliveryStatus. I have tried creating it as deliveryStatus or #deliver-status. The earlier on doesn't map again and the later one throws compile time exception. Is there anyway these things can be handled, like declaring a property with - in between? I cannot change response json as it is not getting generated from my end. Hoping for some help.
Update
Changed the class as below referring this answer, but did not help. Its null again.
public class Item
{
public string #event { get; set; }
[JsonProperty(PropertyName = "delivery-status")]
public DeliveryStatus deliveryStatus { get; set; }
}
I am not sure what the issue is at your end, but at least it works if you use this code. Make sure to include a recent version of Newtonsoft.Json in your project and you should be fine.
public class DeliveryStatus
{
public object message { get; set; }
public int code { get; set; }
public string description { get; set; }
[JsonProperty("session-seconds")]
public int session_seconds { get; set; }
}
public class Item
{
[JsonProperty("delivery-status")]
public DeliveryStatus delivery_status { get; set; }
public string #event { get; set; }
[JsonProperty("log-level")]
public string log_level { get; set; }
public string recipient { get; set; }
}
public class RootObject
{
public List<Item> items { get; set; }
}
public static void Main(string[] args)
{
string json = #"{
""items"": [{
""delivery-status"": {
""message"": null,
""code"": 605,
""description"": ""Not delivering to previously bounced address"",
""session-seconds"": 0
},
""event"": ""failed"",
""log-level"": ""error"",
""recipient"": ""test#test.com""
}]
}";
RootObject r = JsonConvert.DeserializeObject<RootObject>(json);
}
I'm trying to create an object to be returned as JSON for my REST Web Service.
I wish to get something returned like this:
{
"message": [
{
"name": "whatever.bmp"
}
],
"errors": null,
"FileInflected": 0,
"path": "C:\thepath"
}
So, how can I change the class (eFileOutput) in C#?
How can I change the class I have below?
Currently I'm able to create similar output like this:
{
"message": "Hello World",
"errors": null,
"FileInfected": 0,
"path": "C:\bla bla..."
}
and my C# class is as follows:
[DataContract]
public class eFileOutput
{
[DataMember]
public string message { get; set; }
[DataMember]
public string errors { get; set; }
[DataMember]
public Int32 FileInfected { get; set; }
[DataMember]
public string path { get; set; }
}
Tks
This is the classes that represent the JSON you've stated:
public class Message
{
public string name { get; set; }
}
public class MyObject
{
public List<Message> message { get; set; }
public object errors { get; set; }
public int FileInflected { get; set; }
public string path { get; set; }
}
var json = Newtonsoft.Json.JsonConvert.SerializeObject(new MyObject
{
message = new List<Message>
{
new Message {name = "whatever.bmp"}
},
FileInflected = 0,
path = #"c:\thepath"
});
Edit (thanks to devzero): Then you can serialize using Newtonsoft (my favorite) or JavaScriptSerializer as stated here: Turn C# object into a JSON string in .NET 4
public class MyObject
{
public Message Message { get; set; }
public List<Error> Errors { get; set; }
public int FileInflected { get; set; }
public string Path { get; set; }
}
public class Message
{
public string Name { get; set; }
}
public class Error
{
//Whatever you want
}
and if You want to serialize member as camelCase, describe like this:
var jsonSerializerSettings = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() };
var json = JsonConvert.SerializeObject(c, jsonSerializerSettings);