Null Reference exception was unhandled by user code and item is null - asp.net-mvc

This working but all of a sudden it stopped working and was throwing null reference exception, when i checked in my basket record was inserted but the item is still null: the error is around BasketItem item = basket.BasketItems.FirstOrDefault(i => i.product_Id == product_Id);
using my_eCommerce.Contracts.Repositories;
using my_eCommerce.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
namespace my_eCommerce.Services
{
public class BasketService
{
IRepositoryBase<Basket> baskets;
public const string BasketSessionName = "eCommerceBasket";
public BasketService(IRepositoryBase<Basket> baskets)
{
this.baskets = baskets;
}
private Basket CreateNewBasket(HttpContextBase httpContext)
{
//create a new basket
//
//ffirst ceate a new cookie
HttpCookie cookie = new HttpCookie(BasketSessionName);
// Now create a new Basket and set the creation date
Basket basket = new Basket();
//basket.BasketId = Guid.NewGuid(); //basket.BasketId = Guid.NewGuid() is supposed to come after date;
basket.Basket_Id = Guid.NewGuid();
basket.date = DateTime.Now;
baskets.Insert(basket);
baskets.Commit();
//Add basketId to a cookie
cookie.Value = basket.Basket_Id.ToString();
cookie.Expires = DateTime.Now.AddDays(1);
httpContext.Response.Cookies.Add(cookie);
return basket;
}
public bool AddToBasket(HttpContextBase httpContext, int product_Id, int quantity)
{
bool succcess = true;
Basket basket = GetBasket(httpContext);
//BasketItem item = basket.BasketItems.FirstOrDefault(i => i.product_Id == product_Id);
BasketItem item = basket.BasketItems.FirstOrDefault(i => i.product_Id == product_Id);
if (item == null)
{
item = new BasketItem()
{
Basket_Id = basket.Basket_Id,
product_Id = product_Id,
Quantity = quantity
};
basket.BasketItems.Add(item);
}
else
{
item.Quantity = item.Quantity + quantity;
}
baskets.Commit();
return succcess;
}
public Basket GetBasket(HttpContextBase httpContext)
{
HttpCookie cookie = httpContext.Request.Cookies.Get(BasketSessionName);
Basket basket;
Guid basket_Id;
if (cookie != null)
{
if (Guid.TryParse(cookie.Value, out basket_Id))
{
basket = baskets.GetById(basket_Id);
}
else
{
basket = CreateNewBasket(httpContext);
}
}
else
{
basket = CreateNewBasket(httpContext);
}
return basket;
}
}
}

