i need some help here
I am trying to make an API call by sending a json object to it.
but i am struggling to convert C# datetime to proper json format.
Here is my Sample Code.
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create("example.com");
httpWebRequest.ContentType = "text/json";
httpWebRequest.Method = "POST";
using (StreamWriter streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = "{\"ReferenceNumber\":\"Testing OAKLAND\",\"CustomerNotes\":\"Testing\",\"DeliveryDate\":" + "Date(" + System.DateTime.Now.Ticks + ")" +
",\"OrderLineItems\":[{\"ItemEntityId\":14771,\"Quantity\":2}]}";
streamWriter.Write(json);
streamWriter.Close();
}
HttpWebResponse httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (StreamReader streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
string responseText = streamReader.ReadToEnd();
Response.Write(responseText);
Response.End();
}
Please guide me how to format datetime in json and do u guys think that json this json object is fine?? I am Using .NET 2.0 Framework
Use serialization instead. It will handle any escaping and converting you need to do.
For .NET 2.0 you don't have the luxury of anonymous types, so you will have to create a model class for the data you want to serialize:
public class OrderModel {
private string _referenceNumber;
public string ReferenceNumber {
get { return _referenceNumber; }
set { _referenceNumber = value; }
}
...
class OrderItem {
private int _itemEntityId;
public int ItemEntityId {
get { return _itemEntityId; }
set { _itemEntityId; }
}
....
}
}
You can use the SerializeObject method of JSON.net
string json = JsonConvert.SerializeObject(new OrderModel {
ReferenceNumber = "Testing OAKLAND",
CustomerNotes = "Testing",
DeliveryDate = DateTime.Now,
OrderLineItems = new List<OrderItem>() {
new OrderItem { ItemEntityId = 14771, Quantity = 2 }
}
});
I know this seems like more code, but believe me it will save you a lot of hassle in the future and for any other developers looking at your code.
Related
I'm working on project in which I'm Posting data from asp.net webform to WCF service. I'm posting data through params and the service respond me back a JSON string. Now I have an issue in deserialize. I read many threads but didn't find any solution. Hope someone can sort out my problem. Thanks in Advance
Response from WCF
{"LoginResult":false}
I just want "false" value.
How I tried:
string URL = "http://localhost:32319/ServiceEmployeeLogin.svc";
WebRequest wrGETURL;
wrGETURL = WebRequest.Create(URL+"/"+emp_username+"/"+emp_password+"/"+emp_type);
wrGETURL.Method = "POST";
wrGETURL.ContentType = #"application/json; charset=utf-8";
HttpWebResponse webresponse = wrGETURL.GetResponse() as HttpWebResponse;
Encoding enc = System.Text.Encoding.GetEncoding("utf-8");
// read response stream from response object
StreamReader loResponseStream = new StreamReader(webresponse.GetResponseStream(), enc);
// read string from stream data
strResult = loResponseStream.ReadToEnd();
var jObj = JObject.Parse(strResult);
var dict = jObj["LoginResult"].Children().Cast<JProperty>();
You could use json.net to do it like this:
public class AuthResponse {
public bool LoginResult { get; set; }
}
var deserializedResponse = JsonConvert.DeserializeObject<AuthResponse>(strResult);
http://james.newtonking.com/json
.Net 4.5 has a JavaScriptSerializer, which should work as well:
public class AuthResponse {
public bool LoginResult { get; set; }
}
System.Web.Script.Serialization.JavaScriptSerializer sr = new System.Web.Script.Serialization.JavaScriptSerializer();
AuthResponse response = sr.Deserialize<AuthResponse>(responseText);
http://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer%28v=vs.110%29.aspx
Having a simple C# unit test:
[TestMethod]
public void JsonPostTest()
{
string testUri1 = "http://localhost:1293/Test/StreamDebug";
string testUri2 = "http://localhost:1293/Test/StreamDebug2?someParameter=abc";
string sampleJson = #"
{
""ID"": 663941764,
""MessageID"": ""067eb623-7580-4d82-bb5c-f5d7dfa69b1e""
}";
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(testUri1);
EmailConfig config = GetTestConfigLive();
// Add postmark headers
request.Accept = "application/json";
request.ContentType = "application/json";
request.Method = "POST";
using (var outStream = new StreamWriter(request.GetRequestStream()))
{
outStream.Write(sampleJson);
}
// Get response
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
string resultText = "";
using (var reader = new StreamReader(response.GetResponseStream()))
{
resultText = reader.ReadToEnd();
}
Assert.Inconclusive();
}
And a simple set of MVC actions to consume and echo posted data back to the unit test (Notice that the code in both actions is identical):
[HttpPost]
[ValidateInput(false)]
public ActionResult StreamDebug()
{
string postbody = "";
using (StreamReader reader = new StreamReader(Request.InputStream, Encoding.UTF8))
{
postbody = reader.ReadToEnd();
}
return this.Content(postbody);
}
[HttpPost]
[ValidateInput(false)]
public ActionResult StreamDebug2(string someParameter)
{
string postbody = "";
using (StreamReader reader = new StreamReader(Request.InputStream, Encoding.UTF8))
{
postbody = reader.ReadToEnd();
}
return this.Content(postbody);
}
If I post to the first action I get a string containing the posted json, if I post to the second action I get an empty string.
To make matters more interesting, if I change the content type in the unit test to "text/plain", both actions return the expected values.
Can anyone shed any light on why this might be happening?
Its also worth noting that the request length on the both actions under both sets of circumstances seems to be of the right length.
Further environmental information:
Unit test is in a separate MS test project.
Actions are in a empty MVC 4.0 project (Net 4.0).
It is possible that somewhere in the request pipeline Request.InputStream was already read. In this case its position is already at the end, and of course ReadToEnd reads nothing and returns empty string. This is the root of the problem in our case. Resetting the position fixes the problem:
[HttpPost]
[ValidateInput(false)]
public ActionResult StreamDebug2(string someParameter)
{
string postbody = "";
Request.InputStream.Position = 0;
using (StreamReader reader = new StreamReader(Request.InputStream, Encoding.UTF8))
{
postbody = reader.ReadToEnd();
}
return this.Content(postbody);
}
Update. After a little bit of digging into sources I also found why the position was shifted. It turns out that Request.InputStream is used in JsonValueProviderFactory in the following manner:
// System.Web.Mvc.JsonValueProviderFactory
private static object GetDeserializedObject(ControllerContext controllerContext)
{
if (!controllerContext.HttpContext.Request.ContentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase))
{
return null;
}
StreamReader streamReader = new StreamReader(controllerContext.HttpContext.Request.InputStream);
string text = streamReader.ReadToEnd();
if (string.IsNullOrEmpty(text))
{
return null;
}
JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer();
return javaScriptSerializer.DeserializeObject(text);
}
This method is called by ControllerActionInvoker to retrieve values from request and bind them to action parameters. Note that this is the only place where Request.InputStream is used through all the MVC.
Therefore if content type of the request is json, the method above is called, input stream gets shifted and attempt to read it yet again without resetting the position fails. However when content type is a plain text, MVC does not try to read the request using json deserialization, input stream is not read before the call in controller and everything works as expected.
I created a Rest Webservice with ASP.NET MVC 4 Web Application. If I want to consume the service and send a request including a requestbody the input parameter CoreMessage item is always null. I watched some sample tutorials and some sample code but I couldn't fix the bug.
Some code of my Rest Client
CoreMessage message = new CoreMessage() { Source = "Dummy", Date = DateTime.Now, Data = "abcd" };
var url = "http://localhost:12294/api/message";
var method = "POST";
string reponseAsString = "";
try
{
var request = (HttpWebRequest)WebRequest.Create(url);
request.Method = method;
using (Stream requestStream = request.GetRequestStream())
using (StreamWriter writer = new StreamWriter(requestStream))
{
writer.Write(message);
}
}
catch (Exception ex)
{
reponseAsString += "ERROR: " + ex.Message;
}
My Controller with the Post function look like this
public MessageRepository repository = new MessageRepository();
public HttpResponseMessage PostMessage(CoreMessage item)
{
bool status = repository.TransmitMessage(item);
var response = Request.CreateResponse<bool>(HttpStatusCode.Created, status);
return response;
}
My Model
public class CoreMessage
{
public string Source { get; set; }
public DateTime Date { get; set; }
public string Data { get; set; }
}
There are few things to try
First, put [FromBody] attribute:
public HttpResponseMessage PostMessage([FromBody] CoreMessage item)
Then try to add Content-Type header to your request
request.ContentType = "application/json; chatset=utf-8"
And you have to make it JSON before writing to stream, you cannot write the object out like that. The method depends on what framework you use for JSON serialisation. One of the most popular one is JSON.NET, which is dead easy to install through NuGet package manager. Once you got it installed you can serialise your CoreMessage to string like:
string messageString = JSONConvert.SerializeObject(message);
Then writing it in UTF-8 encoding:
using (StreamWriter writer = new StreamWriter(requestStream, Encoding.UTF8))
{
writer.Write(messageString);
}
After all, if it's still not working, you can try Dev HTTP Client in Chrome. The tool will allow you to craft raw HTTP request. Your request should have Content-Type as application/json; charset=utf-8 and POST data as JSON string.
I'm having trouble understanding how to parse JSON string into c# objects with Visual .NET. The task is very easy, but I'm still lost...
I get this string:
{"single_token":"842269070","username":"example123","version":1.1}
And this is the code where I try to desterilize:
namespace _SampleProject
{
public partial class Downloader : Form
{
public Downloader(string url, bool showTags = false)
{
InitializeComponent();
WebClient client = new WebClient();
string jsonURL = "http://localhost/jev";
source = client.DownloadString(jsonURL);
richTextBox1.Text = source;
JavaScriptSerializer parser = new JavaScriptSerializer();
parser.Deserialize<???>(source);
}
I don't know what to put between the '<' and '>', and from what I've read online I have to create a new class for it..? Also, how do I get the output?
An example would be helpful!
Create a new class that your JSON can be deserialized into such as:
public class UserInfo
{
public string single_token { get; set; }
public string username { get; set; }
public string version { get; set; }
}
public partial class Downloader : Form
{
public Downloader(string url, bool showTags = false)
{
InitializeComponent();
WebClient client = new WebClient();
string jsonURL = "http://localhost/jev";
source = client.DownloadString(jsonURL);
richTextBox1.Text = source;
JavaScriptSerializer parser = new JavaScriptSerializer();
var info = parser.Deserialize<UserInfo>(source);
// use deserialized info object
}
}
If you're using .NET 4 - use the dynamic datatype.
http://msdn.microsoft.com/en-us/library/dd264736.aspx
string json = "{ single_token:'842269070', username: 'example123', version:1.1}";
JavaScriptSerializer jss = new JavaScriptSerializer();
dynamic obj = jss.Deserialize<dynamic>(json);
Response.Write(obj["single_token"]);
Response.Write(obj["username"]);
Response.Write(obj["version"]);
Yes, you need a new class with properties that will match your JSON.
MyNewClass result = parser.Deserialize<MyNewClass>(source);
The usual way would be create a class (or a set of classes, for more complex JSON strings) that describes the object you want to deserialize and use that as the generic parameter.
Another option is to deserialize the JSON into a Dictionary<string, object>:
parser.Deserialize<Dictionary<string, object>>(source);
This way, you can access the data, but I wouldn't suggest you to do this unless you have to.
You need a Class that match with the JSON you are getting and it will return a new object of that class with the values populated.
Following is the code..
ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(AcceptAllCertifications);
request = WebRequest.Create("https://myipaddress/api/admin/configuration/v1/conference/1/");
request.Credentials = new NetworkCredential("admin", "admin123");
// Create POST data and convert it to a byte array.
request.Method = "GET";
// Set the ContentType property of the WebRequest.
request.ContentType = "application/json; charset=utf-8";
WebResponse response = request.GetResponse();
// Display the status.
Console.WriteLine(((HttpWebResponse)response).StatusDescription);
// Get the stream containing content returned by the server.
dataStream = response.GetResponseStream();
// Open the stream using a StreamReader for easy access.
StreamReader reader = new StreamReader(dataStream);
// Read the content.
string responseFromServer = reader.ReadToEnd();
JavaScriptSerializer js = new JavaScriptSerializer();
var obj = js.Deserialize<dynamic>(responseFromServer);
Label1.Text = obj["name"];
// Display the content.
Console.WriteLine(responseFromServer);
// Clean up the streams.
reader.Close();
dataStream.Close();
response.Close();
dynamic data = JObject.Parse(jsString);
var value= data["value"];
I would like to use the search method of stackoverflow API to return the json structure of results based on a search keyword and then display those results (title, description and the url) in the SearchResults div.
I am new to C# and my first attempt went something like this:
protected void searchStockOverflow(string y)
{
var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://api.stackoverflow.com/1.1/search?intitle="+y);
httpWebRequest.ContentType = "text/json";
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = "{ \"intitle\": \"" + y + "\"}";
streamWriter.Write(json);
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var responseText = streamReader.ReadToEnd();
SearchResults.InnerHtml += "<div style='border:1px solid blue;margin:5px;'>";
SearchResults.InnerHtml += responseText + "<br />";
SearchResults.InnerHtml += "</div><br style='clear:both;' />";
}
}
The issue is that what is returned looks like dingbats rubbish - i guess because it is serialized and need to be deserialized?
I would definitely say consider using the REST client; however, to look at the issues... generally you want to deserialize the data as JSON manually, then run that data through your UI code. For example:
static void SearchStackOverflow(string y)
{
var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://api.stackoverflow.com/1.1/search?intitle=" + Uri.EscapeDataString(y));
httpWebRequest.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;
httpWebRequest.Method = "GET";
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
string responseText;
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
responseText = streamReader.ReadToEnd();
}
var result = (SearchResult)new JavaScriptSerializer().Deserialize(responseText, typeof(SearchResult));
.... do something with result ...
}
class SearchResult
{
public List<Question> questions { get; set; }
}
class Question
{
public string title { get; set; }
public int answer_count { get; set; }
}
Which uses the JavaScriptSerializer from System.Web.Extensions.dll
Also Take a look at Stacky StackApps .Net Client Library which is REST-based API that provides access to stackoverflow family of websites.
Unfortunately I'm on my Mac and can't run a test on your code. You might want to check the character encoding of both your page and the response stream coming back. If they don't match; it could cause the characters coming from the response stream to be rendered incorrectly, hence the rubbish you're seeing.