How to receive incoming json data posted from outside - asp.net-mvc

I want to receive json formatted posted data to my controller. Actually it's used for paypal payment webhook call issue. I already attached a json data example. Please advice me "FormCollection" is good idea to access that json or whats the best practice for this situation?
Json:
{"menu": {
"id": "file",
"value": "File",
"popup": {
"menuitem": [
{"value": "New", "onclick": "CreateNewDoc()"},
{"value": "Open", "onclick": "OpenDoc()"},
{"value": "Close", "onclick": "CloseDoc()"}
]
}
}}
Controller:
[HttpPost]
public JsonResult ReceiveData(FormCollection data)
{
using (var ctx = new db_mydb())
{
}
return Json("ok");
}

Since that data being received is structured and comming in as JSON you should create strongly typed model(s) to store the data.
public class Menuitem {
public string value { get; set; }
public string onclick { get; set; }
}
public class Popup {
public IList<Menuitem> menuitem { get; set; }
}
public class Menu {
public string id { get; set; }
public string value { get; set; }
public Popup popup { get; set; }
}
public class PaypalWebhookModel {
public Menu menu { get; set; }
}
Action should be updated to reflect the desired model.
[HttpPost]
public JsonResult ReceiveData([FromBody]PaypalWebhookModel data) {
using (var ctx = new db_mydb()) {
//...
}
return Json("ok");
}

Related

How can I return API Messages in ASP.NET MVC?

I have some message in the API response. I want to return the message to user. I cannot find how can I do it.
Sample Controller
[HttpGet]
public async Task<IActionResult> ListCountries()
{
List<Country> countries = new List<Country>();
var response = await _client.GetAsync("countries/getall");
if (response.IsSuccessStatusCode)
{
string apiResponse = await response.Content.ReadAsStringAsync();
var JsonData = JsonConvert.DeserializeObject<JsonCountryData>(apiResponse);
countries = JsonData.Data;
}
return View(countries);
}
Country Model
namespace EVisaProject.Models
{
public class CountryModel
{
public int Id { get; set; }
public string CountryName { get; set; }
}
public class JsonCountryData
{
public List<CountryModel> Data { get; set; }
}
}
API
Because you're not de-serializing the property. Look at the object you're de-serializing the JSON data into:
public class JsonCountryData
{
public List<CountryModel> Data { get; set; }
}
Notice that it contains a property called Data. Which is why you can access the Data property. You can't access the Success or Message properties because you haven't added them to the model, so they don't exist.
In order to use them, add them to the model so they exist:
public class JsonCountryData
{
public List<CountryModel> Data { get; set; }
public bool Success { get; set; }
public string Message { get; set; }
}
Once they exist, you'll be able to use them:
var JsonData = JsonConvert.DeserializeObject<JsonCountryData>(apiResponse);
// after here you can access the "Success" and "Message" properties on the "JsonData" object
There's nothing special about the "message" property in the JSON response. You would access it exactly the same way that you already access the "data" property.

Ms Graph : How to Defer Commit of a file with the SDK?

I would like to defer the file commit's when i use the SDK upload session.
This is possible with the API : https://learn.microsoft.com/en-us/graph/api/driveitem-createuploadsession?view=graph-rest-1.0
{
"item": {
"#microsoft.graph.conflictBehavior": "rename"
},
"deferCommit": true
}
But in the SDK : https://learn.microsoft.com/en-us/graph/sdks/large-file-upload?tabs=csharp
I couldn't find the equivalent in DriveItemUploadableProperties object
public class DriveItemUploadableProperties
{
public DriveItemUploadableProperties();
public string Description { get; set; }
public long? FileSize { get; set; }
public FileSystemInfo FileSystemInfo { get; set; }
public string Name { get; set; }
public IDictionary<string, object> AdditionalData { get; set; }
public string ODataType { get; set; }
}
How do i send the deferCommit flag and how do i send the completing flag ?
Edit 1 :
I've try :
DriveItemUploadableProperties properties = new DriveItemUploadableProperties
{
ODataType = null,
AdditionalData = new Dictionary<string, object>
{
{ "#microsoft.graph.conflictBehavior", "replace" },
{"deferCommit", true}
}
};
but it doesn't work
The deferCommit property isn't a member of the driveItemUploadableProperties class. This property should be set as part of the AdditionalData of DriveItemUploadableProperties. Please see documentation on completing a file for details on how to explicitly complete the upload.
This might look something like this:
AdditionalData = new Dictionary<string, object>
{
{ "#microsoft.graph.conflictBehavior", "replace" },
{"deferCommit", true}
},
Let me know whether this helps and if you have further questions.

WebApi receive parameters including dynamic list using FromBody

I am trying to receive the below JSON format in webapi
{
"name": "Matt",
"age": "24",
"payload": {"key1": "value1", "key2": "value2"}
}
here the payload is dynamic and it can have any key and value.
My webapi looks like
public class Person
{
public string name{ get; set; }
public int age{ get; set; }
public string payload { get; set; }
}
public async Task<HttpResponseMessage> Post([FromBody]Person value)
{
// Getting name and age but not payload.
}
Questions
Is FromBody the way to get this values? If yes, what i am missing here. If no, what is the best practice for these kind of inputs?
Yes [FromBody] should be used. You can use an IDictionary<string,string> for payload.
public class Person
{
public string name{ get; set; }
public int age{ get; set; }
public IDictionary<string,string> payload { get; set; }
}
public async Task<HttpResponseMessage> Post([FromBody]Person value)
{
var value1 = value.payload["key1"];
var value2 = value.payload["key2"];
}

