get Facebook Pages in Windows Phone 7 using C# SDK - json

I tried to figure this out using the Windows Phone sample from the Facebook C# SDK page, but have been unsuccessful.
Here's the main code:
private void GetPages()
{
var fb = new FacebookClient(_accessToken);
fb.GetCompleted += (o, e) =>
{
if (e.Error != null)
{
Dispatcher.BeginInvoke(() => MessageBox.Show(e.Error.Message));
return;
}
var result = (IDictionary<string, object>)e.GetResultData();
// returns data and paging from Facebook
Dispatcher.BeginInvoke(() =>
{
foreach (var item in result)
{
// Not sure if/how to use the custom classes here
//item has .Key and .Value
//.Key = data and .Value contains the key/value pais for each of the pages returned
}
});
};
fb.GetAsync("me/accounts");
}
// Custom Classes
public class FacebookPageCollection
{
[JsonProperty(PropertyName = "data")]
public FacebookPage[] data { get; set; }
[JsonProperty(PropertyName = "paging")]
public FacebookPagePaging paging { get; set; }
}
public class FacebookPage
{
[JsonProperty(PropertyName = "name")]
public string Name { get; set; }
[JsonProperty(PropertyName = "access_token")]
public string AccessToken { get; set; }
[JsonProperty(PropertyName = "category")]
public string Category { get; set; }
[JsonProperty(PropertyName = "id")]
public string Id { get; set; }
}
public class FacebookPagePaging
{
[JsonProperty(PropertyName = "previous")]
public Uri previous { get; set; }
[JsonProperty(PropertyName = "next")]
public Uri next { get; set; }
}
This is what the variable "result" returns:
{"data":[{"name":"value1","access_token":"value2","category":"value3","id":"value4","perms":["ADMINISTER","EDIT_PROFILE","CREATE_CONTENT","MODERATE_CONTENT","CREATE_ADS","BASIC_ADMIN"]},{"name":"value1","access_token":"value2","category":"value3","id":"value4","perms":["ADMINISTER","EDIT_PROFILE","CREATE_CONTENT","MODERATE_CONTENT","CREATE_ADS","BASIC_ADMIN"]}],"paging":{"next":"url"}}
What I'd like to do is retrieve and save details for each page.
I have been trying to figure this out and have looked over a number of other posts on here and elsewhere. I just don't have enough experience to figure it out.
Any help is appreciated.
Thank you.
Sri

Here is a trick to understanding how to work with json response in fb c# sdk.
Here is the mapping between Javascript JSON and C# JSON. (Notice there is no DateTime and another complex .net objects as it is not part of the JSON spec found in JSON.org)
JsonObject => keyvalue pairs => IDictionary<string, object> / IDictinary<string, dynamic>
JsonArray => array => IList<object> / IList<dynamic>
string => string
number => long/decimal
boolean => bool
Here is how you do the actual mapping.
var result = (IDictionary<string, object>)e.GetResultData();
var data = (IList<object>)result["data"];
foreach(var act in data) {
var account = (IDictionary<string,object>) act;
var name = (string)account["name"];
var accessToken = (string)account["access_token"];
var id = (string)account["id"];
// normalize to IList<string> permissions, so it is easier to work without casting.
var permissions = ((IList<object>)account["perms"]).Select(x => (string)x).ToList();
}

Related

c# JsonConvert.DeserializeObject<List<Movie>>(content) doesn't work if return JSON is nested

