Neo4J Readify client/driver: Unable to deserialize object - neo4j

Im getting a error/exception when im trying get a resultset by running the following method:
public IEnumerable<NeoProduct> GetAllProductsUnderCategory(int categoryId)
{
var query = neo.Cypher.Match("(c:Category{CategoryId:{id}})<-[*](p:Product)")
.WithParam("id", categoryId)
.Return(p => p.As<NeoProduct>()).Results;
}
As you can see its a very simple method that returns a list of NeoProducts. NeoProduct is a simple POCO with the following properties:
public int CategoryId { get; set; }
public string CategoryName { get; set; }
public int ParentCategoryId { get; set; }
The stacktrace is:
[OverflowException: Value was either too large or too small for an Int64.]
System.Number.ParseInt64(String value, NumberStyles options, NumberFormatInfo numfmt) +14278344
System.String.System.IConvertible.ToInt64(IFormatProvider provider) +55
System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider) +14285879
Neo4jClient.Serialization.CommonDeserializerMethods.CoerceValue(DeserializationContext context, PropertyInfo propertyInfo, JToken value, IEnumerable`1 typeMappings, Int32 nestingLevel) in D:\temp\tmpC806\Neo4jClient\Serialization\CommonDeserializerMethods.cs:101
Neo4jClient.Serialization.CommonDeserializerMethods.Map(DeserializationContext context, Object targetObject, JToken parentJsonToken, IEnumerable`1 typeMappings, Int32 nestingLevel) in D:\temp\tmpC806\Neo4jClient\Serialization\CommonDeserializerMethods.cs:365
Neo4jClient.Serialization.CommonDeserializerMethods.CreateAndMap(DeserializationContext context, Type type, JToken element, IEnumerable`1 typeMappings, Int32 nestingLevel) in D:\temp\tmpC806\Neo4jClient\Serialization\CommonDeserializerMethods.cs:303
Neo4jClient.Serialization.<>c__DisplayClass17_0.<ParseInSingleColumnMode>b__1(JToken row) in D:\temp\tmpC806\Neo4jClient\Serialization\CypherJsonDeserializer.cs:437
System.Linq.WhereSelectEnumerableIterator`2.MoveNext() +223
System.Linq.Buffer`1..ctor(IEnumerable`1 source) +264
System.Linq.Enumerable.ToArray(IEnumerable`1 source) +106
Neo4jClient.Serialization.CypherJsonDeserializer`1.Deserialize(String content) in D:\temp\tmpC806\Neo4jClient\Serialization\CypherJsonDeserializer.cs:64
[ArgumentException: Neo4j returned a valid response, however Neo4jClient was unable to deserialize into the object structure you supplied.
For the method, I'm passing a argument which returns a result-set containing 900 entities (result is from the Neo4J browser). Otherwise, the method seems to be working as intended.
I suspect that the JSON object is too large for the internal deserializer. Anyone had this problem?

I discovered the problem. There was a entity in the database which had a very long number which was larger than int64 causing the deserializer to throw a exception (was trying to insert a number larger than int64 into a int64 property).
Today's lesson: Make sure the data fit into the model :)

Related

Receiving "Value cannot be null. Parameter name: httpContext" when sending MVC Mailer email from ASP MVC

My MVC Mailer instance is failing when I send from the server. I'm getting the error Value cannot be null.Parameter name: httpContext when I attempt to send an email.
my code looks like this:
public static void SendApproval(TimeOffRequest request)
{
MailService mailer = new MailService();
mailer.ViewData.Model = request;
MvcMailMessage mailMessage = new MvcMailMessage
{
Subject = $"PTO request approved for {request.StartTime} to {request.EndTime}",
From = new MailAddress("calendar#company.com"),
};
mailMessage.To.Add(new MailAddress(request.Requester.Email));
if (mailMessage.To.Count == 0)
return;
mailer.PopulateBody(mailMessage, "RequestApproved");
mailMessage.Send();
}
It's specifically failing on the line mailer.PopulateBody(mailMessage, "RequestApproved");
It is being called from the post of a controller endpoint. Why is the context missing in this scenario? I attempted to manually pass the context and that failed as well.
Heres the top of the stack trace:
System.Web.Routing.RouteCollection.GetRouteData(HttpContextBase httpContext) +505
Mvc.Mailer.MailerBase.CreateControllerContext() +98
Mvc.Mailer.MailerBase.ViewExists(String viewName, String masterName) +127
MVCMailer's PopulateBody method has 3 arguments and 4 arguments overload in MailerBase class (3 arguments version actually calls 4 arguments overload with masterName set as null):
// 3 arguments overload
public virtual void PopulateBody(MailMessage mailMessage, string viewName, Dictionary<string, string> linkedResources)
{
PopulateBody(mailMessage, viewName, null, linkedResources);
}
// 4 arguments overload
public virtual void PopulateBody(MailMessage mailMessage, string viewName, string masterName = null, Dictionary<string, string> linkedResources = null)
{
...
}
Based from that findings, use additional null to fill unnecessary method arguments, either using 3 or 4 arguments version:
// 3 arguments
mailer.PopulateBody(mailMessage, "RequestApproved", null);
// 4 arguments
mailer.PopulateBody(mailMessage, "RequestApproved", null, null);
Since the possible cause originated from MailerBase class (in var routeData = RouteTable.Routes.GetRouteData(CurrentHttpContext); where CurrentHttpContext passed null value), you can see utilization of null-checking for HttpContextBase virtual property in this request.
Similar issue:
MvcMailer unit tests: System.ArgumentNullException httpContext cannot be null

Deleting an entity with a modified enum property with Breeze

I have an issue when I am trying to delete an entity that also has a modified enum property. The error i get is Invalid cast from 'System.String' to 'BV.Entities.CarType'. A simple example follows:
public class Car {
public int Id { get; set; }
public CarType Type { get; set; } // CarType is an enum
}
var car = // load a car entity
car.Type('Sedan');
car.entityAspect.setDeleted();
manager.saveChanges();
This can happen, for example, when a user starts editing a record, but then decides to just delete it.
I have also used the DocCode sample to test this. I edited the saveTodoTests.js and used the 'can save add, update, and delete in one batch' test similar to what was suggested here Exception in client breeze.js when using enum property on model. If I alter the enum type of the deleteTodo item it throws the error, if I remove the setDeleted() it will save it correctly.
System.InvalidCastException was unhandled by user code
HResult=-2147467262
Message=Invalid cast from 'System.String' to 'BV.Entities.CarType'.
Source=mscorlib
StackTrace:
at System.Convert.DefaultToType(IConvertible value, Type targetType, IFormatProvider provider)
at System.String.System.IConvertible.ToType(Type type, IFormatProvider provider)
at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider)
at Breeze.ContextProvider.EF6.EFContextProvider`1.ConvertValue(Object val, Type toType)
at Breeze.ContextProvider.EF6.EFContextProvider`1.SetPropertyValue(Object entity, String propertyName, Object value)
at Breeze.ContextProvider.EF6.EFContextProvider`1.<>c__DisplayClass10.<RestoreOriginal>b__f(KeyValuePair`2 kvp)
at System.Collections.Generic.List`1.ForEach(Action`1 action)
at Breeze.ContextProvider.EF6.EFContextProvider`1.RestoreOriginal(EntityInfo entityInfo)
at Breeze.ContextProvider.EF6.EFContextProvider`1.<ProcessAllDeleted>b__9(EFEntityInfo entityInfo)
at System.Collections.Generic.List`1.ForEach(Action`1 action)
at Breeze.ContextProvider.EF6.EFContextProvider`1.ProcessAllDeleted(List`1 deletedEntities)
at Breeze.ContextProvider.EF6.EFContextProvider`1.SaveChangesCore(SaveWorkState saveWorkState)
at Breeze.ContextProvider.ContextProvider.OpenAndSave(SaveWorkState saveWorkState)
at Breeze.ContextProvider.ContextProvider.SaveChanges(JObject saveBundle, TransactionSettings transactionSettings)
at BV.Web.Controllers.DefaultController.SaveChanges(JObject saveBundle) in c:\Work\Code\BV\BV.Web\Controllers\DefaultController.cs:line 59
Ok, this was a bug and is fixed in the combination of the current breeze.server.net and breeze.js repos on GitHub. It will also go out as part of the next release (1.4.14) sometime next week.

Unit test for integer attribute validation for an Entity Framework object

How to create a unit test to an Entity Framework object to verify an integer attribute validation annotated with the [required] key like this:
[Required]
public Int32 MyIntProperty { get; set; }
The unit test code should be something like this:
EntityObject entityObject = new EntityObject();
entityObject.MyIntProperty = null;
EntityObjectContext.EntityObject.Attach(entityObject);
EntityObjectContext.ObjectStateManager.ChangeObjectState(entityObject, EntityState.Added);
var dbContext = new DbContext(EntityObjectContext, true);
int errors = dbContext.GetValidationErrors().Count();
Assert.AreEqual(1, errors);
The problem is that I can not indicate the null value to an integer property. Is it possible to tests this validation another way?
Tks.
If the validation fails only on null then there is nothing to test here, as Int32 will never be null. If you want to make it possible to be null change it's type to Int32? (or better: int?). If the validation fails for some other reasons, then don't put null into your property but some other erroneous value.
Int32 cannot be null unless it Int32?.
I don't know if the following suits your requirement but Int32 would be 0 when not initialised.
Assert.AreNotEqual(0, error);
I resolve my problem by testing if the property was annotated by the [Required] key word:
var propertyInfo = typeof(EntityObject).GetProperty("MyIntProperty");
var attribute = (EdmScalarPropertyAttribute)
propertyInfo.GetCustomAttributes(
typeof(EdmScalarPropertyAttribute), true)
.FirstOrDefault();
Assert.IsFalse(attribute.IsNullable);
If anyone have other solution please tell me.
Tks.

Getting NullReferenceException when assigning an entity to another one in EF

I'm getting the exception in the second line of the following:
var proceso = procesoService.GetEntityById(_codigoProceso);
var bitacora = new BitacoraEjecucionProceso
{
Mensaje = mensaje,
Fecha = DateTime.Now,
Resultado = resultado,
Proceso = proceso
};
The complete stacktrace of the exception is:
System.NullReferenceException: Object reference not set to an instance of an object.
at System.Data.Objects.EntitySetQualifiedType.GetHashCode(EntitySetQualifiedType obj)
at System.Collections.Generic.Dictionary`2.FindEntry(TKey key)
at System.Collections.Generic.Dictionary`2.ContainsKey(TKey key)
at System.Data.Objects.ObjectStateManager.AddStateManagerTypeMetadata(EntitySet entitySet, ObjectTypeMapping mapping)
at System.Data.Objects.ObjectStateManager.GetOrAddStateManagerTypeMetadata(Type entityType, EntitySet entitySet)
at System.Data.Objects.ObjectStateManager.AddEntry(IEntityWrapper wrappedObject, EntityKey passedKey, EntitySet entitySet, String argumentName, Boolean isAdded)
at System.Data.Objects.ObjectContext.AddSingleObject(EntitySet entitySet, IEntityWrapper wrappedEntity, String argumentName)
at System.Data.Objects.DataClasses.RelatedEnd.AddEntityToObjectStateManager(IEntityWrapper wrappedEntity, Boolean doAttach)
at System.Data.Objects.DataClasses.RelatedEnd.AddGraphToObjectStateManager(IEntityWrapper wrappedEntity, Boolean relationshipAlreadyExists, Boolean addRelationshipAsUnchanged, Boolean doAttach)
at System.Data.Objects.DataClasses.RelatedEnd.Add(IEntityWrapper wrappedTarget, Boolean applyConstraints, Boolean addRelationshipAsUnchanged, Boolean relationshipAlreadyExists, Boolean allowModifyingOtherEndOfRelationship, Boolean forceForeignKeyChanges)
at System.Data.Objects.DataClasses.RelatedEnd.Add(IEntityWrapper wrappedEntity, Boolean applyConstraints)
at System.Data.Objects.DataClasses.EntityReference`1.set_ReferenceValue(IEntityWrapper value)
at System.Data.Objects.DataClasses.EntityReference`1.set_Value(TEntity value)
at Aseinfo.VH4.Data.BitacoraEjecucionProceso.set_Proceso(Proceso value) in C:\vh4\VH4\Data\AppDataContext.Designer.cs:line 16295
I've checked the EF source and have no clue why getting the hash code of my entity is throwing a NullReference..
Any ideas??
Thx!
I discovered what was happening. My DLL was not updated because I was using external CSDL, SSDL and MSL files.

How can I keep an object that was returned from an already disposed of DataContext?

Get User Action
[HttpGet]
[ActionName("Index")]
public ActionResult Get(int id)
{
User u = UserCore.GetUser(id);
if (u == null)
return Content("user not found", "text/plain");
return new XmlResult(u);
}
UserCore.GetUser
public static User GetUser(int UserID)
{
using (PanamaDataContext db = new PanamaDataContext())
{
return (from u in db.Users where u.UserID == UserID select u).FirstOrDefault();
}
}
The Route
routes.MapRoute(
"GetUser",
"user/{id}",
new { controller = "Users", action = "Index" }
);
And finally the test URLs
/user/9000 returns "user not found" as expected (does not exist currently)
/user/75 (actually exists in the DB) however returns:
Cannot access a disposed object. Object name: 'DataContext accessed
after Dispose.'.
[ObjectDisposedException: Cannot access a disposed object. Object
name: 'DataContext accessed after Dispose.'.]
System.Data.Linq.DataContext.GetTable(Type type) +1020550
System.Data.Linq.CommonDataServices.GetDataMemberQuery(MetaDataMember
member, Expression[] keyValues) +120
System.Data.Linq.DeferredSourceFactory1.ExecuteKeyQuery(Object[]
keyValues) +258
System.Data.Linq.DeferredSourceFactory1.Execute(Object instance) +928
System.Data.Linq.DeferredSource.GetEnumerator() +53
System.Data.Linq.EntitySet1.Load() +112
System.Data.Linq.EntitySet1.get_Count() +9
Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterUser.Write14_User(String
n, String ns, User o, Boolean isNullable, Boolean needType) +5060
Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterUser.Write15_User(Object
o) +144
[InvalidOperationException: There was an error generating the XML
document.]
System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter,
Object o, XmlSerializerNamespaces namespaces, String encodingStyle,
String id) +646
System.Xml.Serialization.XmlSerializer.Serialize(TextWriter
textWriter, Object o, XmlSerializerNamespaces namespaces) +72
System.Xml.Serialization.XmlSerializer.Serialize(TextWriter
textWriter, Object o) +10 ...
I'm assuming this is because the referenced object no longer exists but what can I do? Somehow copy the object that is returned from the DataContext?
Either way it should be returning XML and not that error.
You should use view models. Basically you should construct a view model inside the lifetime of the DataContext and pass this view model to the view result (in your case the XmlResult). This view model should be constructed by mapping properties of the actual domain model returned by your datacontext and all this should happen inside this context lifetime. Ayende Rahien has a great series of blog posts about view models (It's for NHibernate but the problem of disposed context is exactly the same as with EF data datacontexts).
You need to eagerly include the child rows using the Include() method.

Resources