Append to a Json object in MVC controller in ASP.NET before sending data to the View

I am building an MVC application in ASP.NET. In my Index Controller I am calling an API, get the data and pass them to the view.
This works well and I have no problem getting data back in my View.
public ActionResult Index()
{
Base model = null;
var client = new HttpClient();
var task =
client.GetAsync(
"http://example.api.com/users/john/profile")
.ContinueWith((taskwithresponse) =>
{
var response = taskwithresponse.Result;
var readtask = response.Content.ReadAsAsync<Base>();
readtask.Wait();
model = readtask.Result;
});
task.Wait();
return View(model);
}
My Model is following:
public class Base
{
public Data data { get; set; }
}
public class Data
{
public Profile profile { get; set; }
public Credit credit { get; set; }
}
public class Profile
{
public String firstname { get; set; }
public String lastname { get; set; }
}
public class Credit
{
public int amount { get; set; }
public string balance { get; set; }
}
The API returns data in this format:
{
"data": {
"profile": {
"firstname": "John,
"lastname": "Newman",
},
"credit": {
"amount": 30,
"neverbought" : false
}
}
}
What I want to achieve now, is to add some more properties to the returned data. For example I want to add a state property to credit, which will be calculated according to amount and neverbought properties.
But for now let's say the credit.state will always be "lowCredit".
So what I did, was to add Credit.state = "neverBought"; to my Controller before sending data to the View. Then I got some errors that my Credit class does not contain a definition for state.
I added state property to my Credit Model, but then I got "An object reference is required for the non-static field, method or property.
Here is the code I used:
task.Wait();
model.credit.state = "lowCredit";
return View(model);
What am I doing wrong and what should I do to solve the problem?
It would be nice if you showed what code you used to throw the stated error. But I am going to assume that you probably did it before your async task completed. As long as you have the field available in your model
public class Credit
{
public int amount { get; set; }
public string state { get; set; }
public string balance { get; set; }
}
then you should be able to just set it (wait until the async finishes)
task.Wait();
model.data.credit.state = "lowCredit";
return View(model);
attempting to assign this value before the task has finished would be like trying to assign a value to null and will cause a runtime exception.

Deserialize Json likes from friends of facebook asp.net mvc

i need to deserialize a json string from facebook that i get from the graph:
{
"id": "1741240583",
"music": {
"data": [
{
"name": "KMN | Kill My Name",
"id": "168949476496447",
"created_time": "2013-05-01T07:30:54+0000"
},
{
"name": "Hocus Pocus",
"id": "174462922710692",
"created_time": "2013-04-16T17:55:46+0000"
}
]
}
}
the way i have did is like this:
public class Result
{
public Music music { get; set; }
}
public class Music
{
public Data[] data { get; set; }
}
public class Data
{
public string[] name { get; set; }
}
protected void Button1_Click(object sender, EventArgs e)
{
string teste = "{\"id\": \"723560709\",\"music\": {\"data\": [{\"name\": \"LOKO ( Life Opium Kill over )\",\"id\": \"129518483779162\",\"created_time\": \"2013-05-07T02:54:39+0000\"},],}}";
Result soap = JsonConvert.DeserializeObject<Result>(teste);
but it returns this error:
Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'GuiaDePresentes.Buscape.Buscape_Controle+Data' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.
To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List<T> that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.
Path 'music.data', line 1, position 38.
how can i make this thing work?
PS:yeah, i am a newbie in programming :D
I believe your JSON test string is not formed correctly, I have checked it on http://jsonlint.com/ and it proves invalid.
Now, I recently had big issues working with JSON but this website helped me a lot
http://encosia.com/asp-net-web-services-mistake-manual-json-serialization/
Hope it helps :)
TEST EXAMPLE
using System.Web.Script.Serialization;
public class Datum
{
public string name { get; set; }
public string id { get; set; }
public string created_time { get; set; }
}
public class Paging
{
public string next { get; set; }
}
public class Music
{
public List<Datum> data { get; set; }
public Paging paging { get; set; }
}
public class RootObject
{
public string id { get; set; }
public Music music { get; set; }
}
protected void Page_Load(object sender, EventArgs e)
{
WebClient wc = new WebClient();
JavaScriptSerializer json = new JavaScriptSerializer();
string _token = "BAACEdEose0cBAE8U2tleN51ZBd8g8nBsUPVinB0dYFC2WfsGmbp2x8Vl6ZAynV81IXdZB0PkZCfFscjGjLvg8zSj1FMSi6E7al5sMLUDpZA5ZCR3rWJJjdUYxx3sdLUIaq1BJ8hGjrKPyVW6pEtp96mDmwF2vLnrivcrofvQLO4YNEqpj23Rb5gv7GwRYSbVnplKsg0dHAGS79iAp4ZBZAarwuVpSbNfZBcwZD";
string _url = "https://graph.facebook.com/YOURID?fields=music.fields(name)&access_token=" + _token;
string _json = wc.DownloadString(_url);
RootObject jsonObject= json.Deserialize<RootObject>(_json);
Response.Write(jsonObject.music.data.First().name);
Response.Write(_json);
}
Once you have your jsonObject you can use LINQ to access all the properties and all the data and you can convert it into a Result if you want too.
You can use this website to create you classes from JSON http://json2csharp.com/

Resources