ASP.NET MVC Model binding not parsing - json

I am having some problems getting my ASP.NET MVC application to parse my model, i simply just get "null".
This is my ASP.NET MVC action
public AdobeReturnSet<UserModel> Post([FromBody]UserModel model)
I have also tried without the [FromBody], that did not help.
This is my model
public class UserModel
{
public int AdobeId { get; set; }
[Required]
[StringLength(500)]
public string FristName { get; set; }
[Required]
[StringLength(500)]
public string LastName { get; set; }
[Required]
[StringLength(250)]
[EmailAddress]
public string Email { get; set; }
[Required]
public string OrganizationIdentification { get; set; }
public string Organization { get; set; }
public string OrganizationFull { get; set; }
}
And this is how i send the request
using (WebClient wc = new WebClient())
{
wc.Headers[HttpRequestHeader.Accept] = "application/json";
wc.Headers[HttpRequestHeader.AcceptCharset] = "utf-8";
wc.Headers[HttpRequestHeader.ContentType] = "application/json";
result = wc.UploadString(url, "POST", data);
}
The url is correct as the correct action is reached and this is the value of data:
{"AdobeId":0,"FristName":"Kasper Rune","LastName":"Søgaard","Email":"krus#arcanic.dk","OrganizationIdentification":null,"Organization":null,"OrganizationFull":null}
But when the request reaches my action is the model simply null.
It is a ApiController if that changes anything.

Looks like an encoding problem. Try using the UploadData method instead and use UTF-8 encoding:
using (var wc = new WebClient())
{
var data = Encoding.UTF8.GetBytes(#"{""AdobeId"":0,""FristName"":""Kasper Rune"",""LastName"":""Søgaard"",""Email"":""krus#arcanic.dk"",""OrganizationIdentification"":null,""Organization"":null,""OrganizationFull"":null}");
wc.Headers[HttpRequestHeader.Accept] = "application/json";
wc.Headers[HttpRequestHeader.ContentType] = "application/json";
byte[] result = wc.UploadData(url, "POST", data);
string json = Encoding.UTF8.GetString(result);
}
Alternatively you could use the new HttpClient:
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.ConnectionClose = true;
var value = new
{
AdobeId = 0,
FristName = "Kasper Rune",
LastName = "Søgaard",
Email = "krus#arcanic.dk",
};
var result = client.PostAsJsonAsync(url, value).Result;
if (result.IsSuccessStatusCode)
{
string json = result.Content.ReadAsStringAsync().Result;
}
}
Also you might have a typo at FristName which should probably be FirstName.

Related

RestSharp query returning NotFound