I'm new to xamarin forms. i'm using a third party api to retrieve a list of movies based on search text of the title. The third party movie api I'm using is below
[movie api][1]
http://www.omdbapi.com/?apikey==*******&s=man
This returns JSON data as below
{"Search":[{"Title":"Iron Man","Year":"2008","imdbID":"tt0371746","Type":"movie","Poster":"https://m.media-amazon.com/images/M/MV5BMTczNTI2ODUwOF5BMl5BanBnXkFtZTcwMTU0NTIzMw##._V1_SX300.jpg"},{"Title":"Iron Man 3","Year":"2013","imdbID":"tt1300854","Type":"movie","Poster":"https://m.media-amazon.com/images/M/MV5BMjE5MzcyNjk1M15BMl5BanBnXkFtZTcwMjQ4MjcxOQ##._V1_SX300.jpg"},{"Title":"Iron Man 2","Year":"2010","imdbID":"tt1228705","Type":"movie","Poster":"https://m.media-amazon.com/images/M/MV5BMTM0MDgwNjMyMl5BMl5BanBnXkFtZTcwNTg3NzAzMw##._V1_SX300.jpg"},{"Title":"Man of Steel","Year":"2013","imdbID":"tt0770828","Type":"movie","Poster":"https://m.media-amazon.com/images/M/MV5BMTk5ODk1NDkxMF5BMl5BanBnXkFtZTcwNTA5OTY0OQ##._V1_SX300.jpg"},{"Title":"Spider-Man","Year":"2002","imdbID":"tt0145487","Type":"movie","Poster":"https://m.media-amazon.com/images/M/MV5BZDEyN2NhMjgtMjdhNi00MmNlLWE5YTgtZGE4MzNjMTRlMGEwXkEyXkFqcGdeQXVyNDUyOTg3Njg#._V1_SX300.jpg"},{"Title":"Ant-Man","Year":"2015","imdbID":"tt0478970","Type":"movie","Poster":"https://m.media-amazon.com/images/M/MV5BMjM2NTQ5Mzc2M15BMl5BanBnXkFtZTgwNTcxMDI2NTE#._V1_SX300.jpg"},{"Title":"The Amazing Spider-Man","Year":"2012","imdbID":"tt0948470","Type":"movie","Poster":"https://m.media-amazon.com/images/M/MV5BMjMyOTM4MDMxNV5BMl5BanBnXkFtZTcwNjIyNzExOA##._V1_SX300.jpg"},{"Title":"Spider-Man 2","Year":"2004","imdbID":"tt0316654","Type":"movie","Poster":"https://m.media-amazon.com/images/M/MV5BMzY2ODk4NmUtOTVmNi00ZTdkLTlmOWYtMmE2OWVhNTU2OTVkXkEyXkFqcGdeQXVyMTQxNzMzNDI#._V1_SX300.jpg"},{"Title":"Spider-Man: Homecoming","Year":"2017","imdbID":"tt2250912","Type":"movie","Poster":"https://m.media-amazon.com/images/M/MV5BNTk4ODQ1MzgzNl5BMl5BanBnXkFtZTgwMTMyMzM4MTI#._V1_SX300.jpg"},{"Title":"Spider-Man 3","Year":"2007","imdbID":"tt0413300","Type":"movie","Poster":"https://m.media-amazon.com/images/M/MV5BYTk3MDljOWQtNGI2My00OTEzLTlhYjQtOTQ4ODM2MzUwY2IwXkEyXkFqcGdeQXVyNTIzOTk5ODM#._V1_SX300.jpg"}],"totalResults":"10750","Response":"True"}
with three parts in the JSON data -"Search","totalResult" and "Response"
I need to access the data in the "Search" section and deserialised that to my POCO class Movie. How should I do it?
My POCO class for Movie is below
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;
namespace NetflixRouletteApp.Models
{
public class Movie
{
[JsonProperty("Title")]
public string Title { get; set; }
[JsonProperty("Year")]
public int Year { get; set; }
[JsonProperty("Released")]
public DateTime Released { get; set; }
[JsonProperty("Rated")]
public string Rated { get; set; }
[JsonProperty("Runtime")]
public string Runtime { get; set; }
[JsonProperty("Genre")]
public string Genre { get; set; }
[JsonProperty("Director")]
public string Director { get; set; }
[JsonProperty("Writer")]
public string Writer { get; set; }
[JsonProperty("Actors")]
public string Actors { get; set; }
[JsonProperty("Plot")]
public string Plot { get; set; }
[JsonProperty("Language")]
public string Language { get; set; }
[JsonProperty("Country")]
public string Country { get; set; }
[JsonProperty("Awards")]
public string Awards { get; set; }
[JsonProperty("Poster")]
public string Poster { get; set; }
[JsonProperty("Type")]
public string mtype { get; set; }
}
}
MovieService.cs is
using NetflixRouletteApp.Models;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using RestSharp;
using RestSharp.Authenticators;
using System.Threading;
using System.Net.Http.Headers;
using Newtonsoft.Json.Linq;
namespace NetflixRouletteApp.Services
{
public class MovieService
{
public static readonly int MinSearchLength = 3;
private const string Url = "http://www.omdbapi.com/?apikey=d09e0406";
private HttpClient _client = new HttpClient();
public static Exception CreateExceptionFromResponseErrors(HttpResponseMessage response)
{
var httpErrorObject = response.Content.ReadAsStringAsync().Result;
// Create an anonymous object to use as the template for deserialization:
var anonymousErrorObject =
new { message = "", ModelState = new Dictionary<string, string[]>() };
// Deserialize:
var deserializedErrorObject =
JsonConvert.DeserializeAnonymousType(httpErrorObject, anonymousErrorObject);
// Now wrap into an exception which best fullfills the needs of your application:
var ex = new Exception();
// Sometimes, there may be Model Errors:
if (deserializedErrorObject.ModelState != null)
{
var errors =
deserializedErrorObject.ModelState
.Select(kvp => string.Join(". ", kvp.Value));
for (int i = 0; i < errors.Count(); i++)
{
// Wrap the errors up into the base Exception.Data Dictionary:
ex.Data.Add(i, errors.ElementAt(i));
}
}
// Othertimes, there may not be Model Errors:
else
{
var error =
JsonConvert.DeserializeObject<Dictionary<string, string>>(httpErrorObject);
foreach (var kvp in error)
{
// Wrap the errors up into the base Exception.Data Dictionary:
ex.Data.Add(kvp.Key, kvp.Value);
}
}
return ex;
}
public async Task<IEnumerable<Movie>> FindMoviesByActor(string title)
{
_client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = await _client.GetAsync($"{Url}&s={title}");
response.EnsureSuccessStatusCode();
try
{
if (response.StatusCode == HttpStatusCode.NotFound)
return Enumerable.Empty<Movie>();
var content = response.Content.ReadAsStringAsync().Result;
List<Movie> movies = JsonConvert.DeserializeObject<List<Movie>>(content);
movies.ForEach(Console.WriteLine);
return movies;
}
catch {
// Unwrap the response and throw as an Api Exception:
var ex = CreateExceptionFromResponseErrors(response);
throw ex;
}
}
public async Task<Movie> GetMovie(string title)
{
var response = await _client.GetAsync($"{Url}&t={title}");
if (response.StatusCode == HttpStatusCode.NotFound)
return null;
var content = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<Movie>(content);
}
}
}
MoviePage.Xaml
<? xml version = "1.0" encoding = "utf-8" ?>
< ContentPage xmlns = "http://xamarin.com/schemas/2014/forms"
xmlns: x = "http://schemas.microsoft.com/winfx/2009/xaml"
x: Class = "NetflixRouletteApp.Views.MoviesPage" >
< StackLayout >
< SearchBar x: Name = "searchBar"
Placeholder = "Enter value..."
SearchCommand = "{Binding SearchButtonPressed}"
SearchCommandParameter = "{Binding Source={x:Reference searchBar}, Path=Text}" />
< !--< ActivityIndicator IsRunning = "{Binding IsSearching}" /> -->
< Frame x: Name = "notFound" Padding = "20" HasShadow = "False" IsVisible = "False" >
< Label Text = "No movies found matching your search." TextColor = "Gray" ></ Label >
</ Frame >
< ListView x: Name = "moviesListView" ItemSelected = "OnMovieSelected" >
< ListView.ItemTemplate >
< DataTemplate >
< ImageCell ImageSource = "{Binding Poster}"
Text = "{Binding Title}"
Detail = "{Binding Year}" ></ ImageCell >
</ DataTemplate >
</ ListView.ItemTemplate >
</ ListView >
</ StackLayout >
</ ContentPage >
MoviePage.xaml.cs
using NetflixRouletteApp.Models;
using NetflixRouletteApp.Services;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace NetflixRouletteApp.Views
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class MoviesPage : ContentPage
{
private MovieService _movieService = new MovieService();
// Note that IsSearching is a bindable property. This is required for
// binding ActivityIndicator's IsRunning property. If we do not define
// IsSearching as a bindable property, its initial value (false) will
// be used to set ActivityIndicator.IsRunning. Later when we change
// the value of IsSearching, ActivityIndicator will be unaware of this.
// So, we need to implement it as a bindable property.
//private BindableProperty IsSearchingProperty = BindableProperty.Create("IsSearching",
// typeof(bool), typeof(MoviesPage), false);
public ICommand SearchButtonPressed { private set; get; }
public MoviesPage()
{
BindingContext = this;
SearchButtonPressed = new Command<string>(HandleSearchPressed);
InitializeComponent();
}
async void HandleSearchPressed(string searchText)
{
if (searchText == null)
return;
await FindMovies(title: searchText);
}
async Task FindMovies(string title)
{
try
{
var movies = await _movieService.FindMoviesByActor(title);
moviesListView.ItemsSource = movies;
moviesListView.IsVisible = movies.Any();
notFound.IsVisible = !moviesListView.IsVisible;
}
catch (Exception)
{
await DisplayAlert("Error", "Could not retrieve the list of movies.", "OK");
}
}
async void OnTextChanged(object sender, TextChangedEventArgs e)
{
if (e.NewTextValue == null)
return;
await FindMovies(title: e.NewTextValue);
}
async void OnMovieSelected(object sender, SelectedItemChangedEventArgs e)
{
if (e.SelectedItem == null)
return;
var movie = e.SelectedItem as Movie;
moviesListView.SelectedItem = null;
await Navigation.PushAsync(new MovieDetailsPage(movie));
}
}
}
go to json2csharp.com and paste your json, it will generate this C# class
public class Movie {
public string Title { get; set; }
public string Year { get; set; }
public string imdbID { get; set; }
public string Type { get; set; }
public string Poster { get; set; }
}
public class Root {
public List<Movie> Search { get; set; }
public string totalResults { get; set; }
public string Response { get; set; }
}
then deserialize the response in your service layer
Root root = JsonConvert.DeserializeObject<Root>(content);
List<Movie> Movies = root.Search;

