Getting timestamp() value using C# client - neo4jclient

Just a quick one, I have a node that gets a value set using the value of timestamp(), when I query for the node using
public List<Thing> ListThings()
{
return client.Cypher
.Match("(thing:Thing)")
.Return<Thing>("thing").Results.ToList();
}
I have a class called Thing that looks like this:
public class Thing{
public string name {get; set;}
public int id {get;set;}
public DateTimeOffset timestamp{get;set}
}
We create the 'thing' ahead of time by using:
Create(thing:Thing{id:6,name:'thing1', timestamp:timestamp()}) return thing
I get every value back apart from timestamp when calling from my script, which is a little annoying, any ideas? I get all the values back using the query in Neo4j browser, so I was wondering if I was actually doing something wrong?
Thanks

Tatham is right, the timestamp() returns a long that's not convertible into DateTimeOffset or DateTime. One of the problems is that the returned value is Milliseconds since 1/1/1970, so you need to calculate that, unfortunately, JSON.Net can't do that automagically.
If you can change your Thing class you could have a property that isn't serialized but is calculated by the Timestamp property, something like this:
public class Thing
{
private static DateTime _epoch = new DateTime(1970, 1, 1);
public string id { get; set; }
public string name { get; set; }
private long _ts;
public long timestamp
{
get { return _ts; }
set
{
_ts = value;
TimestampAsDateTime = _epoch.AddMilliseconds(_ts);
}
}
[JsonIgnore]
public DateTime TimestampAsDateTime { get; set; }
}
The TimestampAsDateTime property would only ever be available in your code.

If you go to the Neo4j console and just run RETURN timestamp(), you'll see the result is a number like 1440468541547. That can't be de-serialized to a DateTimeOffset, especially as there's no offset component. You'll need to use a different type in C#: probably long, or maybe DateTime.

Thank you for your excellent answers, you solved the problem, but I am using a slightly overlooked (on my part) solution.
As the data type for timestamp() is long I am just going to return that from the service. We have the ability to handle that perfectly using the clients in-built Date object.
It was a mistake on my part, I wrongly assumed that timestamp would have been DateTime, but then I got an error about it and was advised to use DateTimeOffset, which I did, never really considered long as an option.
Please remember I am from a MSSQL background and some things, although easier to do, take a different perspective to grasp.
Thanks to you both though, appreciate the time taken to assist.

Related

How to use an optional, generic parameter on a controller action?

I am working with a BaseController that is used for a variety of entities. They may have int or string primary keys, represented by <TPk>.
E.g.:
[HttpGet]
public ActionResult Create(TPk id)
{
return View();
}
Everything is fine until I try and use TPk as an optional parameter.
[HttpGet]
public ActionResult Create(TPk id = default(TPk))
{
return View();
}
It seems that the 'optional' part isn't working.
So /controller/create/2 is fine, but /controller/create gives me the following error:
The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult Create(Int32)'
The optional works fine with an int or string id. I can call /controller/create/2 AND /controller/create.
But using a generic type argument TPk, the parameterless route no longer works.
What I've Tried
I have tried making the TPk parameter nullable, but it won't compile:
The type 'TPk' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method 'Nullable'
I have tried changing the parameter name from id to altId as per this question - no joy
I have tried calling the same method, in exactly the same way, but with non-generic parameters. E.g.:
public virtual async Task<ActionResult> Create(int id = default(int))
This worked fine.
I have tried creating a simple new project to isolate this code. (Shown below). This still gives problems with the parameterless version.
Simple Code Test
Controller
public abstract class BaseController<TPk> : Controller
{
public ActionResult Create(TPk id = default(TPk))
{
return View();
}
}
public class NewsController : BaseController<int>
{
}
Entity Classes
public class BaseDataModel<TPk>
{
public TPk Id { get; set; }
public string Title { get; set; }
}
public class PageDataModel : BaseDataModel<string>
{
public string Content { get; set; }
}
public class NewsDataModel : BaseDataModel<int>
{
public DateTime Date { get; set; }
}
Asp.net conventions are heavily based on reflection. So this might explain the behavior. I have not tested if it realy does not work, but I am sure at this state you already tried to create a new project (POC) to preclude any custom code.
Maybe it can be fixed by looking deeper into the routing (method selection) and ModelBinder source code...
I would just create a different DuplicateRecord action instead.
If you do not understand your method without this comment, it is a good indication, that your current code probably smells anyway. (You are doing to much at the same thing):
// duplicates existing record if id is passed in, otherwise from scratch
Extract the shared things to another method (maybe even a service class) and have for each difference a seperate method.
That said, the idea of a generic CrudController is lovely, I tried this myself some years ago. But in trying so I have introduced all sort of generic parameters, strategy patterns, event delegates to make all possibilities possible.
What happens if you need a join?
What happens if you need a transaction?
How do you handle errors?
What happens if your crud logic needs 1, 2, 3 ... additional parameters to decide what to do?
Soft Delete / Hard Delete?
Cascade Delete / Restrict Delete?
What happens if you ...
I have written so much code, it was blessing to revert to the good old non generic code. And if abstracted away in a service, the ActionMethods realy do not need to get big.
public async Task<IActionResult> CreateProduct(CancellationToken ct, ProductCreateModel model)
{
var result = await _productService.CreateAsync(model, ct);
//create response with some helpers... probably some ActionFilters
}
Generics can work ofcorse in a simple crud mapping where each View has exact one Entity, but it does not scale very well. So beaware and think twice about what you realy want ;)

