How to deserialize json with object name - asp.net-mvc

I'm not really sure how to phrase the problem but, I have the following json:
{
"person": {
"first_name": "John",
"gender": "M",
"last_name": "Doe"
}
}
And deserializing using json.net/javascriptserializer(asp.net) I have the following test code:
public class Person
{
public string first_name { get; set; }
public string last_name { get; set; }
public string gender { get; set; }
}
[Test]
public void TestDeserialize()
{
string json = #"{""person"":{""first_name"":""John"",""gender"":""M"",""last_name"":""Doe""}}";
var serializer = new JavaScriptSerializer(); // asp.net mvc (de)serializer
Person doe = serializer.Deserialize<Person>(json);
Person doe1 = JsonConvert.DeserializeObject<Person>(json); // json.net deserializer
Assert.AreEqual("John", doe.first_name);
Assert.AreEqual("John", doe1.first_name);
}
The test method fails, because both are null. Anything wrong with my code to deserialize?

You need an intermediary class here:
public class Model
{
public PersonDetails Person { get; set; }
}
public class PersonDetails
{
public string first_name { get; set; }
public string last_name { get; set; }
public string gender { get; set; }
}
and then:
string json = #"{""person"":{""first_name"":""John"",""gender"":""M"",""last_name"":""Doe""}}";
var serializer = new JavaScriptSerializer();
var model = serializer.Deserialize<Model>(json);
Assert.AreEqual("John", model.Person.first_name);

Examine the object in the debugger but I suspect you need to test doe.person.first_name and doe1.person.first_name

This will do it:
string json = #"{'first_name':'John','gender':'M','last_name':'Doe'}";
var serializer = new JavaScriptSerializer();
Person doe = serializer.Deserialize<Person>(json);
[EDIT]
Oh wait...perhaps you are not in control of the JSON that you receive and cannot change it. If that's the case then Darin's solution would be what you need.

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.

Trying to use ViewModel to Scaffold Controller throws error

Very new to ASP.net Core 2 MVC but trying to figure things out.
I have created a ViewModel:
ublic class PeopleStateViewModel
{
public People People { get; set; }
public StatesDictionary States { get; set; }
public PeopleStateViewModel(People people)
{
People = people;
States = new StatesDictionary();
}
}
I Have these two models:
public class People
{
public int ID { get; set; }
[StringLength(60, MinimumLength = 2)]
[Required]
public string FirstName { get; set; }
[StringLength(60, MinimumLength = 2)]
[Required]
public string LastName { get; set; }
}
public static SelectList StateSelectList
{
get { return new SelectList(StateDictionary, "Value", "Key"); }
}
public static readonly IDictionary<string, string>
StateDictionary = new Dictionary<string, string> {
{"Choose...",""}
, { "Alabama", "AL" }
, { "Alaska", "AK" }
, { "Arizona", "AZ" }
, { "Arkansas", "AR" }
, { "California", "CA" }
// code continues to add states...
};
}
I try to create a controller using MVC Controller with views, using Entity Framework.
I then get this error:
I want to be able to use data from both models data on a view...
Any help is appreciated.
You can't create a scaffolding by using PeopleStateViewModel since it doesn't have primary key defined (you need to use actual data model from database). You can add the ID property with KeyAttribute in People data model & perform scaffolding on this data model instead:
public class People
{
[Key]
public int ID { get; set; }
[StringLength(60, MinimumLength = 2)]
[Required]
public string FirstName { get; set; }
[StringLength(60, MinimumLength = 2)]
[Required]
public string LastName { get; set; }
}
Additionally using non-parameterless constructor in the viewmodel on form submit with HttpPost like this:
[HttpPost]
public ActionResult ActionName(PeopleStateViewModel model)
{
// do something
}
It will throw this exception:
System.MissingMethodException: No parameterless constructor defined
for this object.
To prevent that error, declare a parameterless constructor on the viewmodel class:
public class PeopleStateViewModel
{
public People People { get; set; }
public StatesDictionary States { get; set; }
public PeopleStateViewModel()
{
}
public PeopleStateViewModel(People people)
{
People = people;
States = new StatesDictionary();
}
}
As mentioned in the comments, domain models should be used in scaffolding controllers and views. In your case use the People model when scaffolding. After the controller and views are created, start modifying the controller and views to use the PeopleStateViewModel.

MVC 4 Web API NullException Error (Noobie)

