I have some problem in understanding how does the asp.net mvc deal with Null values .
In the first scenario i have the following action method:-
[HttpPost]
public ActionResult Delete(int labtestid, int visitid)
{
try
{
var vlr = repository.GetVisitLabResult(labtestid,visitid);
string desc = vlr.LabTest.Description;
repository.DeleteVisitLabResult(vlr);
repository.Save();
return Json(new { IsSuccess = "True", id = labtestid, description = desc }, JsonRequestBehavior.AllowGet);
}
Incase the repository method var vlr = repository.GetVisitLabResult(labtestid,visitid); does not return any result (var vlr is null) then the following exception will be raised on the string desc = vlr.LabTest.Description; NullReferenceException was unhandled by user code. So why did the framework raise an exception instead of just assigning a null value to the string desc !!!
BR
It looks like the actual object itself is null. You have a null object and you're trying to access properties on it, hence the runtime will throw a NullReferenceException. You're best off checking if the object is null first before trying to access it's members :)
Related
In my ASP.NET MVC 5 application, I have an ActionResult in one of my controllers that takes parameters from the client and returns a JSON string.
The problem is, I get the error below when I have null values in one or more of the database records. I can clear this error by casting all the null values to an empty string in the view table itself, but I'd rather not keep that as a long-term solution.
System.Data.Entity.Core.MappingException: 'Schema specified is not valid. Errors:
EFA.msl(16,12) : error 2019: Member Mapping specified is not valid. The type 'Edm.String[Nullable=False,DefaultValue=,MaxLength=,Unicode=,FixedLength=]' of member 'ScheduledStartTime' in type 'EFAModel.v_DemandList' is not compatible with 'SqlServer.datetime[Nullable=False,DefaultValue=,Precision=3]' of member 'ScheduledStartTime' in type 'EFAModel.Store.v_DemandList'.'
Any recommendations on how should be approaching this scenario?
[HttpPost]
public ActionResult GetDemandData()
{
//get basic parameters from DataTables
var draw = Request.Form.GetValues("draw").FirstOrDefault();
var start = Request.Form.GetValues("start").FirstOrDefault();
var length = Request.Form.GetValues("length").FirstOrDefault();
//Find Order Column
var sortColumn = Request.Form.GetValues("columns[" + Request.Form.GetValues("order[0][column]").FirstOrDefault() + "][name]").FirstOrDefault();
var sortColumnDir = Request.Form.GetValues("order[0][dir]").FirstOrDefault();
//find search parameters
var searchParam = Request.Form.GetValues("search[value]")[0];
//build return dataset
int pageSize = length != null ? Convert.ToInt32(length) : 0;
int skip = start != null ? Convert.ToInt32(start) : 0;
int recordsTotal = 0;
//materialize dataset using serch parameters
EFAEntities efa = new EFAEntities();
//*** throws error when database table contains null values ***
var dataSet = (from a in efa.v_DemandList
where a.ScheduledStartTime.Contains(searchParam)
select a
).Distinct().OrderBy(sortColumn + " " + sortColumnDir);
recordsTotal = dataSet.Count();
var data = dataSet.Skip(skip).Take(pageSize).ToList();
return Json(new { draw = draw, recordsFiltered = recordsTotal, recordsTotal = recordsTotal, data = data }, JsonRequestBehavior.AllowGet);
}
Sample from View Table:
Error message is clear! Its clearly saying that ScheduledStartTime type in efa.v_DemandList is not the same type for ScheduledStartTime in database table. In your model class ScheduledStartTime is string type but in your database table its datatime type.
So change your ScheduledStartTime type from string to DateTime in your DemandList model class.
Then update your query as follows:
var dataSet = (from a in efa.v_DemandList
where a.ScheduledStartTime.ToString().Contains(searchParam)
select a
).Distinct().OrderBy(sortColumn + " " + sortColumnDir);
Here I am using .ToString() with ScheduledStartTime otherwise you cannot use Contains() because its a DateTime type.
Give default values in your action method. If it's in fact null, you'll get the default value. For ints, you need to provide a nullable type.
[HttpPost]
public ActionResult GetDemandData(int? start=0, int? length=0, etc)
{
I have a multiselectlist where a user can pick some or none inputvoltages. When the user selects no InputVoltages my query throws a null exception when I call .Tolist(). Why am I not just getting back an empty list?
I'm using MVC5 C# and entity framework 6.
repository
public IQueryable<InputVoltage> All
{
get { return context.InputVoltages; }
}
controller
var newInputVoltages = unitOfWorkPds.InputVoltageRepository
.All.Where(m => engineeringPdsEditViewModel.SelectedInputVoltages
.Contains(m.Id))
.ToList<InputVoltage>();
All does return a list but SelectedInputVoltages is null when nothing is selected. I was wondering if that was the issue.
When I use this query and add a where statement for my index page I don't receive a null error when I call ToList
IQueryable<EngineeringPdsIndexViewModel> query =
(from a in context.EngineeringPds
select new EngineeringPdsIndexViewModel
{
Id = a.Id,
Name = a.Name,
Status = a.Status,
AnnualQuantities = a.AnnualQuantities,
ToMarketDate = a.ToMarketDate,
SubmittedBy = a.SubmittedBy,
TargetPrice = a.TargetPrice
});
So I believe Brian has the right idea of what is wrong but here is the issue extended
I have a multiselect box that is populated in the get action method by
IList<InputVoltage> inputVoltagesList = unitOfWorkPds.InputVoltageRepository.All.ToList();
then
pdsEditViewModel.InputVoltageList = inputVoltagesList.Select(m => new SelectListItem { Text = m.Name, Value = m.Id.ToString() }); in my view I hav#Html.ListBoxFor(m => m.SelectedApprovals, Model.ApprovalList)
but when a user makes no selections the selectedInputvoltages comes into my post controller action as null how do I get it to come in as an empty list?
UPDATE
For anyone who runs into the same problem Brians first answer explains the issue. The work around for submitting a ListBox with empty lists can be found here
How can I return an empty list instead of a null list from a ListBoxFor selection box in Asp.net MVC?
Any Extension method defined in the BCL for IEnumerable<T> or IQueryable<T> that returns IEnumerable<T> or IQueryable<T> will not return null. It might return an empty collection, but that is very different to null.
try this:
var newInputVoltages = engineeringPdsEditViewModel.SelectedInputVoltages == null ?
unitOfWorkPds.InputVoltageRepository.All :
unitOfWorkPds.InputVoltageRepository.All.Where(m => engineeringPdsEditViewModel.SelectedInputVoltages.Contains(m.Id)).ToList();
Where will not return null. The problem is in the argument:
engineeringPdsEditViewModel.SelectedInputVoltages.Contains(m.Id)
A NULL engineeringPdsEditViewModel or SelectedInputVoltages can cause NullReferenceException to be thrown. So you need to do a null check against these objects.
You can see this play out with a similar test sample. Here we get a nullrefex because myString is null. So when Where executes it tries to do a comparison and blows up:
var test = new TestClass(1);
var test2 = new TestClass(2);
var test3 = new TestClass(3);
List<TestClass> tests = new List<TestClass>();
tests.Add(test);
tests.Add(test2);
tests.Add(test3);
string myString = null;
var result = tests.Where(t => myString.Contains(t.Myint.ToString())).ToList();
Console.WriteLine(result.Count);
Update: (To answer your comment)
You can return an empty list like this:
List<InputVoltage> newInputVoltages = new List<InputVoltage>();
if(engineeringPdsEditViewModel != null && engineeringPdsEditViewModel.SelectedInputVoltages != null)
{
//Where params are not null so its safe to use them
newInputVoltages = unitOfWorkPds.InputVoltageRepository
.All.Where(m => engineeringPdsEditViewModel.SelectedInputVoltages
.Contains(m.Id))
.ToList<InputVoltage>();
}
//else no need to do anything...just return the empty list created above
return newInputVoltages;
you will not get an empty list and it's expected behaviour it returns null.
just test the input (I used the Ternary Operator) when you create the variable and you won't need any validation later
var newInputVoltages = SelectedInputVoltages.Any()
? unitOfWorkPds.InputVoltageRepository
.All.Where(m => engineeringPdsEditViewModel.SelectedInputVoltages.Contains(m.Id))
.ToList<InputVoltage>()
: new List<InputVoltage>();
Can anyone explain why I'm sometimes gets a NULL exception on this insert method?
As said is only sometimes, which for me is just even more confusing.
The table OrderLine has a referemce to the table Product in the datacontext (.dbml file)
public void insertNewOrder(string accountNumber, int orderId)
{
var order = orderRep.GetOrderById(orderId);
var orderlineData = orderLineRep.GetOrderLines(order.OrderID);
foreach (var orderLine in orderlineData)
{
int currentStatus = dlvRep.getAxOrderStatusNumber(orderLine.ItemNumber, 0);
string levering = "";
string status = dlvRep.getAxOrderStatus(orderLine.ItemNumber, currentStatus, out levering);
WebsiteOrderStatus insertNew = new WebsiteOrderStatus
{
AccountNumber = accountNumber,
OrderID = orderId,
ItemNumber = orderLine.ItemNumber,
ItemName = orderLine.Product.Name,
FormatName = orderLine.Product.ProductFormatName,
Quantity = orderLine.Quantity,
Price = orderLine.Price,
Status = status,
Levering = levering,
LastUpdatedStatus = currentStatus,
CreatedDate = DateTime.Now
};
db.WebsiteOrderStatus.InsertOnSubmit(insertNew);
db.SubmitChanges();
}
}
Exception message:
Cannot insert the value NULL into column 'FormatName', table 'GWportal.dbo.WebsiteOrderStatus'; column does not allow nulls. INSERT fails.
The statement has been terminated.
When I look up the products which this code is having trouble finding the ProductFormatName for. The value of ProductFormatName is not NULL and it's having the value as I expected ex: "PS3".
Another strange thing is, why aren't it complaining about:
ItemName = orderLine.Product.Name,
This coulmn does not allow nulls either.
It's probably a bug in the code fororderLineRep.GetOrderLines(order.OrderID) that causes orderLine.Product.ProductFormatName to be set to null.
Try adding some debug code:
foreach (var orderLine in orderlineData)
{
if (orderLine.Product.ProductFormatName == null) {
throw new Exception("ProductFormatName == null");
}
// ...
Another strange thing is, why aren't it complaining about:
ItemName = orderLine.Product.Name,
This coulmn does not allow nulls either.
I can think of two explanations:
orderLine.Product.Name isn't null. The bug mentioned above may affect only ProductFormatName.
orderLine.Product.Name is null, but one error is enough to terminate the statement immediately. Only one error will be reported. Other errors that are also present won't be reported until the first error is fixed.
[HttpPost]
public JsonResult CreateUser(UserCreateDTO dto)
{
Entity.User Us = new User();
Us.Name = dto.Name;
Us.Surname = dto.Surname;
Us.Username = dto.Username;
Us.Password = dto.Password;
container.Users.Add(Us);
container.SaveChanges();
UserCreateList UsList = new UserCreateList
{
Id = Us.Id,
Name = Us.Name,
Surname = Us.Surname,
Username = Us.Username,
Email = Us.Email,
Password = Us.Password
};
return Json(UsList);
}
It's an ajax New Member Form.
When it comes to this controller from ajax submit, it's throwing an internal network server error. I debugged the code and its crashed at the line container.users.add(us); and the line below..
According to my examples it must be Users.AddObject but there's no AddObject selection..
It can be a problem for giving error or how can I fix it.
www.muratkamci.com/exception.jpg
This is the pic of ex.
That error "conversion of a datetime2 data type to a datetime data type resulted in an out-of-range value." can occur when you fail to set a datetime value on a field that does not accept nulls. Since you aren't defining any DateTime properties on your User object, this is a likely scenario. Look at your model, and see if you can find a non-nullable datetime field.
i m currently working on a tutorial for a blog using ado.net and mvc3 (in c#). I m fairly new to developing so please cut me some slack! Anyways I m having trouble debugging one of the data controllers responsible for reading (validation is turned off) user posts and adding them to the blog. The code breaks down at the GetPost function (marked with a comment).
Any help would be greatly appreciated
` using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Blog.Models;
using System.Text;
namespace Blog.Controllers
{
public class PostsController : Controller
{
private BlogModel model = new BlogModel();
public ActionResult Index()
{
return View();
}
[ValidateInput(false)]
public ActionResult Update(int? id, string title, string body, DateTime dateTime, string tags)
{
if (!IsAdmin)
{
return RedirectToAction("Index");
}
Post post = GetPost(id);
post.Title = title;
post.DateTime = dateTime;
post.Body = body;
post.Tags.Clear();
tags = tags ?? string.Empty;
string[] tagNames = tags.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
foreach (string tagName in tagNames)
{
post.Tags.Add(GetTag(tagName));
}
if (id.HasValue)
{
model.AddToPosts(post);
}
model.SaveChanges();
return RedirectToAction("Details", new { id = post.ID });
}
public ActionResult Edit(int? id)
{
Post post = GetPost(id);
StringBuilder tagList = new StringBuilder();
foreach (Tag tag in post.Tags)
{
tagList.AppendFormat("{0} ", tag.Name);
}
ViewBag.Tags = tagList.ToString();
return View(post);
}
private Tag GetTag(string tagName)
{
return model.Tags.Where(x => x.Name == tagName).FirstOrDefault() ?? new Tag() { Name = tagName };
}
/* Bellow is where I get the exception 'Sequence contains no elements' */
private Post GetPost(int? id)
{
return id.HasValue ? model.Posts.Where(x => x.ID == id).First() : new Post() { ID = -1 };
}
public bool IsAdmin { get { return true; } }
}
}
`
EDIT 16:29 GMT Yep you guys are right on the money! That went trough nicelly, thanks!
Whats weird is I m now getting Nullreference exception on this bit
post.Title = title;
post.DateTime = dateTime;
post.Body = body;
do I have to declare them somehow or am i missing something else?
Nevermind the edit above, that was just a typo. Thanks again
Try using FirstOrDefault(). If a LINQ expression yield no result, it is likely that with the methods First() or Single() you'll end up with the 'Sequence contains no elements' expection.
Edit: When using FirstOrDefault(), the Default means null. You need to check if GetPost returns null.
My guess is that model.Posts does not contain any elements and thus trying to perform a First() will cause the error you're getting.
Using FirstOrDefault() instead will return the default value of the type should no items be found in the collection.
Your problem is most likely that the results of the model.Posts.Where(x => x.ID == id) query are empty, which makes the First() method throw your error, which is the default behavior when querying the first element of an empty result set.
Try using FirstOrDefalut instead of First, which will returns null intead of throwing an exception. And of course, test if your result is null aftewards so you don't try using empty objects !