Sending JSON object to the server via http GET - json

I am looking for sending JSON object to the server via GET.
Chris's answer on Post an Array of Objects via JSON to ASP.Net MVC3 works for the http POST but not for GET.
My case also works for POST but not for GET. What can I do to make GET work
Here is my case:
in Controller I have the following method
public ActionResult Screenreport(Screentable screendata)
{
// do something here
return View();
}
I have two ModelView as follows:
public class Screenrecord
{
public string Firstname{ get; set; }
public string Lastname{ get; set; }
}
public class Screentable
{
public List<Screenrecord> Screenlist { get; set; }
}
On the client side I generate JSON object
var Screentable = { Screenlist: screendata };
screendata is an array of Screenrecord
All this work when I use POST but when I use GET I am getting null value (screendata = null) Controllers' method.
In other word when click GO, screendata is null in Screenreport(Screentable screendata) routine.
Also, if I send one JSON object it works but if I send an array (list) like I described, it does not.
Is what I am trying to do doable?

No :-)
Thats not how get works.
http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
(see 9.3 GET)
"The GET method means retrieve whatever information (in the form of an entity) is identified by the Request-URI"
Request-URI being the important part here. There is no concept of body data in a GET request.

Try changing method to public ActionResult Screenreport(HttpRequestMessage request)
Then use below code to get JSON object.
data = request.RequestUri.Query;
data = HttpUtility.ParseQueryString(data).Get("request");

Try this example in Javascript:
var someObject = {
id:123456,
message:"my message",
}
var objStr = JSON.stringify(someObject);
var escapedObjStr = encodeURIComponent(objStr);
var getUrlStr = "http://myserver:port?json="+escapedObjStr
and now you can forward this URL to your server. I know this is not in any .NET language but you can definitely find the equivalent methods used, or just use the JS right away.

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

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);

Using Json.NET for JSON Model Binding

I have a method being posted to via AJAX with the following header:
public JsonResult GetDocuments(string searchTerm, SortRequest sort)
The SortRequest object is defined as follows:
[DataContract]
public class SortRequest
{
[DataMember(Name = "field")]
public string Field { get; set; }
[DataMember(Name = "dir")]
public string Direction { get; set; }
}
Because of legacy code, the JSON object has the property name "dir" which doesn't directly match the C# property name. We want to use Json.NET as the model binder for JSON requests because it is able to handle this, but the problem is that the JSON coming into the model binder looks like a single object with two top level properties, "searchTerm" and "sort". The deserialization process then tries to map that entire JSON string into each method parameter which obviously fails.
I have tried looking through the now open source .NET MVC code and have not yet been able to determine how the DefaultModelBinder class handles this gracefully. The only option I can see so far is to convert every JSON action to take in a single request parameter but this doesn't seem like a good solution as the DefaultModelBinder doesn't require this.
Edit for clarification:
The JSON request string looks something like this:
{
"searchTerm": "test",
"sort": {
"field": "name",
"dir": "asc"
}
}
We are overriding the DefaultModelBinder and only using Json.NET when the request is of type application/json. Here is the relevant code:
var request = controllerContext.HttpContext.Request;
request.InputStream.Seek(0, SeekOrigin.Begin);
using (var reader = new StreamReader(request.InputStream))
{
var jsonString = reader.ReadToEnd();
result = JsonConvert.DeserializeObject(jsonString, bindingContext.ModelType);
}
The bindingContext.ModelType is going to be set to String and SortRequest for each parameter in the method, but since the above is a single JSON object, it doesn't map to either of those types and thus inside the method itself, everything is set to default values.
I think the JsonProperty attribute can be used for this as follows:
[DataContract]
public class SortRequest
{
[DataMember(Name = "field")]
[JsonProperty("field")]
public string Field { get; set; }
[DataMember(Name = "dir")]
[JsonProperty("dir")]
public string Direction { get; set; }
}
Update
Based upon the json add a binding prefix:
public JsonResult GetDocuments(string searchTerm, [Bind(Prefix="sort"] SortRequest sort)
I ended up going with a solution using the JToken.Parse method in the Json.NET library. Essentially what is happening is that we check the top level properties of the JSON object and see if there exists the current action parameter we are trying to bind to. Where this falls down is if there is overlap between the parameter name of the action and a property name of a single request being passed in. I think this is enough of an edge case to let slide as it would require only a single object be passed into an action that is expecting multiple.
Here is the modified BindModel method:
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
object result;
if (IsJSONRequest(controllerContext))
{
var request = controllerContext.HttpContext.Request;
request.InputStream.Seek(0, SeekOrigin.Begin);
using (var reader = new StreamReader(request.InputStream))
{
var jsonString = reader.ReadToEnd();
// Only parse non-empty requests.
if (!String.IsNullOrWhiteSpace(jsonString))
{
// Parse the JSON into a generic key/value pair object.
var obj = JToken.Parse(jsonString);
// If the string parsed and there is a top level property of the same
// name as the parameter name we are looking for, use that property
// as the JSON object to de-serialize.
if (obj != null && obj.HasValues && obj[bindingContext.ModelName] != null)
{
jsonString = obj[bindingContext.ModelName].ToString();
}
}
result = JsonConvert.DeserializeObject(jsonString, bindingContext.ModelType);
}
}
else
{
result = base.BindModel(controllerContext, bindingContext);
}
return result;
}