I'm working on my first MVC 4 app, following the MVC First Web API Tutorial on Asp.net. I've left the names the same, but changed the model and controller code. Here's my model:
public class Product
{
public string SID { get; set; }
public string name { get; set; }
public string givenName { get; set; }
public string sn { get; set; }
public string mail { get; set; }
public string telephoneNumber { get; set; }
public string mobile { get; set; }
public string otherMobile { get; set; }
public string title { get; set; }
public string Manager { get; set; }
public DateTime whenChanged { get; set; }
}
public class ProductModel
{
public ProductModel()
{
ProductList = new List<Product>();
}
public IList<Product> ProductList { get; set; }
}
And here's my APIcontroller:
public class ProductsController : ApiController
{
ProductModel products = new ProductModel();
public IEnumerable<Product> GetAD()
{
DirectoryEntry domainRoot = new DirectoryEntry(LDAP_server);
DirectorySearcher searcher = new DirectorySearcher(searchStr);
SearchResultCollection results = searcher.FindAll();
foreach (SearchResult srchResult in results)
{
DirectoryEntry dirEntry = srchResult.GetDirectoryEntry();
if (dirEntry.Properties["givenName"].Value != null && dirEntry.Properties["sn"].Value != null && !dirEntry.Parent.Name.Contains("Terminated"))
{
products.ProductList.Add(new Product()
{
SID = dirEntry.Properties["sid"].Value.ToString(),
name = dirEntry.Properties["name"].Value.ToString(),
givenName = dirEntry.Properties["givenName"].Value.ToString(),
sn = dirEntry.Properties["sn"].Value.ToString(),
mail = dirEntry.Properties["mail"].Value.ToString(),
telephoneNumber = dirEntry.Properties["telephoneNumber"].Value.ToString(),
mobile = dirEntry.Properties["mobile"].Value.ToString(),
otherMobile = dirEntry.Properties["otherMobile"].Value.ToString(),
title = dirEntry.Properties["title"].Value.ToString(),
Manager = dirEntry.Properties["Manager"].Value.ToString(),
whenChanged = Convert.ToDateTime(dirEntry.Properties["whenChanged"].Value.ToString()),
});
}
}
return products.ProductList;
}
}
I'm getting the NullException on 'products.ProductList.Add(new Product()', am I missing something simple? Please forgive my coding, as I'm just trying to get this up and running, thanks.
the problem mostly likely is dealing with dirEntry, not Web API itself. rather than introduce LDAP into this, just create a bunch of dummy products to return.
FYI... there is also a memory leak issue with the use of LDAP objects. They need to be properly disposed of, both along the happy path and if an exception is thrown.
I'm an idiot. 'sid' is not the correct property name from AD, it is 'objectSid', thus always returning a null. I knew it was something simple.

Cosuming JSON with JavaScriptSerializer returns NULL object

My Json string:
jsonString ="{"GetStatusResult":[{"CaseCompleteInd":"N","CaseNbr":"999999","InSurgeryNowInd":"Y","InRoomNowInd":"N"}]}";
My classes:
public class GetStatusResult
{
public List<CaseModel> caseDetails { get; set; }
}
public class CaseModel
{
public string CaseCompleteInd { get; set; }
public string CaseConfirmNbr { get; set; }
public string InSurgeryNowInd { get; set; }
public string InRoomNowInd{ get; set; }
}
}
My code:
GetStatusResult caseInfo = new GetStatusResult();
JavaScriptSerializer jsSerializer = new JavaScriptSerializer();
caseInfo = jsSerializer.Deserialize<GetStatusResult>(jsonString);
My Problem:
The object is always returning as NULL and the CaseModel details are not being populated. The JSON string obviously has data, but I feel that my class structure is somehow messed up with the root level class. It appears similar to other examples posted here and elsewhere, so I'm at a loss right now. Any help is greatly appreciated.
If you modify your JSON string to
jsonString ="{"caseDetails":[{"CaseCompleteInd":"N","CaseNbr":"999999","InSurgeryNowInd":"Y","InRoomNowInd":"N"}]}";
then it should work.
Properties of JSON object correspond to the properties of .NET object having the same name.

Returning Associated Members via Ria DomainService Invoke Method

I got this DomainService method I'm calling from my SL ViewModel using the Invoke attribute:
[Invoke]
public ServiceModel.Recipy GetRecipyById(int recipyId)
{
return new Recipy
{
RecipyId = 1,
Name = "test",
Description = "desc",
Author = new Author
{
AuthorId = 1,
Name = "Johan"
}
};
}
The code in my ViewModel looks like this:
public RecipyViewModel()
{
context.GetRecipyById(1, RecipyLoadedCallback, null);
}
private void RecipyLoadedCallback(InvokeOperation<Recipy> obj)
{
_name = obj.Value.Name;
_description = obj.Value.Description;
_authorName = obj.Value.Author.Name;
}
The Recipy and Author POCO/ServiceModel classes:
public class Recipy
{
[Key]
public int RecipyId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
[Association("Author", "RecipyId", "AuthorId")]
[Include]
public Author Author { get; set; }
}
public class Author
{
[Key]
public int AuthorId { get; set; }
public string Name { get; set; }
}
Now, the code works fine, except that the associated Author is not transfered over to the client/viewmodel, the Author property of Recipy is null. I thought that using the [Associate] and [Include] attributes would do the trick?
Thanks for any help, I'm trying hard to grok the DomainService/RIA stuff and I'm close to giving up and go "normal" WCF/REST instead :)
As I understand it, [Invoke] doesn't support complex hierarchies at the moment, so I solved it by making sure I had the correct attributes for [Include] and [Association] on the collection, and went back to using a normal RIA query method instead.

Resources