WP read user_id from JSON and show it

I want to show user_id from the following JSON:
[{"username":"Kac26","email":"xklemenx#gmail.com","city":"Slovenj Gradec","id":"15"}]
So I save this JSON to class. I get JSON from my webpage.
My class:
public class Class2
{
public string username{ get; set; }
public string email { get; set; }
public string city { get; set; }
public int id { get; set; }
}
Saving JSON to class:
private async void Login_Tapped(object sender, TappedRoutedEventArgs e)
{
string str = user.Text; //get user name from textbox
HttpClient http = new HttpClient();
var response= await http.GetStringAsync("http://mywebpage.com/events/apis/user.php/user=" + str);
}
Then I want to show user id in textbox_id when i press button.
private void Button_Tapped(object sender, TappedRoutedEventArgs e)
{
textbox_id.Text = Class2.id;
}
But error shows up when I try to reach Class2.id
Anyone know how to do that? And do I save json to class correct?
Thanks!!!
In "Saving JSON to class", I don't see where you are actually doing that. Here's how you would deserialize the string returned by the service:
private async void Login_Tapped(object sender, TappedRoutedEventArgs e)
{
string str = user.Text; //get user name from textbox
HttpClient http = new HttpClient();
var response = await http.GetStringAsync("http://mywebpage.com/events/apis/user.php/user=" + str);
Class2 myClass2 = null;
try
{
var jsonSerializer = new DataContractJsonSerializer(typeof(Class2));
using (var stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(response)))
{
myClass2 = jsonSerializer.ReadObject(stream) as Class2;
}
}
catch
{
// serialization error occurred
}
// do something with myClass2
}
Also, FYI if you don't want the property names on your response class to match the JSON properties (for example, not be lower case), you can use DataContractAttribute and DataMemberAttribute on your class like so:
[DataContract]
public class Class2
{
[DataMember(name = "username")]
public string UserName { get; set; }
[DataMember(name = "email")]
public string EMail { get; set; }
[DataMember(name = "city")]
public string SomeCompletelyDifferentNameForCity { get; set; }
[DataMember(name = "id")]
public int Id { get; set; }
}
Class2.id is a static access to a non-static property of Class2. You have to create an instance of Class2 with new Class2(); at some point and then you can access the property.