Omit null values in json response from Nancy FX

I am trying to create a REST service using Nancy FX in a C# environment. I can easily do a Response.AsJson and it all looks good. But I want the response to omit any properties that are null.
I have not been able to figure out how to do this yet.
Could someone point to me towards a help document or a blog post somewhere, that explains how to do this.
Thanks,
JP
I would create a dynamic anonymous type and return that. So let's say you have a User object like this:
public class User
{
public string Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
You want to pass back an instance of this type as a JSON response so you will have some code like this:
Get["/user/{userid}"] = parameters =>
{
var user = UserService.GetById(Db, (string)parameters.userid);
if (user == null) return HttpStatusCode.UnprocessableEntity;
return Response.AsJson(user);
};
But you don't want to return the User instance, instead you want to return an separate instance of a dynamic type that will only implement a property if the property value is not null for a given instance.
So I would suggest code something like this:
Get["/user/{userid}"] = parameters =>
{
var user = UserService.GetById(Db, (string)parameters.userid);
if (user == null) return HttpStatusCode.UnprocessableEntity;
dynamic userDTO = new ExpandoObject();
userDTO.Id = user.Id;
if (!string.IsNullOrEmpty(user.FirstName)) userDTO.FirstName = user.FirstName;
if (!string.IsNullOrEmpty(user.LastName)) userDTO.Lastname = user.LastName;
return Response.AsJson((ExpandoObject)userDTO);
};
Note 1
You don't need to test for the Id since that is implied by the successful return of the User instance from the database.
Note 2
You need to use a dynamic type so you can include ad hoc properties. The problem is that extension methods cannot accept dynamic types. To avoid this you need to declare it as an ExpandoObject but use it as a dynamic. This trick incurs a processing overhead but it allows you to cast the dynamic to an ExpandoObject when passing it in to the AsJson() extension method.

Returning and displaying a JSON Object which is an associate array in a Windows 8 App

I am using a online tutorial to lean how to create a web service, generate a JSON object, send it back to my Win 8 App and display it. The web service is working however I am struggling to return a value to the APP. My code in the app is:
WinJS.xhr({
url: 'http://localhost/filmgloss/web-service.php?termID=1&format=JSON'
})
.done(
function complete(result) {
// terms is the key of the object
for (var terms in result) {
for (var term in terms) {
if (result.hasOwnProperty(term)) {
//here you have to acess to
var termName = result[term].termName;
var def = result[term].definition;
}
//Show Terms
testDef.innerText = definition;
}
}
},
And he code in my web service is:
if($format == 'json') {
header('Content-type: application/json');
echo json_encode(array('terms'=>$terms));
}else...
The JSON output itself looks like:
{"terms":[{"term":{ "termName":"Focus","definition":"A Focus..."}}]}
I am using a for..in but whilst I can look inside terms' I can't work out how to look interm`
I usually build my own data structure that represents the JSON structure.
In your case it would be something like this:
public class TermsList
{
public List<Term> terms { get; set; }
}
public class Term
{
public string termName { get; set }
public definition termName { get; set }
...
}
Then you can just deserialize your string into your object. There are different ways to do this. I would use Json.Net.
Here is one way:
Parse JSON in C#
public static T Deserialise<T>(string json)
{
T obj = Activator.CreateInstance<T>();
using (MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(json)))
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
obj = (T)serializer.ReadObject(ms); // <== Your missing line
return obj;
}
}
If you wanna keep it dynamic, that should work too:
http://www.drowningintechnicaldebt.com/ShawnWeisfeld/archive/2010/08/22/using-c-4.0-and-dynamic-to-parse-json.aspx
I have managed to resolve my issue with the help of a developer friend. My problem was that I had not realised that the result of WinHS.xhr was not already a JSON Array. Although my web-service outputs a JSON Array when it is consumed through WinHS.xhr it appears to be returned as an XMLHttpRequest object.
The solution was therefore to process the result using:
JSON.parse(result.responseText)
I could then use a For...In loop as expected:
for (terms in responseTerms) {
//terms will find key "terms"
var termName = responseTerms.terms[0].term.termName;
var termdefinition = responseTerms.terms[0].term.definition;
testTerm.innerText = termName;
testDef.innerText = termdefinition;
}
Thanks for everyone that commented, hopefully this may help others in the future if they're starting out with Win 8 app development.