I have a web method in a MVC .NET application that accepts a json string of data from an AJAX call to be updated in the database
The data is an array of objects, and be one of two package types. I check which package type it is, then deserialize the string to that class. So the function looks something like this:
public JsonResult SaveData (string jsonIn)
{
string rtnStr = "";
bool hasChanges = false;
using (var db = new MyDBContext())
{
JArray packages = JArray.Parse(jsonIn);
foreach (JObject package in packages.Children<JObject>())
{
string packageType = "Unknown";
if (package != null & package.TryGetValue("DataType", out JToken value))
{
packageType = value.ToString();
}
if (packageType == "PackageTypeA")
{
PackageTypeA pkgTypeA = JsonConvert.DeserializeObject<PackageTypeA>(package.ToString());
//do some things
}
else if (packageType == "PackageTypeB") {
PackageTypeB pkgTypeB = JsonConvert.DeserializeObject<PackageTypeB>(package.ToString());
//do something else
}
}
}
}
I'm getting occasional exceptions in the error log on this line in particular: packageType = value.ToString();
:
Message: Object reference not set to an instance of an object.
Stack Trace:
at MyApp.Controllers.PlansController.SaveData(String jsonIn) in C:\home\projects\dotNet\MyApp\MyApp\Controllers\PlansController.cs:line 257
at lambda_method(Closure , ControllerBase , Object[] )
at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters)
at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass15.<InvokeActionMethodWithFilters>b__12()
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation)
at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass15.<>c__DisplayClass17.<InvokeActionMethodWithFilters>b__14()
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation)
at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass15.<>c__DisplayClass17.<InvokeActionMethodWithFilters>b__14()
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)
at System.Web.Mvc.Controller.ExecuteCore()
at System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext)
at System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext)
at System.Web.Mvc.MvcHandler.<>c__DisplayClass6.<>c__DisplayClassb.<BeginProcessRequest>b__5()
at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass1.<MakeVoidDelegate>b__0()
at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass8`1.<BeginSynchronous>b__7(IAsyncResult _)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.End()
at System.Web.Mvc.MvcHandler.<>c__DisplayClasse.<EndProcessRequest>b__d()
at System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>b__0(Action f)
at System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action)
at System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult)
at System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step)
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
As a boolean method shouldn't package.TryGetValue("DataType", out JToken value)
equate to false so that packageType = value.ToString();
isnt executed if DataType is null?