This is my first usage of RestSharp
I am trying to connect to HubSpot using their FormsAPI (https://legacydocs.hubspot.com/docs/methods/forms/submit_form)
Using .Net, C#, MVC.
When I run in Fiddler, it works.
Here is my C# code, when I run it, I get a StatusCode of "NotFound". I am sure it is something simple I am missing?
var client = new RestClient("https://api.hsforms.com");
var request = new RestRequest("submissions/v3/integration/submit/{PortalId}/{formGuid}", Method.POST);
request.AddUrlSegment("portalId", "[myportalid]");
request.AddUrlSegment("formGuid", "[myformid]");
request.AddQueryParameter("hapikey", "[myapikey]");
request.RequestFormat = DataFormat.Json;
request.AddParameter("firstname", "testfirstname");
request.AddParameter("lastname", "testlastname");
request.AddParameter("email", "testemail#emailaddress.com");
request.AddParameter("business_unit", "Test");
It is better to create model of c# class and serialize it to Json and send POST request.
Example of RestSharp request
public async Task SendHubSpotRequest()
{
var PortalId = 1;
var formGuid = 1;
var client = new RestClient("https://api.hsforms.com");
var request = new RestRequest($"submissions/v3/integration/submit/{PortalId}/{formGuid}", Method.POST);
var hubSpotRequest = new HubSpotRequest()
{
SubmittedAt = "1517927174000",
Fields = new Field[]
{
new Field() { Name = "email", Value = "testemail#emailaddress.com" },
new Field() { Name = "firstname", Value = "testfirstname" },
new Field() { Name = "lastname", Value = "testlastname" }
},
Context = new Context
{
Hutk = "hutk",
PageUri = "www.example.com/page",
PageName = "Example page"
},
LegalConsentOptions = new LegalConsentOptions
{
Consent = new Consent
{
// Fill other params
}
}
};
request.AddParameter("application/json; charset=utf-8", JsonConvert.SerializeObject(hubSpotRequest), ParameterType.RequestBody);
var response = await client.ExecuteAsync(request);
var responseContent = response.Content;
}
C# classes of body json model
public class HubSpotRequest
{
[JsonProperty("submittedAt")]
public string SubmittedAt { get; set; }
[JsonProperty("fields")]
public Field[] Fields { get; set; }
[JsonProperty("context")]
public Context Context { get; set; }
[JsonProperty("legalConsentOptions")]
public LegalConsentOptions LegalConsentOptions { get; set; }
}
public class Context
{
[JsonProperty("hutk")]
public string Hutk { get; set; }
[JsonProperty("pageUri")]
public string PageUri { get; set; }
[JsonProperty("pageName")]
public string PageName { get; set; }
}
public class Field
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("value")]
public string Value { get; set; }
}
public class LegalConsentOptions
{
[JsonProperty("consent")]
public Consent Consent { get; set; }
}
public class Consent
{
[JsonProperty("consentToProcess")]
public bool ConsentToProcess { get; set; }
[JsonProperty("text")]
public string Text { get; set; }
[JsonProperty("communications")]
public Communication[] Communications { get; set; }
}
public class Communication
{
[JsonProperty("value")]
public bool Value { get; set; }
[JsonProperty("subscriptionTypeId")]
public long SubscriptionTypeId { get; set; }
[JsonProperty("text")]
public string Text { get; set; }
}