How to build Dynamic Linq from Request.QueryString?

I'm currently working on feature to implement/build a filter through Request.QueryString. The idea here is the filter can be on any property with in the Model For ex.,
public class Alert{
public string Name;
public string Status;
public Datetime StartDate;
public Datetime EndDate;
public bool IsActive;
}
so the calling client wants to pass something like this in the query string startdate >=2013-10-1&Name=John&IsActive=false. I'm using System.Linq.Dynamic from Scottgu to build the where clause which takes a string but the format to build is kind of killing me. I need some pointers on the format and I'm doing the type checking through reflection before executing this and also I'm filtering this against the data that came back from DB and not passing this into the db.Any help is really appreciated!
Don't reinvent the wheel if you don't need to :P
Have a look at Odata, and the .net web.api
That should do what you need.

Form Action Posting null

My baldness is growing more rapidly than it should be. I first posted this question a couple days ago. I now know the problem and have it working... sort of. Another problem surfaced in it's place.
To solve the previous problem, I manually created the name to requestedDays[{0}].DateOfLeave where {0} was a Guid. This allowed my controller to properly receive the List<> of values.
Using this article's method, the name generated is requestedDays[{0}].DayRequested.DateOfLeave which my controller doesn't properly receive because the name has the class in it, DayRequested.DateOfLeave.
[Authorize, HttpPost]
public ActionResult Create(LeaveRequest leaveRequest, List<DayRequested> requestedDays)
{
}
I have tried to figure out work-arounds with the manual generation, but nothing I have tried works thus far. You can see my validation method here. I do know about the second part of Sanderson's article on validation however, it is quite hard to validate something that isn't being passed into the method.
This is my ViewModel I am using in my partial view.
public class LeaveRequestRow
{
public LeaveRequestRow(DayRequested dayRequested, List<SelectListItem> leaveRequestType)
{
this.DayRequested = dayRequested;
this.LeaveRequestType = leaveRequestType;
}
public List<SelectListItem> LeaveRequestType { set; get; }
public DayRequested DayRequested { set; get; }
}
Does anyone have any ideas on how to proceed? Should I convert my dropdown to a jQuery build control and stop using the ViewModel?
Binding 1-N controller arguments of complex types can be kind of tricky.
Your code examples are not meshing with my fried end of day Friday brain but I'll give it a shot.
Assuming the LeaveRequest class looks like this:
public class LeaveRequest {
public string Text { get; set; }
public string Number { get; set; }
}
The posted form keys must be:
leaveRequest.Text
leaveRequset.Number
That is the easy part. The 1-N binding of a list of DayRequested gets a little weird. Say the DayRequested object looks like this:
public class DayRequested {
public string Words { get; set; }
public string Data { get; set; }
}
Your posted form keys look like:
requestedDays[0].Data
requestedDays[0].Words
requestedDays[1].Data
requestedDays[1].Words
requestedDays[2].Data
requestedDays[2].Words
requestedDays[3].Data
requestedDays[3].Words
The default MVC binder should then trun all 10 form values into your two method arguments ... a POCO and a List of POCOs.
I have solved this, though not as elegantly as I had hoped. All TextBoxFor had to be changed to TextBox along with the addtional changes needed with doing this. The names then were correctly generated and I could move on. This did break the ability for the validation message to appear next to the field, though ValidationSummary still does work. I will be working on fixing that later on and post code samples and a solution on my website.

