C# – System.InvalidOperationException: Nullable object must have a value.ASP.NET MVC

asp.net-mvcclinqnullable

I am tired of fixing this error but nothing is working.

Here is the error:

System.InvalidOperationException: Nullable object must have a value.
at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource
resource) at System.Nullable1.get_Value() at
Finance.Calculator.Presentation.Admin.Areas.HDGS.Controllers.TransactionController.Edit(Int64
TransactionId, String returnURL) in
d:\BuildAgent2\work\83d988abf03ace44\Code\Presentation\Finance.Calculator.Presentation.Admin\Areas\HDGS\Controllers\TransactionController.cs:line
44 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, IDictionary2
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.b__14()
at
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext
controllerContext, IList1 filters, ActionDescriptor actionDescriptor,
IDictionary
2 parameters) at
System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext
controllerContext, String actionName)

Here is my Code:

public ViewResult Edit(string TId, string returnURL)
    {
        long tid = !string.IsNullOrEmpty(TId) ? Convert.ToInt64(TId) : Convert.ToInt64(Request.QueryString["TId"].ToString());
        var TransactionItem = db.HDGSAccTransaction.SingleOrDefault(t => t.TransactionID.Equals(tid));
        TransactionVM oTrns = null;
        if (!string.IsNullOrEmpty(returnURL))
        {
            TempData["ReturnUrl"] = returnURL;
        }
        if (TransactionItem != null)
        {
            oTrns = new TransactionVM
            {
                TRef = TransactionItem.dimTransaction.TRef,
                Yr = TransactionItem.Yr,
                IcV = (decimal)TransactionItem.IcV,
                OFv = (decimal)TransactionItem.OFv,
                OCBv = (decimal)TransactionItem.OCBv,
                OOBv = (decimal)TransactionItem.OOBv,
                OInv = (decimal)TransactionItem.OInv
            };
        }

        return View(oTrns);
    }

Please Note: This code runs fine in the development environment from Visual Studio but not on the servers when it is deployed.

Best Answer

I guess the reason why it's only working on your development environment is that the variables always have a value there and on your server the nullables are null.

If a Nullable<T> is null you cannot cast it explicitly to the value type because you get your exception "Nullable object must have a value". (Demo)

So don't cast it. What value do you want to use instead of null, you could use decimal.MinValue:

// ...
IcV = TransactionItem.IcV.HasValue ? TransactionItem.IcV.Value : decimal.MinValue,
// ...

For what it's worth, here is an extension method:

public static T SafeCast<T>(this Nullable<T> t, T defaultValue = default(T)) where T : struct
{
    return t.HasValue ? t.Value : defaultValue;
}

Then you can from now on use this:

IcV = TransactionItem.IcV.SafeCast(decimal.MinValue),
Related Topic