Make request for Element Of Statistical Learning Dataset in Json format (C#)

Please I want to make request for this dataset https://web.stanford.edu/~hastie/ElemStatLearn/datasets/prostate.data and get it in json format.
But when I run it, I get this error "Unexpected character encountered while parsing value: l. Path '', line 1, position 1.". Below is the code I wrote using C#
public class Prostate
{
public string lcavol { get; set; }
public string lweight { get; set; }
public string age { get; set; }
public string lbph { get; set; }
public string svi { get; set; }
public string lcp { get; set; }
public string gleason { get; set; }
public string pgg45 { get; set; }
public string lpsa { get; set; }
public string train { get; set; }
}
public async Task<Prostate> Data()
{
HttpClient client = new HttpClient();
var resp = await client.GetAsync("https://web.stanford.edu/~hastie/ElemStatLearn/datasets/prostate.data");
var repsStr = await resp.Content.ReadAsStringAsync();
var newdata = JsonConvert.DeserializeObject(repsStr);
Prostate somedata = (Prostate) newdata;
return somedata;
}
I saved the file as txt and opened it in excel. I later saved it as csv then read it using this code
public async Task<List<Prostate>> Files()
{
List<Prostate> prostates = new List<Prostate>();
var file = Path.Combine(Directory.GetCurrentDirectory(), "[path to file]");
string[] linesofdata = await System.IO.File.ReadAllLinesAsync(file);
foreach(string line in linesofdata){
string[] linewords = line.Split(',');
Prostate newprostate = new Prostate();
newprostate.lcavol = linewords[0];
newprostate.lweight = linewords[1];
newprostate.age = linewords[2];
newprostate.lbph = linewords[3];
newprostate.svi = linewords[4];
newprostate.lcp = linewords[5];
newprostate.gleason = linewords[6];
newprostate.pgg45 = linewords[7];
newprostate.lpsa = linewords[8];
newprostate.train = linewords[9];
prostates.Add(newprostate);
}
return prostates.ToList();
}

Azure route not forwarded to endpoint after filtering query

I am starting to use Azure IoT hub and I configured my endpoints and servicehub to learn from it with a route.
In this route I specify that when a message says level = critical that it forwards the message to my endpoint like explained in the following link: https://learn.microsoft.com/en-us/azure/iot-hub/iot-hub-csharp-csharp-process-d2c
The difference is that I use my own code for my temperature sensor with a programmed DTO and that I send it as one big json message (see code)
DTO class:
[DataContract]
class Bmp280DTO
{
[DataMember]
public Guid guid { get; set; }
[DataMember]
public string deviceName { get; set; }
[DataMember]
public float tempSensorValue { get; set; }
[DataMember]
public float pressureSensorValue { get; set; }
[DataMember]
public float altitudeSensorValue { get; set; }
[DataMember]
public DateTime measurementTime { get; set; }
[DataMember]
public string measurename { get; set; }
[DataMember]
public string level { get; set; }
public Bmp280DTO() { }
public Bmp280DTO(Guid id, String Device, float TmpSensorValue, float PrSensorValue, float AlSensorValue)
{
this.guid = id;
this.deviceName = Device;
this.tempSensorValue = TmpSensorValue;
this.pressureSensorValue = PrSensorValue;
this.altitudeSensorValue = AlSensorValue;
this.measurementTime = DateTime.Now;
this.measurename = "LightSensor";
this.level = DetermineMessageLevel(TmpSensorValue);
}
public string ToJson()
{
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Bmp280DTO));
MemoryStream ms = new MemoryStream();
ser.WriteObject(ms, this);
string json = Encoding.UTF8.GetString(ms.ToArray(), 0, (int)ms.Length);
return json;
}
public string DetermineMessageLevel(float temperaturesensorvalue)
{
if(temperaturesensorvalue > 22)
{
return "critical";
}
return "normal";
}
}
Message send:
private void SendBmp280Data(Bmp280DTO AzureBmp280Data)
{
System.Text.StringBuilder Bmp280JsonMessage = new System.Text.StringBuilder();
Bmp280JsonMessage.Append(AzureBmp280Data.ToJson());
MessageCommands.SendMessage(Bmp280JsonMessage.ToString());
}
Examples of message:
{"guid":"xxxx","deviceName":"Bmp280Sensor","tempSensorValue":23.59763,"pressureSensorValue":98792.11,"altitudeSensorValue":213.046539,"measurementTime":"2017-02-23T05:34:00.4544388-08:00","measurename":"LightSensor","level":"critical"}
The message is received in the IOT hub but not forwarded to the endpoint.
What am I doing wrong? Are you not able to query json object messages? And if that's the case how do you do it then? I don't want to send unnecessary messages.
It seems that this was a problem with the encoding while sending the message.
I encoded the message in UTF8 while it needed to be done in ASCII value's.
I also could add message-properties to make it more obvious.
So as following:
var messageString = JsonConvert.SerializeObject(AzureBmp280Data);
Debug.WriteLine("Message Sent: {0}", messageString, null);
var message = new Message(Encoding.ASCII.GetBytes(messageString));
message.Properties.Add("level", "critical");

How to receive json post data in a Webhook

