I want to fine-tune the results in the controller action with a few parameters coming from client.
I was following this answer.
The problem is the logs variable returns no results even if all the parameters are not there (I expect it to return all the records). It works perfectly fine I do
return View(db.Logs.ToList());
But my implementation of the answer by Darren Kopp doesn't return anything at all. My code:
Category cat;
DateTime startDate;
DateTime endDate;
var logs = from log in db.Logs
select log;
if (Enum.TryParse<Category>(viewModel.Category, out cat))
logs = logs.Where(l => l.LogCategory == cat);
if (DateTime.TryParse(viewModel.StartDate, out startDate))
logs = logs.Where(l => l.TimeStamp >= startDate);
return View(logs.ToList());
I am using VS 2015 & this is MVC 5. What is causing the problem?
Related
I am working on implementing a full calendar with RavenDB.
I do a simple, as usual anonymous return of a model.
public JsonResult GetHolidays()
{
return Json(Session.Query<Models.Holiday>().Select(d => new
{
id = d.Id,
title = d.Name,
start = d.DateStart,
end = d.DateEnd,
allDay = true
}), JsonRequestBehavior.AllowGet);
}
I set allDay to true but my result is false. (I point my broswer to the controller /Home/GetHolidays and that is the result string, I have done this many times before to make sure the JSON is correct)
[{"id":"holidays/97","title":"Piotr Test 2 - 1","start":"\/Date(1405284740420)\/","end":"\/Date(1405543940420)\/","allDay":false},{"id":"holidays/98","title":"Piotr Test 10 - 26","start":"\/Date(1404593542266)\/","end":"\/Date(1407703942266)\/","allDay":false},{"id":"holidays/99","title":"Piotr Test 3 - 0","start":"\/Date(1405198343713)\/","end":"\/Date(1405457543713)\/","allDay":false}]
I have done this so many times. Why is the result coming back as false?
Even if I set it to false it stays false. I cleared the cache and restarted a lot. Not sure why this is happening. Anybody knows what I am doing wrong?
RavenDB doesn't provide a way to select user supplied values from the index.
Your query try to do a (trivially simple, but still) computation during the query, and RavenDB doesn't support that.
You can add that property after the query returns from RavenDB.
Not completely sure how this influences the Anonymous type, but you MUST use .ToList() after query to RavenDB Session.
Its like the anonymous type originated/inherited from the model of the DB ... ? Not sure how to explain this behaviour.
public JsonResult GetHolidays()
{
return Json(Session.Query<Models.Holiday>()**.ToList()**.Select(d => new
{
id = d.Id,
title = d.Name,
start = d.DateStart,
end = d.DateEnd,
allDay = true
}), JsonRequestBehavior.AllowGet);
}
Below is the code in question. I receive Object reference not set to an instance of an object. on the where clause inside the Linq query. However, this only happens after it goes through and builds my viewpage.
Meaning: If I step through using debugger, I can watch it pull the correct order I am filtering for, go to the correct ViewPage, fill in the model/table with the correct filtered item, and THEN it comes back to my Controller and shows me the error.
public ActionResult OrderIndex(string searchBy, string search)
{
var orders = repositoryOrder.GetOpenOrderList();
if (Request.QueryString["FilterOrderNumber"] != null)
{
var ordersFiltered = from n in orders
where n.OrderNumber.ToUpper().Contains(Request.QueryString["FilterOrderNumber"].ToUpper().ToString())
select n;
return View(ordersFiltered);
}
return View(orders);
}
its always better to manipulate your strings and other things outside the linq query ,
please refer : http://msdn.microsoft.com/en-us/library/bb738550.aspx
from the readability point of view also its not good ,
public ActionResult OrderIndex(string searchBy, string search)
{
var orders = repositoryOrder.GetOpenOrderList();
var orderNumber = Request.QueryString["FilterOrderNumber"];
if (!string.IsNullOrEmpty(orderNumber))
{
orderNumber = orderNumber.ToUpper();
var ordersFiltered = from n in orders
where n.OrderNumber.ToUpper().Contains(orderNumber)
select n;
return View(ordersFiltered);
}
return View(orders);
}
Your query is not being executed in your Action method because you don't have a ToList (or equivalent) added to your query. When your code returns, your query will be enumerated somewhere in your view and that's the point where the error occurs.
Try adding ToList to your query like this to force query execution in your action method:
var ordersFiltered = (from n in orders
where n.OrderNumber.ToUpper().Contains(Request.QueryString["FilterOrderNumber"].ToUpper().ToString())
select n).ToList();
What's going wrong is that a part of your where clause is null. This could be your query string parameter. Try moving the Request.QueryString part out of your query and into a temporary variable. If that's not the case make sure that your orders have an OrderNumber.
You both were right. Just separately.
This fixed my problem
var ordersFiltered = (from n in orders
where !string.IsNullOrEmpty(n.OrderNumber) && n.OrderNumber.ToUpper().Contains(Request.QueryString["FilterOrderNumber"].ToUpper().ToString())
select n);
I have just started using Neo4jClient and Cypher and surprisingly I don't find any example on the net that's using the DateTime filed in the the cypher query where clause .
when I an trying to get some nodes filtered on a DateTime property, the query is not returning any results, here is an example of what I was trying:
Say I am looking for all make employees in HR deportment whose Date of birth is within a time range. the query I am trying to build is as shown below.
client.Cypher
.Start(new { company = companyNode.Reference})
.Match("(department)<-[:BELONGS_TO]-(employee)-[:BELONGS_TO]->(company)")
.Where<Department>(department=>department.Name=='Human Resource')
.AndWhere<Employee>(employee=> employee.DOB >= searchStart && employee.DOB<= searchEnd)
.ReturnDistinct((employee)=> new {name = employee.Name});
here Employee->DOB/searchStart/searchEnd are all DateTimeOffset fields and the data stored in the graph via the neo4jclient is represented as "1990-09-28T19:02:21.7576376+05:30"
when i am debugging the code I see that Neo4jClient is actually representing the query as something like this
AND ((employee.DOB >=10/3/1988 8:16:41 PM +03:00) AND (employee.DOB <=10/3/2003 8:16:41 PM +03:00))
when I get rid of the DOB where clause i do get results.
I would really appreciate if someone can point me to how the DateTimeOffset property can be used in the queries.
Regards, Kiran
Using the DateTimeOffset works fine for me:
private static IList<Node<DateOffsetNode>> Between(IGraphClient client, DateTimeOffset from, DateTimeOffset to)
{
ICypherFluentQuery<Node<DateOffsetNode>> query = new CypherFluentQuery(client)
.Start(new { n = All.Nodes })
.Where((DateOffsetNode n) => n.Date <= to && n.Date >= from)
.Return<Node<DateOffsetNode>>("n");
return query.Results.ToList();
}
Where DateOffsetNode is just:
public class DateOffsetNode { public DateTimeOffset Date { get;set; } }
But another way is to store the ticks value and compare with that instead:
.Where((DateObj o) => o.Ticks < DateTime.Now.Date.Ticks)
I typically define DateObj like:
public class DateObj {
public long Ticks { get;set; }
public int Year { get;set; }
public int Month { get;set;}
public int Day { get;set;}
public DateObj(){}
public DateObj(DateTime dt){
Ticks = dt.Date.Ticks;
Year = dt.Date.Year;
Month = dt.Date.Month;
Day = dt.Date.Day;
}
}
So I can also do things like:
.Where((DateObj o) => o.Year == 2013)
The equivalent for a time is to use something like the TotalMilliseconds property on the DateTime object as well:
.Where((TimeObj o) => o.TimeMs < DateTime.Now.TimeOfDay.TotalMilliseconds)
There's also whole chunk of the O'Reilly book about Neo4J (that they give an electronic copy of away free from the Neo4J Site here: http://www.neo4j.org/learn) about managing dates, which I believe echoes the information in the blog linked to above. I.e. they recommend putting dates into the database as nodes (i..e. year nodes with relationships to month nodes, with relationships to day nodes) and then linking all date sensitive nodes to the relevant day.
Would get a bit painful if you want to measure things in Milliseconds, though...
I'm having some trouble working with dates.
I have an object with a date field:
public DateTime FechaInicio{get; set;}
This definition generates the following field in the database:
FechaInicio datetime not null
Making the request to the web service I get the date ( in the JSON ) in the following format:
"FechaInicio": "1982-12-02T00: 00:00"
And calling FechaInicio() on tne entity returns a javascript Date object.
Creating a new entity I get the following value:
createPalanca var = function () {
MetadataStore var = manager.metadataStore;
metadataStore.getEntityType palancaType = var ("Toggle");
palancaType.createEntity newPalanca = var ();
manager.addEntity (newPalanca);
//Here: newPalanca.FechaInicio () has the value in this format: 1355313343214
//Expected Date object here
newPalanca return;
};
After all, my real question is: What format should I use to assign new values to date type fields?
Edit:
After doing some tests, I noticed that if I assign a Date object to the property, everything seems fine until we got to this line:
saveBundleStringified var = JSON.stringify (saveBundle);
saveBundle content is:
FechaInicio: Thu Dec 20 2012 00:00:00 GMT+0100 (Hora estándar romance)
and the saveBundleStringified:
"FechaInicio": "2012-12-19T23:00:00.000Z" <- I guess this is utc format
What finally is stored in the database is: 2012-12-19 23:00:00.0000000
When the result of the call to SaveChanges are returned , they are merged with the entities in cache at the function updateEntity which does this check: if (!core.isDate(val)) that returns false.
As a consequence it is created a new Date object with the wrong date:
function fastDateParse(y, m, d, h, i, s, ms){ //2012 12 19 23 00 00 ""
return new Date(y, m - 1, d, h || 0, i || 0, s || 0, ms || 0);
}
Correct me if I'm wrong, but I think that's the problem.
Sorry for taking so long...
There were bugs with Breeze's DateTime timezone serialization and the default DateTime values used for newly constructed entities with non-nullable date fields. These are fixed as of v 0.77.2. Please confirm if this set of fixes works for you.
And thanks for finding these.
And to answer your question, all date properties on your object should be set to javascript Dates. Breeze should handle all of the serialization issues properly.
Dates always scare me. My immediate instinct is that the browser and server are not on the same TimeZone; how that could be I don't know. In any case, it's bound to happen and I recall all kinds of fundamental problems with coordinating client and server on datetime. I think the usual recommendation has always been to keep everything in UTC and adjust what you display to the user in local time.
I rather doubt this is a helpful answer. I'm not sure what part Breeze should play in resolving this. Would welcome a suggestion that we can circulate and build consensus around.
Also can you clarify this statement:
When the result of the call to SaveChanges are returned , they are merged with the entities in cache at the function updateEntity which does this check: if (!core.isDate(val)) that returns false. As a consequence it is created a new Date object with the wrong date
What do you mean by "the wrong date"? And are you saying that Breeze thinks the incoming date value is in an invalid format (as opposed to being a date other than the one you expected)?
Yes, #Sascha, Breeze is using the Web Api standard for JSON formatting (Json.Net) and it is set for ISO8601 format as opposed to the wacky Microsoft format (which escapes me as I write this).
Breeze/Web Api seem to need the dates in some special format (ISO8601). Any other format did not work for me. moment.js solved the problem for me with setting and reading. Formatting is also nicely done if you use Knockout to display the date with a special binding.
entity.someDate(moment().utc().toDate()) // example
and it works.
You could also use this:
Date.prototype.setISO8601 = function(string) {
var regexp = "([0-9]{4})(-([0-9]{2})(-([0-9]{2})" +
"(T([0-9]{2}):([0-9]{2})(:([0-9]{2})(\.([0-9]+))?)?" +
"(Z|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?";
var d = string.match(new RegExp(regexp));
var offset = 0;
var date = new Date(d[1], 0, 1);
if (d[3]) {
date.setMonth(d[3] - 1);
}
if (d[5]) {
date.setDate(d[5]);
}
if (d[7]) {
date.setHours(d[7]);
}
if (d[8]) {
date.setMinutes(d[8]);
}
if (d[10]) {
date.setSeconds(d[10]);
}
if (d[12]) {
date.setMilliseconds(Number("0." + d[12]) * 1000);
}
if (d[14]) {
offset = (Number(d[16]) * 60) + Number(d[17]);
offset *= ((d[15] == '-') ? 1 : -1);
}
offset -= date.getTimezoneOffset();
time = (Number(date) + (offset * 60 * 1000));
this.setTime(Number(time));
};
To the question started, my code (I'll try to only include relevant portions to start), starting with my script:
function RaceDate_onChange() {
var pickedDate = $(this).data('tDatePicker').value();
var month = pickedDate.getMonth() + 1;
$.get("/RaceCard/Details?year=" + pickedDate.getFullYear() + "&month=" + month + "&day=" + pickedDate.getDate());
}
Then my markup:
#Html.Telerik().DatePickerFor(model => model.RaceDate).ClientEvents(events => events.OnChange("RaceDate_onChange"))
And finally a bit of the receiving action:
[HttpGet]
public ActionResult Details(int year, int month, int day)
{
var viewModel = new RaceCardModel {Metadata = DetailModelMetadata.Display, RaceDate = new DateTime(year, month, day)};
I'm trying to get the selection of a new date to trigger a GET, to refresh the page without submitting a form. This works fine, except for this problem:
In GET requests to the Details action, the day value is always one day behind the DatePicker. E.g. The first value is set from a view model property, when the view is rendered, say 3. I then click on 14 and hit my breakpoint in the action method. The day value is 3. When I click on 29 and hit the breakpoint, the day value is 14.
Besides asking what is wrong, I'll take a liberty and ask if there is a better way that is no more complicated. I am fairly novice and would rather deliver working code that needs revision than get bogged down in tangents and details.
Try using e.value instead as shown in the client-side events example. You are probably using an older version where the value() method returned the previous value during the OnChange event.
UPDATE:
"e.value" means the value field of the OnChange arguments:
function onChange(e) {
var date = e.value; // instead of datePicker.value()
}
As far as the 1 month difference you are getting, that's normal, and it is how the getMonth() method works in javascript on a Date instance:
The value returned by getMonth is an
integer between 0 and 11. 0
corresponds to January, 1 to February,
and so on.
So adding +1 is the correct way to cope with the situation, exactly as you did.
Just a little remark about your AJAX call: never hardcode urls. Always use url helpers when dealing with urls:
var year = pickedDate.getFullYear();
var month = pickedDate.getMonth() + 1;
var day = pickedDate.getDate();
var url = '#Url.Action("Details", "RaceCard")';
$.get(url, { year: year, month: month, day: day }, function(result) {
// process the results of the AJAX call
});