Your basket or basket.BasketItems objects could be null in some situations. You should put Null check for this object the way you have done for the item object. Try to rewrite the code in the following way:
...
BasketItem item = null;
Basket basket = GetBasket(httpContext);
if(basket != null && basket.BasketItems != null)
{
item = basket.BasketItems.FirstOrDefault(i => i.product_Id == product_Id);
}
if (item == null)
{
...

Use Null-conditional operators ?.
You can use it like below and it will not throw exception but it will return
null if basket is null.
null if basket.BasketItems is null.
Or FirstOrDefault() value from basket.BasketItems
BasketItem item = basket?.BasketItems?.FirstOrDefault(i => i.product_Id == product_Id);

Related

How do I programmatically add records to an Umbraco v8 form?

I'm looking to add records to an Umbraco v8 form. I know I need the form guid. Is this how I'd do it? Something like this?
public void PostFormData()
{
Guid FormGuid = new Guid("8494a8f0-94da-490e-bd61-7e658c226142");
var form = _formService.Get(FormGuid);
//place for field data into fieldDic
var fieldDic = new Dictionary<Guid, RecordField>();
var firstName = form.AllFields.First(f => f.Alias == "firstName");
var firstNameRecord = new RecordField(firstName);
firstNameRecord.Values = new List<object>() { "Mad Max" };
fieldDic.Add(firstName.Id, firstNameRecord);
var record = new Record()
{
Created = DateTime.Now,
Form = form.Id,
RecordFields = fieldDic,
State = FormState.Submitted,
};
record.RecordData = record.GenerateRecordDataAsJson();
_recordStorage.InsertRecord(record, form);
}
Here's how I do it. Note, I'm hard-coding the Record.UmbracoPageId to -1 while you might want to actually pass in the correct page ID.
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using Umbraco.Core;
using Umbraco.Core.Composing;
using Umbraco.Core.Logging;
using Umbraco.Forms.Core.Data.Storage;
using Umbraco.Forms.Core.Models;
using Umbraco.Forms.Core.Persistence.Dtos;
using Umbraco.Forms.Core.Services;
namespace myProject.Services
{
public class FormServiceComposer : IUserComposer
{
public void Compose(Composition composition)
{
composition.Register<IFormService, FormService>(Lifetime.Request);
}
}
public interface IFormService
{
void InsertFormData(Guid formGuid, object formModel, string ipAddress);
}
public class FormService : IFormService
{
private readonly ILogger _logger;
private readonly Umbraco.Forms.Core.Services.IFormService _formService;
private readonly IRecordStorage _recordStorage;
private readonly IRecordFieldStorage _recordFieldStorage;
private readonly IWorkflowService _workflowService;
public FormService(ILogger logger, Umbraco.Forms.Core.Services.IFormService formService, IRecordStorage recordStorage, IRecordFieldStorage recordFieldStorage, IWorkflowService workflowService)
{
_logger = logger;
_formService = formService;
_recordStorage = recordStorage;
_recordFieldStorage = recordFieldStorage;
_workflowService = workflowService;
}
#region IFormService
public void InsertFormData(Guid formGuid, object formModel, string ipAddress)
{
try
{
Form form = _formService.GetForm(formGuid);
Record record = new Record();
foreach (Field field in form.AllFields)
{
string caption = CleanCaption(field.Caption);
if (formModel.GetType().GetProperty(caption) == null) continue;
var propertyValue = formModel.GetType().GetProperty(caption).GetValue(formModel, null);
if (propertyValue != null)
{
List<object> values = ExtractValues(propertyValue);
RecordField recordField = new RecordField
{
Alias = field.Alias,
FieldId = field.Id,
Field = field,
Key = Guid.NewGuid(),
Record = record.Id,
Values = values
};
_recordFieldStorage.InsertRecordField(recordField);
record.RecordFields.Add(recordField.Key, recordField);
}
}
record.Form = formGuid;
record.IP = ipAddress;
record.UmbracoPageId = -1;
record.State = Umbraco.Forms.Core.Enums.FormState.Approved;
record.RecordData = record.GenerateRecordDataAsJson();
_recordStorage.InsertRecord(record, form);
_recordStorage.DisposeIfDisposable();
}
catch (Exception ex)
{
_logger.Error<FormService>(ex, "Failed inserting Umbraco Forms data for {formGuid}");
}
}
#endregion IFormService
#region Private
private string CleanCaption(string caption)
{
Regex rgx = new Regex("[^a-zA-Z0-9 -]");
return rgx.Replace(caption.Trim().Replace(" ", ""), "");
}
private List<object> ExtractValues(object propertyValue)
{
List<object> result = new List<object>();
if (propertyValue is string == false && propertyValue.GetType().GetGenericTypeDefinition() == typeof(List<>))
{
IEnumerable<object> _propertyValue = (IEnumerable<object>)propertyValue;
if (_propertyValue.Any())
{
if (_propertyValue.First().GetType().GetProperties().Count() > 1)
{
JArray _properties = JArray.Parse(JsonConvert.SerializeObject(propertyValue));
foreach (JToken item in _properties)
{
string _value = string.Empty;
foreach (var _property in _propertyValue.First().GetType().GetProperties())
{
string _key = _property.Name;
_value = _value + (_value == "" ? "" : " - ") + item[_key].ToString();
}
result.Add(_value);
}
}
else
{
string _key = _propertyValue.First().GetType().GetProperties().First().Name;
JArray _properties = JArray.Parse(JsonConvert.SerializeObject(propertyValue));
foreach (JToken item in _properties)
{
result.Add(item[_key].ToString());
}
}
}
}
else
{
result.Add(propertyValue);
}
return result;
}
#endregion Private
}
}

asp.net mvc core A second operation was started on the context before the first operation is completed

I am using this code for authorization on controllers.
with [Authorize(Policy = "CustomRole")]
The thing happened that after 3 or 4 request it fails with
A second operation started on this context before a previous operation completed
public class CustomRoleRequirement : AuthorizationHandler<CustomRoleRequirement>, IAuthorizationRequirement
{
public CMSContext _context = new CMSContext();
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, CustomRoleRequirement requirement)
{
var routeobj = context.Resource as Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext;
var c = routeobj.RouteData.Values.Values.ToList();
var keys = routeobj.RouteData.Values.Keys.ToList();
string area = "";
string id = "";
string controller = "";
string action = "";
string module = "";
foreach (var item in keys)
{
if (item=="area")
{
int indexs = keys.FindIndex(cc => cc == "area");
area = c[indexs].ToString();
}
else if (item == "id")
{
int indexs = keys.FindIndex(cc => cc == "id");
id = c[indexs].ToString();
}
else if (item == "controller")
{
int indexs = keys.FindIndex(cc => cc == "controller");
controller = c[indexs].ToString();
}
else if (item == "module")
{
int indexs = keys.FindIndex(cc => cc == "module");
module = c[indexs].ToString();
}
else if (item == "action")
{
int indexs = keys.FindIndex(cc => cc == "action");
action = c[indexs].ToString();
}
}
string modulelink = controller;
if (!string.IsNullOrEmpty(module))
{
modulelink = modulelink + "/" + module;
}
List<string> Roles = new List<string>();
int UserId = Auth.UserID;
string UserName = Auth.UserName;
if (UserName == "superadmin")
{
context.Succeed(requirement);
return Task.CompletedTask;
}
else
{
// apparently the error occurred here
var moduleobj = _context.AppModules.FirstOrDefault(q => q.Link == modulelink);
if (moduleobj != null)
{ // 69 role is assessing news module
//60 role is accessing page module
var RolesModulesobj = _context.AppRolesModules.FirstOrDefault(q => q.ModuleId == moduleobj.ModuleId && q.RolesId == Auth.RoleId);
if (RolesModulesobj != null)
{
string permissionsobj = RolesModulesobj.Permissions;
List<string> PermissionsListobj = permissionsobj.Split(',').Select(x => x.Trim()).ToList();
var FindFullAccess = PermissionsListobj.FirstOrDefault(q => q.Contains("FullAccess:true"));
if (FindFullAccess != null)
{
context.Succeed(requirement);
return Task.CompletedTask;
}
else
{
var abc = PermissionsListobj.FirstOrDefault(q => q.Contains(action + ":true"));
if (abc != null)
{
context.Succeed(requirement);
return Task.CompletedTask;
}
else
{
context.Fail();
return Task.CompletedTask;
}
}
}
}
}
The error occurred at this line above
var moduleobj = _context.AppModules.FirstOrDefault(q => q.Link == modulelink);
How can I make task wait before the second operation started in the method above?
You can't use a singleton DB context. You either create one each time you need one or you pool them.

Check for but allow duplicates entries in the Db

My Db allows duplicate monuments, so the traditional method of checking for duplicates will not work. The user first inputs a monument name, then I run a check against the Db and if no duplicates found, great, allow the user to input the rest of the data. If one of more monuments with the same name are found, display a list of the monuments already in the Db. If this is truly a new monument with the same name, allow the user to input the new monument.
What I have so far:
[Authorize]
public ActionResult MonumentTitle(string battleRecordID, int callingRecordID)
{
ViewBag.monumentBattleRecID = battleRecordID; // ID of the battle
ViewBag.battleName = getBattleName(battleRecordID);
var vModel = new MonumentTitle();
vModel.BattleRecID = ViewBag.monumentBattleRecID;
vModel.BattleName = ViewBag.battleName;
vModel.CallingRecID = callingRecordID;
return View(vModel);
}
[HttpPost]
[Authorize]
public ActionResult MonumentTitle(MonumentTitle monumentTitle)
{
ViewBag.callingRecordID = monumentTitle.CallingRecID;
ViewBag.battleName = monumentTitle.BattleName;
ViewBag.MonumentName = monumentTitle.MonumentName;
var NmonumentTitle = monumentTitle;
ViewBag.battleName1 = NmonumentTitle.BattleName;
var List_monument = from s in db.Monuments
where (s.MonumentStatus == "A" &&
s.MonumentBattleRecID == monumentTitle.BattleRecID &&
s.MonumentName == monumentTitle.MonumentName
)
select s;
List_monument = List_monument.OrderBy(s => s.MonumentName);
var vModel = new MonumentTitleDuplicate();
vModel.MonumentTitle = NmonumentTitle;
vModel.Monument = List_monument.ToList();
if (vModel.Monument.Count == 0)
{
return RedirectToAction("MonumentCreate", new { battleRecord = vModel.MonumentTitle.BattleRecID, callingRecordID = vModel.MonumentTitle.CallingRecID, monumentName = vModel.MonumentTitle.MonumentName });
}
{
return RedirectToAction("MonumentTitleDuplicate", vModel );
}
}
Works for when there is not a duplicate. Where I run into a problem is trying to switch control to "MonumentTitleDuplicate" and pass the model.
[Authorize]
[HttpGet]
public ViewResult MonumentTitleDuplicate(MonumentTitleDuplicate monumentTitleDuplicate)
{
return View("MonumentTitleDuplicate", monumentTitleDuplicate);
}
[HttpPost]
[Authorize]
public ActionResult MonumentTitleDuplicate(MonumentTitle monumentTitle)
{
ViewBag.callingRecordID = monumentTitle.CallingRecID;
return RedirectToAction("MonumentCreate", new { battleRecord = monumentTitle.BattleRecID, callingRecordID = monumentTitle.CallingRecID, monumentName = monumentTitle.MonumentName });
}
[Authorize]
public ActionResult MonumentCreate(string battleRecord, int callingRecordID, string monumentName)
{
Got it -- needed to use TempData to pass the model to the new controller so:
[Authorize]
public ActionResult MonumentTitle(string battleRecordID, int callingRecordID)
{
ViewBag.monumentBattleRecID = battleRecordID; // ID of the battle
ViewBag.battleName = getBattleName(battleRecordID);
var vModel = new MonumentTitle();
vModel.BattleRecID = ViewBag.monumentBattleRecID;
vModel.BattleName = ViewBag.battleName;
vModel.CallingRecID = callingRecordID;
return View(vModel);
}
[HttpPost]
[Authorize]
public ActionResult MonumentTitle(MonumentTitle monumentTitle)
{
ViewBag.callingRecordID = monumentTitle.CallingRecID;
ViewBag.battleName = monumentTitle.BattleName;
ViewBag.MonumentName = monumentTitle.MonumentName;
var NmonumentTitle = monumentTitle;
ViewBag.battleName1 = NmonumentTitle.BattleName;
var List_monument = from s in db.Monuments
where (s.MonumentStatus == "A" &&
s.MonumentBattleRecID == monumentTitle.BattleRecID &&
s.MonumentName == monumentTitle.MonumentName
)
select s;
List_monument = List_monument.OrderBy(s => s.MonumentName);
var vModel = new MonumentTitleDuplicate();
vModel.MonumentTitle = NmonumentTitle;
vModel.Monument = List_monument.ToList();
if (vModel.Monument.Count == 0)
{
return RedirectToAction("MonumentCreate", new { battleRecord = vModel.MonumentTitle.BattleRecID, callingRecordID = vModel.MonumentTitle.CallingRecID, monumentName = vModel.MonumentTitle.MonumentName });
}
{
TempData["monumentTitleDuplicate"] = vModel;
return RedirectToAction("MonumentTitleDuplicate");
}
}
[Authorize]
public ActionResult MonumentTitleDuplicate()
{
MonumentTitleDuplicate monumentTitleDuplicate = TempData["MonumentTitleDuplicate"] as MonumentTitleDuplicate;
return View(monumentTitleDuplicate);
}
[HttpPost]
[Authorize]
public ActionResult MonumentTitleDuplicate(MonumentTitle monumentTitle)
{
ViewBag.callingRecordID = monumentTitle.CallingRecID;
return RedirectToAction("MonumentCreate", new { battleRecord = monumentTitle.BattleRecID, callingRecordID = monumentTitle.CallingRecID, monumentName = monumentTitle.MonumentName });
}
Probably have some cleanup work to do (like getting rid of the stuff where I was trying to use ViewBag), but does appear to be working.

Delete a context record from grid in kendo UI using LINQ

Hi Im using kendo ui grid in my project.
This is my code to insert records in database.
public static void Insert(StudentViewModel student)
{
student.StudentId = All().OrderByDescending(p => p.StudentId).First().StudentId + 1;
//All().Insert(0, student);
UniRegEntities uniRegEntities = new UniRegEntities();
Student stu =new Student();
stu.FName = student.FirstName;
stu.LName = student.LastName;
stu.Gender = uniRegEntities.Genders.Where(x => x.Title == student.Gender).FirstOrDefault();
stu.Id = student.StudentId;
uniRegEntities.Students.Add(stu);
uniRegEntities.SaveChanges();
}
And this is my update statement.
public static void Update(StudentViewModel student)
{
UniRegEntities context = new UniRegEntities();
var studentToUpdate = context.Students.Where(x => x.Id == student.StudentId).FirstOrDefault();
studentToUpdate.FName = student.FirstName;
studentToUpdate.LName = student.LastName;
studentToUpdate.Gender = context.Genders.Where(x => x.Title == student.Gender).FirstOrDefault();
context.SaveChanges();
}
Anyone can suggest me the delete method?
You can either get an entity from the DB and then delete it or create one and then delete it.
So:
var e = // Get
ctx.DeleteObject(e);
ctx.SaveChanges();
or
var e = new Foo() { FooId = id };
ctx.Entity.Attach(e);
ctx.DeleteObject(e);
ctx.SaveChanges();
Applied to your situation:
You are getting a record so you want to use DeleteObject()
public static void Update(StudentViewModel student)
{
UniRegEntities context = new UniRegEntities();
var studentToDelete = context.Students.Where(x => x.Id == student.StudentId).FirstOrDefault();
context.Students.DeleteObject(studentToUpdate);
context.SaveChanges();
}
context.Students.Remove(context.students.Single(x=>x.Id==student.Id));
Can you please try with below code snippet?
using (var db= new AppContext(ConnectionStr))
{
try
{
con.Configuration.AutoDetectChangesEnabled = false;
var o = new Student { StudentId = student.StudentId };
db.Students.Attach(o);
db.Students.Remove(o);
db.SaveChanges();
}
catch (Exception ex)
{
throw new Exception(ex.InnerException.Message);
}
finally
{
con.Configuration.AutoDetectChangesEnabled = true;
}
}

How can I update related tables?

My project involves creating a new hotel room and 2 tables in my database will update. My tables are called RoomType and RoomFacility.
I can successfully update RoomType, but when I try to update RoomFacility and use RoomTypeID to make a new room facility, it fails. I always get 1 for my RoomFacilityID.
How can I update data for both tables, roomType and RoomFacility?
This is the code for my service to update my database
public void UpdateFacilityInRooms(List<int> FacilityIDs, int RoomTypeID)
{
List<HotelRoomFacility> hotelRoomFacilities =
_HotelRoomFacilityRopository.AsQueryable()
.Where(f => f.RoomTypeID == RoomTypeID).ToList();
foreach (int newRoomFacility in FacilityIDs)
{
if (hotelRoomFacilities.Where(h => h.RoomFacilityID == newRoomFacility).Count() == 0)
{
HotelRoomFacility facility = new HotelRoomFacility
{
RoomFacilityID = newRoomFacility,
RoomTypeID = RoomTypeID
};
_HotelRoomFacilityRopository.Add(facility);
}
}
_HotelRoomFacilityRopository.CommitChanges();
}
public RoomType NewRoom(int HotelID,int? RoomTypeID,
string RoomTypeName, string RoomTypeDescription)
{
RoomType room = new RoomType();
room.HotelID = HotelID;
room.RoomTypeID = RoomTypeID ?? 0;
room.RoomtypeName = RoomTypeName;
room.RoomTypeDescripton = RoomTypeDescription;
_RoomTypeRepository.Add(room);
_RoomTypeRepository.CommitChanges();
return room;
}
public RoomType UpdateRoom(int RoomTypeID, string RoomTypeName, string RoomTypeDescription, List<int> RoomFacilityIDs)
{
RoomType roomType = (from rt in _RoomTypeRepository.AsQueryable().Include(r => r.HotelRoomFacilities)
where rt.RoomTypeID == RoomTypeID
select rt).FirstOrDefault();
if (roomType == null)
return null;
roomType.RoomTypeName = RoomTypeName;
roomType.RoomTypeDescripton = RoomTypeDescription;
//Add New Room facilities
List<HotelRoomFacility> hotelRoomFacilities = _HotelRoomFacilityRopository.AsQueryable().Where(f => f.RoomTypeID == RoomTypeID).ToList();
foreach (int newRoomFacilityID in RoomFacilityIDs)
{
if (roomType.HotelRoomFacilities.Where(h => h.RoomFacilityID == newRoomFacilityID).Count() == 0)
{
roomType.HotelRoomFacilities.Add(new HotelRoomFacility
{
RoomFacilityID = newRoomFacilityID
});
}
}
foreach (HotelRoomFacility roomFacility in hotelRoomFacilities)
{
if (RoomFacilityIDs.Contains(roomFacility.RoomFacilityID) == false)
_HotelRoomFacilityRopository.Delete(roomFacility);
}
_RoomTypeRepository.Attach(roomType);
_RoomTypeRepository.CommitChanges();
return roomType;
}

Resources