We are using 3rd party api kraken.io to optimize our images.
The results of optimized image is posted in a Webhook.
In their api document it states: After the optimization is over Kraken will POST a message to the callback_url specified in your request in a JSON format application/json.
I am using ngrok to allow remote webhooks to send data to my development machine, using this article.
Results posted to the Callback URL:
HTTP/1.1 200 OK
{
"id": "18fede37617a787649c3f60b9f1f280d",
"success": true,
"file_name": "header.jpg",
"original_size": 324520,
"kraked_size": 165358,
"saved_bytes": 159162,
"kraked_url": "http://dl.kraken.io/18/fe/de/37617a787649c3f60b9f1f280d/header.jpg"
}
Class to Map
public class KrakenOptimizedResults
{
public string id { get; set; }
public bool success { get; set; }
public string file_name { get; set; }
public int original_size { get; set; }
public int kraked_size { get; set; }
public int saved_bytes { get; set; }
public string kraked_url { get; set; }
}
Action Method
[HttpPost]
public ActionResult OptimizedWebHook()
{
Request.InputStream.Position = 0;
string jsonString = new System.IO.StreamReader(Request.InputStream).ReadToEnd();
KrakenOptimizedResults obj = new JavaScriptSerializer().Deserialize<KrakenOptimizedResults>
(jsonString);
return Json(obj);
}
But When I debug the received jsonString in Html Visualizer it looks like key and value pairs instead of Json format.
Received Results not Json Formatted:
file_name=header.jpeg&original_size=118066&kraked_size=102459&saved_bytes=15607
I guess the received data content-type: is application/x-www-form-urlencoded.
Why i am receiving key and value pairs instead of Json format ? how can I deserialize Json data in asp.net mvc ?
Co-founder of https://kraken.io here.
There is a glaring omission in our documentation which I will fix today. To get JSON back, you need to set a "json": true flag in the request. Omitting that flag or setting "json": false will return URLEncoded. Example cURL request:
curl http://api.kraken.io/v1/upload -X POST --form data='{"auth":{"api_key":"YOUR_KEY", "api_secret":"YOUR_SECRET"}, "wait": true, "lossy": true, "callback_url": "http://requestb.in/wbhi63wb", "json": true}' --form upload=#test.jpg
Sorry for the inconvenience :-(
I was able to convert Query String Key and Value pairs to Json Format using this and this post ,there is some delay to convert form Dictionary to Json, so If there is better answers, then do post and advice, below is my solution.
Action Method
[HttpPost]
public ActionResult OptimizedWebHook()
{
Request.InputStream.Position = 0;
string data = new System.IO.StreamReader(Request.InputStream).ReadToEnd();
var dict = HttpUtility.ParseQueryString(data);
var json = new JavaScriptSerializer().Serialize(dict.AllKeys.ToDictionary(k => k, k =>
dict[k]));
KrakenOptimizedResults obj = new JavaScriptSerializer().Deserialize<KrakenOptimizedResults>
(json);
return Json(obj);
}
Recieving JSON formated optimized results from kraken API.
As mentioned by #karim79, To get JSON back, you need to set a "json": true flag in the request.
As Kraken .Net/C# SDK didn't have option to set "json": true, so i have to extend their base class.
Extended Base Class:
public class OptimizeRequestBaseExtended : OptimizeRequestBase,
IOptimizeUploadRequest, IRequest
{
public OptimizeRequestBaseExtended(Uri callbackUrl)
{
CallbackUrl = callbackUrl;
}
[JsonProperty("callback_url")]
public Uri CallbackUrl { get; set; }
[JsonProperty("json")]
public bool JsonFormat { get; set; }
}
Request Kraken API:
var callbackUrl = new Uri("http://localhost:0000/Home/OptimizedWebHook");
OptimizeRequestBaseExtended settings = new OptimizeRequestBaseExtended(callbackUrl);
settings.Lossy = true;
settings.JsonFormat = true;
var response = client.Optimize(image: image, filename: filename, optimizeRequest: settings);
Action Method
[HttpPost]
public ActionResult OptimizedWebHook()
{
Request.InputStream.Position = 0;
string jsonString = new System.IO.StreamReader(Request.InputStream).ReadToEnd();
KrakenOptimizedResults obj = JsonConvert.DeserializeObject<KrakenOptimizedResults>
(jsonString);
return Json(obj);
}
Step 1:
Create an aspx page. This page must be able to accept HTTP POST request.
Step 2:
Add this code to get HTTP POST data.File: default.aspx.cs
File: default.aspx.cs
var reader = new StreamReader(Request.InputStream);
var json = reader.ReadToEnd();
FileStream ostrm;
StreamWriter writer;
TextWriter oldOut = Console.Out;
ostrm = new FileStream(#"C:\logfile4webhook.txt", FileMode.Append, FileAccess.Write);
writer = new StreamWriter(ostrm);
Console.SetOut(writer);
Console.Write(DateTime.Now + " ");
Console.WriteLine(json.ToString() + " ");
Console.SetOut(oldOut);
writer.Close();
ostrm.Close();
Step 3:
Create webhook. This code can be linked to a button on click event.File:default.aspx.cs
AuthenticationDetails auth = new ApiKeyAuthenticationDetails("your api key");
string listID = "";
listID = "your list id";
List list = new List(auth, listID);
List<string> events = new List<string>();
events.Add("Update");
string postback = list.CreateWebhook(events, "URL", "json");
FileStream ostrm;
StreamWriter writer;
TextWriter oldOut = Console.Out;
ostrm = new FileStream(#"C:\logfile4webhook.txt", FileMode.Append, FileAccess.Write);
writer = new StreamWriter(ostrm);
Console.SetOut(writer);
Console.Write(DateTime.Now + " ");
Console.WriteLine(postback + " ");
Console.SetOut(oldOut);
writer.Close();
ostrm.Close();
Step 4:
Activate webhook. Copy that webhook id from the text file and past it to the code below.
File:default.aspx.cs
AuthenticationDetails auth = new ApiKeyAuthenticationDetails("your api key");
string listID = "";
listID = "your list id";
List list = new List(auth, listID);
list.ActivateWebhook("webhook id");
Step 5:
Test weebhook.File: default.aspx.cs
AuthenticationDetails auth = new ApiKeyAuthenticationDetails("your api key");
string listID = "";
listID = "your list id";
List list = new List(auth, listID);
string postback = list.TestWebhook("webhook id").ToString();
FileStream ostrm;
StreamWriter writer;
TextWriter oldOut = Console.Out;
ostrm = new FileStream(#"C:\logfile4webhook.txt", FileMode.Append, FileAccess.Write);
writer = new StreamWriter(ostrm);
Console.SetOut(writer);
Console.Write(DateTime.Now + " ");
Console.WriteLine(postback + " ");
Console.SetOut(oldOut);
writer.Close();
ostrm.Close();
Step 6:
Deserialize body of JSON object. We need to create class structure based on JSON data. I put sample json here and it created required classes
public class CustomField
{
public string Key { get; set; }
public string Value { get; set; }
}
public class Event
{
public List<CustomField> CustomFields { get; set; }
public string Date { get; set; }
public string EmailAddress { get; set; }
public string Name { get; set; }
public string SignupIPAddress { get; set; }
public string Type { get; set; }
}
public class RootObject
{
public List<Event> Events { get; set; }
public string ListID { get; set; }
}
Once you have created your class, append the code from step 2 after
var json = reader.ReadToEnd();
to deserialize and parse json.
RootObject myClass = JsonConvert.DeserializeObject(json);
if (myClass != null)
{
List<Event> t = myClass.Events;
string old_email = "", new_email = "";
old_email = t[0].OldEmailAddress;
new_email = t[0].EmailAddress;
//now you can do your logic with old_email and new_email
}

ASP.net MVC 3 with web service

I am the new one with the using of web service with ASP.net MVC 3.0. Now I have another member in my team, they develop web service and then they passed the URL to me http://localhost:55274/iServices/Generics/Setting.svc/GetSetting/ , then I received the JSON data
{"ID":1,"MailAccount":"blahbla.com","MailPassword":"password","SMTP":"smtp.test.com","SMTPPort":500,"SSL":false}
Now I am trying to get that JSON to use in the class of my ASP.net MVC 3 to provide the mail system setting. I created two class :
public class iceEmailObject
{
public int ID { set; get; }
public String SMTP { set; get; }
public int SMTPPort { set; get; }
public String MailAccount { set; get; }
public String MailPassword { set; get; }
public bool SSL { set; get; }
}
The second class is to handle send mail :
public class EASEmail : ItemEntityDataContext
{
public bool SendMail(string ReplyTo, string SendTo, string Title, string Body, string From, string AttachmentPath, bool isHtml = false)
{
try
{
SmtpMail oMail = new SmtpMail("blah blah blah");
SmtpClient oSmtp = new EASendMail.SmtpClient();
String fff = From;
if (From == "") fff = ReplyTo;
MailAddress ma = new EASendMail.MailAddress(fff, "");
if (From == "")
{
oMail.ReplyTo = ReplyTo;
oMail.Headers.Add("Reply-To", ReplyTo);
}
oMail.From = ma;
oMail.To = SendTo;
oMail.Subject = Title;
oMail.Priority = MailPriority.High;
if (!isHtml)
oMail.TextBody = Body;
else
oMail.HtmlBody = Body;
iceEmailObject mail = new iceEmailObject();
mail.ID = blahblah; //data from web service here
mail.MailAccount = ""; //data from web service here
return true;
}
catch (Exception ex)
{
return false;
}
}
}
I want to get the JSON to initial the object of the first class such as mail.ID = ....
Could any one tell me how could I do that? Thanks.
Try this
JavaScriptSerializer js = new System.Web.Script.Serialization.JavaScriptSerializer();
iceEmailObject mail = js.Deserialize<iceEmailObject>(json);
where json is your JSON string, and mail is the resulting object