Parse Json response and create List of files

how can i parse this json response and create c# object
{"Response":"valid","Files":{"0":{"FileURL":"htp:\/\/somedomain.com\/1.exe","FileVersion":1},"1":{"FileURL":"htp:\/\/somedomain.com\/1.exe","FileVersion":2}}}
i have c# class
public class Files
{
public string fileURL;
public string fileVersion;
}
WebClient wc=new WebClient();
string code=wc.DownloadString("http://somedomain.com/GetLatestFiles.php");
List<Files> f=ParseJson(code);
how can i parse this json please help. I need to implement ParseJson which will return files list or can i deserialize this response to c# class?
Thankyou
Edit implemented some solution but its very slow?
public class LatestFile
{
public string fileURL;
public string fileVersion;
}
private List<LatestFile> ParseJson(string code)
{
List<LatestFile> files = new List<LatestFile>();
dynamic jObj = JsonConvert.DeserializeObject(code);
foreach (var child in jObj.Files.Children())
{
string index = child.Name;
string url = child.First.FileURL.Value;
string version = child.First.FileVersion.Value.ToString();
LatestFile f = new LatestFile();
f.fileURL = url;
f.fileVersion = version;
files.Add(f);
}
return files;
}
Based on #Brian Rogers answer below i am able to implement the generic solution working fast and efficiently.Thanks
https://dotnetfiddle.net/tC0Dws
Try defining your classes like this:
public class RootObject
{
public string Response { get; set; }
public Dictionary<string, LatestFile> Files { get; set; }
}
public class LatestFile
{
public string FileURL { get; set; }
public string FileVersion { get; set; }
}
And make your helper method like this:
private List<LatestFile> ParseJson(string json)
{
RootObject obj = JsonConvert.DeserializeObject<RootObject>(json);
return obj.Files.Values.ToList();
}
Fiddle: https://dotnetfiddle.net/vpre5H
According to the JSON you provided you have three different objects there. First with Response and Files fields. Second - it looks like it's intended to be a collection but with current implementation it's an object - with fields 0 and 1. And third one with fields FileURL and FileVersion.
You can use DataContractJsonSerializer which is available starting from .Net 4.5. It's in System.Runtime.Serialization.Json namespace.
To parse your JSON you need following data structure:
[DataContract]
public class JsonResponse
{
[DataMember(Name = "Response")]
public string Response { get; set; }
[DataMember(Name = "Files")]
public Files Files { get; set; }
}
[DataContract]
public class Files
{
[DataMember(Name = "0")]
public MyFile Frst { get; set; }
[DataMember(Name = "1")]
public MyFile Scnd { get; set; }
}
[DataContract]
public class MyFile
{
[DataMember(Name = "FileURL")]
public string FileURL { get; set; }
[DataMember(Name = "FileVersion")]
public int FileVersion { get; set; }
}
To make testing easier I'm using your sample as a string but you can easily use URL or a Stream:
static string json = #"
{
""Response"":""valid"",
""Files"":
{
""0"":
{
""FileURL"":""htp:\/\/somedomain.com\/1.exe"",""FileVersion"":""1""
},
""1"":
{
""FileURL"":""htp:\/\/somedomain.com\/1.exe"",""FileVersion"":""2""
}
}
}";
static void Main(string[] args)
{
var serializer = new DataContractJsonSerializer(typeof(JsonResponse));
DataContractJsonSerializer js = new DataContractJsonSerializer(typeof(JsonResponse));
using (MemoryStream ms = new MemoryStream(System.Text.ASCIIEncoding.ASCII.GetBytes(json)))
{
JsonResponse response = (JsonResponse)js.ReadObject(ms);
}
}
And that's the result:

