Cosuming JSON with JavaScriptSerializer returns NULL object - asp.net-mvc

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.

Related

Pass complex data object in GET request to MVC controller action

I have model class as below:
public class HomeFilterModel {
public string CompanyName { get; set; }
public string Country { get; set; }
public DateRange Period { get; set; }
}
public class DateRange {
public DateTime? From { get; set; }
public DateTime? To { get; set; }
}
On client side, the data collected as below object:
{
"CompanyName":"",
"Country":"Canada",
"Period":{
"from":"2018-08-05T04:00:00.000Z",
"to":"2018-08-09T04:00:00.000Z"
}
}
It's converted to query string by $.param function and added to URL.
?CompanyName=&Country=Canada&Period%5Bfrom%5D=2018-08-05T04%3A00%3A00.000Z&Period%5Bto%5D=2018-08-10T04%3A00%3A00.000Z
The controller action is as below:
[HttpGet]
public ActionResult Index(HomeFilterModel filter) {
return View(filter ?? new HomeFilterModel());
}
The model data filter can get CompanyName and Country values correctly, but Period.From and Period.To are always NULL. I wonder if I have to make customized ModelBinder for this model class specifically? Or I should use different function other than $.param to construct query string in URL?
UPDATED:
If query string is changed to
?CompanyName=&Country=Canada&Period.from=2018-08-05T04%3A00%3A00.000Z&Period.to=2018-08-10T04%3A00%3A00.000Z
controller action can get all data correctly. So Period[from] is not acceptable by default model binder, while Period.from is.
Anyone has the simplest and best solution for this?

MVC4 Bind DataTable request parameters to action filter

I'm trying to implement server-side paging and sorting for jquery-datatable.
but the issue is I'm not able to bind data posted by datatable to my action model
to do sort and filter
Here is the data posted by jquery-datatable ajax request
draw:5
columns[0][data]:FirstName
columns[0][name]:FirstName
columns[0][searchable]:true
columns[0][orderable]:true
columns[0][search][value]:
columns[0][search][regex]:false
columns[1][data]:LastName
columns[1][name]:LastName
columns[1][searchable]:true
columns[1][orderable]:true
columns[1][search][value]:
columns[1][search][regex]:false
......
columns[n][data]:Position
columns[n][name]:Position
columns[n][searchable]:true
columns[n][orderable]:true
columns[n][search][value]:
columns[n][search][regex]:false
order[0][column]:1
order[0][dir]:desc
start:0
length:10
search[value]:
search[regex]:false
and my action method is:
public JsonResult GetGridData(GridFilter filter)
{ ....}
and my model classes are
public class GridFilter
{
public int draw { get; set; }
public List<ColModel> columns { get; set; }
public List<Order> order { get; set; }
public int start {get;set;}
public int length {get;set;}
public search search { get; set; }
}
public class ColModel
{
public string data { get; set; }
public string name { get; set; }
public string searchable { get; set; }
public string orderable { get; set; }
}
public class Order
{
public string dir { get; set; }
public string column { get; set; }
}
public class search
{
public string value {get;set;}
public string regex {get;set;}
}
How can I make data bind properly using default mvc model binders are a custom one.
Thanks
Make sure your model properties have the same data types as defined here.
Also you have gone one level too far with your models.They are sent as individual parameters so you don't need the GridFilter model, they should be received like so:
[HttpPost]
public JsonResult GetGridData(List<ColModel> columns, List<Order> order, Search search, int? start, int? length, int? draw)
{
}

How do I save several set of information on my model class in MVC?

I'm making a simple website where I'm storing some information that I get from an excel file into my models class and retrieving them from the html page. The following class is a class in my models:
public class ToxinInformation
{
public string cas_rn { get; set; }
public string critical_effect { get; set; }
public string point_of_departure { get; set; }
public string adi_tdi { get; set; }
public string intake { get; set; }
public string hazard_quotient { get; set; }
public string comment { get; set; }
public string tox_link { get; set; }
public string tox_link_decription { get; set; }
public string intake_link { get; set; }
public string intake_link_description { get; set; }
public IList<string> Links { get; set; }
}
And I use this code to set the information in my controller class and return the view:
(of course I would set information all the variables, not only the first one)
var model = new ToxinInformation
{
cas_rn = "lol"
};
return View(model);
So far I can easily set all my strings and my list and retrieve them on my html page, but what do I do if in some cases I need several instances of the class "ToxinInformation"? In some cases I have 2 or more set of data I'd like to save and show in HTML except for just one.
Any suggestions would be very helpful.
You should make a list and add instances of model to the list. Then you can use a DisplayFor or EditorFor template to show them all.
var models = new List<ToxinInformation>();
foreach(var dataBlob in YourDataStore)
{
var model = new ToxinInformation()
{
cas_rn = dataBlob.cas_rn // Not sure where your raw data is coming from.
}
models.add(model)
}
return View(models);

How can I handle large JSON input from Postmark in my MVC application?

This is related to this question, but in this case it's not something I am returning but rather the model binding. I am using Postmark to handle incoming emails, which posts to a page with a JSON payload.
I have a model as below and an action that takes in this JSON payload (posted with application/json) and processes it.
public class EmailModel
{
public IDictionary<string, string> Headers { get; set; }
public string From { get; set; }
public string Cc { get; set; }
public string HtmlBody { get; set; }
public string TextBody { get; set; }
public string ReplyTo { get; set; }
public string Tag { get; set; }
public string To { get; set; }
public string MessageID { get; set; }
public string MailboxHash { get; set; }
public string Subject { get; set; }
public List<Attachment> Attachments { get; set; }
}
public class Attachment
{
public string Content { get; set; }
public int ContentLength { get; set; }
public string ContentType { get; set; }
public string Name { get; set; }
}
This works fine for small attachments, but for anything that exceeds the default maxJsonLength property causes an error in deserialization. ("Error during serialization or deserialization using the JSON JavaScriptSerializer. The length of the string exceeds the value set on the maxJsonLength property.") Because I want to accept image attachments, this means most images fail.
I've tried updating the web.config, but as per those other threads, this doesn't help for MVC controllers. I figure I can probably do what was mentioned in a custom IModelBinder, but I'm struggling with how to intercept the deserialization. (In other words, it still fails because the deserialization has happened already).
Any suggestions? I'm sure it's just something stupid that I'm missing....
You could write a custom JsonValueProviderFactory that uses Json.NET:
public sealed class JsonDotNetValueProviderFactory : ValueProviderFactory
{
public override IValueProvider GetValueProvider(ControllerContext controllerContext)
{
if (controllerContext == null)
throw new ArgumentNullException("controllerContext");
if (!controllerContext.HttpContext.Request.ContentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase))
return null;
var reader = new StreamReader(controllerContext.HttpContext.Request.InputStream);
var bodyText = reader.ReadToEnd();
return String.IsNullOrEmpty(bodyText) ? null : new DictionaryValueProvider<object>(JsonConvert.DeserializeObject<ExpandoObject>(bodyText, new ExpandoObjectConverter()) , CultureInfo.CurrentCulture);
}
}
and in your Application_Start:
ValueProviderFactories.Factories.Remove(ValueProviderFactories.Factories.OfType<JsonValueProviderFactory>().FirstOrDefault());
ValueProviderFactories.Factories.Add(new JsonDotNetValueProviderFactory());

How to deserialize json with object name

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.

Resources