Cannot delete entity with ComplexType property (Entity Framework 4)

This has been driving me nuts for a week now.
I have a class that looks like this:
public class SuggestionVote
{
public virtual int ID { get; set; }
public virtual Suggestion Suggestion { get; set; }
public virtual User User { get; set; }
public virtual VoteTypeWrapper VoteType { get; set; }
public virtual DateTime DateVoted { get; set; }
// Equality overrides omitted
}
VoteTypeWrapper is actually an enum wrapper based on an article on how to fake enums in Entity Framework 4 and looks like this:
public class VoteTypeWrapper
{
private VoteType _type;
public int Value
{
get { return (int)_type; }
set { _type = (VoteType)value; }
}
public VoteType EnumValue
{
get { return _type; }
set { _type = value; }
}
public static implicit operator VoteTypeWrapper(VoteType voteType)
{
return new VoteTypeWrapper { EnumValue = voteType };
}
public static implicit operator VoteType(VoteTypeWrapper voteTypeWrapper)
{
return voteTypeWrapper == null ? VoteType.NotVoted : voteTypeWrapper.EnumValue;
}
}
with the VoteType enumeration being:
public enum VoteType
{
Up,
Down,
NotVoted
}
I've also defined a ComplexType in the model designer:
<ComplexType Name="VoteTypeWrapper" >
<Property Type="Int32" Name="Value" Nullable="false" />
</ComplexType>
The voting system I'm implementing works somewhat like StackOverflow's voting system: The user can vote up or down; voting a second time undoes the previous vote, and voting in the opposite direction (i.e., down when previously voted up) undoes the vote as well.
Now for the problem. Voting once works like a charm and all the values are correctly saved to the database. Undoing a vote, however, refuses to work. To undo a vote I basically mark the vote to undo for deletion and then call SaveChanges on the context.
As soon as I do that an InvalidOperationException occurs giving me the following message:
The entity of type 'System.Data.Entity.DynamicProxies.SuggestionVote_4A3949F5B95E9A51567509467230FD7CEA0FB7761C3AC9C8C2BBC62BCAA033AF'
references the same complex object of type 'Web.Model.VoteTypeWrapper' more than once.
Complex objects cannot be referenced multiple times by the same entity.
I just don't get it. Down anyone know what I could be doing wrong? I've been Googleing for day but to no avail
Well, I've finally decided to work around it but simply mapping an int property instead of a ComplexType. I have also added a (non-mapped) helper property to avoid having to cast constantly from int to VoteType.
I would still love to get an answer for my problem so if you can help it I would appreciate it. I'll give it a couple of days before I mark my own answer as correct.
EDIT: Since I've gotten no answer whatsoever to this, m marking my own answer as good.
I've just encountered the same problem. I have a class that contains a complex type that contains another complex type. Let's call them Class1, Complex1 and ChildComplex. My scenario is the following (I don't know if it matches yours, but the error message is exactly the same).
I retrieve from the context an instance of Class1 and perform a change in a property of Complex1. I then call SaveChanges to the context and get the same exception :
The entity of type '<Class1>' references the same complex object of type '<Complex2>' more than once.
Complex objects cannot be referenced multiple times by the same entity.
I have not found a decent workaround other than cloning the Complex1 instance, replacing the cloned version in the Class1 instance and then making the change. That way EF does not complain that it's the same complex object.
This is a really strange behaviour. If I have time (around 2038) I'll try to isolate it and report it to MS, smells like a bug...
I've just been searching for this same issue, but I've just realized I was misreading the error. Its not complaining that your entity has two properties of the same type, its complaining that your storing the 'exact' same object of that type in both properties.
In my case I was doing a lookup on an table to get my complex type, and I now realize that if the lookup returned the same value it would be the same object.
I fixed this by creating a new object of my complex type and setting its values to the same as the lookup.

Creating an ActionLink with a DateTime in the query string in ASP.NET MVC

I have a search form with a DateTime search criterion, plus some other criteria:
<form method="get" action="/app/search">
<input type="text" value="13/01/2010" name="BeginDate"/>
<input type="text" value="blah" name="SomeOtherCriterion"/>
<form>
So I have a Search controller with a default Action (let's call it Index) and with a SearchCriteria parameter.
public class SearchController
{
public ActionResult Index(SearchCriteria searchCriteria) {//blah }
}
public class SearchCriteria
{
public DateTime BeginDate {get; set;}
public string SomeOtherCriterion {get; set;}
}
Now if I want to create an ActionLink, passing in a SearchCriteria value, thus:
Html.ActionLink("Search", "Index", searchCriteria)
I get the BeginDate query string parameter in US format. Looking on Google and poking around in System.Web.Routing using Reflector it seems to be because it uses the InvariantCulture, so there's nothing I can do about it.
It seems like noone has asked this question before so I guess I'm doing something very stupid.... Please help!
EDIT: Pass in SearchCriteria to ActionLink rather than anonymous object to show why I can't just do the custom ToString() myself.
Given that the framework appears to be hard-coded to handle this piece of data using InvariantCulture, I don't think there's much you can do to make it work transparently.
There is one ugly option - download the MVC source and rip out the code for all the offending classes from Route down to ParsedRoute to create your own RouteBase implementation that does what you need.
If I absolutely had to keep the DateTime declaration on the SearchCriteria class, then that's the route (sorry for the pun) I would choose.
However, a far easier solution would be to change your SearchCriteria class to use a slightly different declaration for the DateTime field, based on a type like this:
public class MyDateTime
{
public DateTime Value { get; set; }
//for passing MyDateTime in place of a DateTime without casting
public static implicit operator DateTime(MyDateTime instance) { return instance.Value; }
//so you can assign a MyDateTime from a DateTime without a cast
//- e.g. MyDateTime dt = DateTime.Now
public static implicit operator MyDateTime(DateTime instance) { return new MyDateTime() { Value = instance }; }
//override ToString so that CultureInfo.CurrentCulture is used correctly.
public override string ToString()
{
return Value.ToString(CultureInfo.CurrentUICulture);
}
}
In theory you should be able to roll out this change without too much fuss.
The big work could be if you have a lot of code that uses members (e.g. .Days etc) of the DateTime instance in SearchCriteria: you either have to reproduce those members on MyDateTime, wrapping around the inner DateTime Value or change all the code to use .Value.Member.
To avoid issues related to Regional Settings and "Culture",
I treat date and time as separate unbound fields and then
assemble them into DateTime in my Controller.
Example:
Year [ ] Month [ ] Day [ ]
I always present separate textboxes for year, month, and day, in that order so that there can be no confusion between U.S. format (month/day/year) and more or less the rest of the world's format (day/month/year).
Can you provide a formatted date in your ActionLink? Try this:
Html.ActionLink("Search",
"Index",
new {BeginDate =
DateTime.Now.ToString("d", new CultureInfo("pt-BR");})
Of course this changes BeginDate to a string instead of a DateTime... but maybe that will work for you?
We use ISO ("s" in a format string -- YYYY-MM-DDTHH:MM:SS) format for this. It works correctly, and JavaScript can handle it as well.
Perhaps you could use a Model Binder to format and parse the date? Just re-read the article and noticed that it does not format the date...Probably not going to work out. I'll leave the answer though in case it provides any unintentional inspiration :)
poking around in System.Web.Routing using Reflector it
seems to be because it uses the
InvariantCulture
Are you realy shure about this? The parts of Modelbinding and UrlBuilding I checked used CurrentCulture. Can you check what happens if you set the CurrentCulture before rendering the link?
Get the ASP.NET MVC 1.0 book written by Scott Hanselman, Scott Guthrie, Phil Haack, and Rob Conery. They actually do this exact scenario in the book. They use a specific route. I am looking at it right now on page 216.
They do it by breaking up day, month, and year. Then it is your responsibility to use those values as they come back.

Resources