BSON Object Being Partially Deserialized

I'm trying to deserialize a BSON HTTP Response Message from a Web API call into a custom type.
using (HttpClient client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:1234");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/bson"));
HttpResponseMessage result;
result = await client.GetAsync("/endpoint/");
MediaTypeFormatter[] formatters = new MediaTypeFormatter[] {
new BsonMediaTypeFormatter()
};
if (result.IsSuccessStatusCode)
{
try
{
RootObject res = await result.Content.ReadAsAsync<RootObject>(formatters);
}
catch (Exception e)
{
}
}
I know the Web API is returning BSON, I checked through Fiddler and the above code actually does deserialize most things correctly in the RootObject. It appears that all of the derived classes are not being deserialized and are just being input into the object as null. Here is an example of a derived class that is not being deserialized.
RootObject.Events.Teams.Linescores
RootObject
[DataContract(Namespace = "", Name = "RootObject")]
[Serializable]
public class RootObject: infoBase
{
[DataMember(EmitDefaultValue = false, Order = 30)]
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, Order = 30)]
public IEnumerable<eventInfo> events { get; set; }
public RootObject() { }
}
Events Object
[DataContract(Namespace = "", Name = "event")]
[Serializable]
[KnownType(typeof(subEventTeam))]
public class eventInfo : infoBase
{
[DataMember(EmitDefaultValue = false, Order = 170)]
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, Order = 170)]
public List<eventTeamBase> teams { get; set; }
public eventInfo() { }
}
Teams Base and Specific Team Type
[DataContract(Namespace = "", Name = "team")]
[Serializable]
[KnownType(typeof(bbLinescoreInfo))]
public class eventTeamBase : infoBase {
[DataMember(Order = 20)]
[JsonProperty(Order = 20)]
public string location { get; set; }
[DataMember(Order = 30, EmitDefaultValue = false)]
[JsonProperty(Order = 30, NullValueHandling = NullValueHandling.Ignore)]
public string nickname { get; set; }
[DataMember(EmitDefaultValue = false, Name = "linescores", Order = 130)]
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, Order = 130)]
public IEnumerable<linescoreBase> linescores { get; set; }
public eventTeamBase() { }
}
[DataContract(Namespace = "", Name = "team")]
[Serializable]
public class subEventTeam : eventTeamBase
{
public subEventTeam () { }
}
Linescore Base and Specific Object
[DataContract(Name = "linescores", Namespace = "")]
[Serializable]
[KnownType(typeof(subLinescoreInfo))]
public class linescoreBase : infoBase
{
public bool isProcessing = false;
public int teamId { get; set; }
public linescoreBase() { }
}
[DataContract(Name = "linescores", Namespace = "")]
[Serializable] public class subLinescoreInfo : linescoreBase
{
[DataMember]
public int inning { get; set; }
[DataMember]
public int? score { get; set; }
public subLinescoreInfo() { };
}
Here is the deserialized (and then re-serialized) part of the response that isn't working output into JSON.
{
"status":"OK",
"recordCount":1,
"RootObject":[
{
"events":[
{
"teams":[
{
"location":"Tallahassee",
"nickname":"Razors",
"linescores":[
{},{},{},{},{},{},{},{}]
}
}
}
}
So as you can see, it is filling in some information correctly (There is a lot more, I've cut down significantly just to illustrate the problem). But the linescores are returning null. As mentioned, the data is returning correctly and it is not null.
I feel like I'm doing something wrong with the known types and I've tried numerous combinations of putting them in different places and the results don't change. Any help would greatly appreciated.
After much searching and trying wrong things, I found a similar solution in another thread.
JSON Solution
I solved this by doing pretty much that exact same thing but with BSON instead of JSON.
This is the code that I needed to add in the global config file of the Web API
BsonMediaTypeFormatter bsonFormatter = new BsonMediaTypeFormatter();
bsonFormatter.SerializerSettings.TypeNameHandling = TypeNameHandling.Objects;
bsonFormatter.AddQueryStringMapping("accept", "bson", "application/bson");
GlobalConfiguration.Configuration.Formatters.Add(bsonFormatter);
And this code went into the client.
BsonMediaTypeFormatter bsonFormatter = new BsonMediaTypeFormatter();
bsonFormatter.SerializerSettings.TypeNameHandling = TypeNameHandling.Objects;
MediaTypeFormatter[] formatters = new MediaTypeFormatter[] {
bsonFormatter
};
Everything else remained the same and was deserialized without incident.

ASP.NET MVC Model binding not parsing

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.