Working with date time in web api - mysql

I have created a WEB APIusing MySQL database. The table includes the data about the meter's serial numbers it's signal strength values and the date time on which the signal strength has comes. For now i am successful in getting data by sending the meter's serial number.
Now I am also sending the date time parameter to it also. But it's not working for me. Below is what i have done.
public HttpResponseMessage GetByMsn(string msn, DateTime dt)
{
try
{
return Request.CreateResponse(HttpStatusCode.Found, medEntitites.tj_xhqd.Where(m=> m.msn == msn).Where(a=> a.date_time < dt ));
}
catch (Exception ex)
{
return Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
}
}
The WebApiConfig file includes
config.Routes.MapHttpRoute(
name: "GetByMsn",
routeTemplate: "api/{controller}/{action}/{msn}/{dt}",
defaults: null,
constraints: new { msn = #"^[0-9]+$" , dt = #"^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$" }
);
After that I am passing the URL like http://localhost:14909/api/meters/GetByMsn/000029000033/2017-10-06T07:52:27
The error I am getting is A potentially dangerous Request.Path value was detected from the client (:).
For this I have also searched for the solutions but couldn't find out the correct one. Also I have replaced : in date time but still it's not working for me
Update 1
While passing only date2017-10-06 it works for me but when I append it with time it doesn't works
For a quick check I checked this question but still i am unable to solve the solution.
I must be missing something that I don't know
Any help would be highly appreciated.

After a lot of searching I finally found a solution.
I have changed the predefined disallowed/invalid characters in my Web.config. Under , added the following: <httpRuntime requestPathInvalidCharacters="<,>,%,&,*,\,?" />. I've removed the : from the standard list of invalid characters.
For more information see this solution

Related

java.lang.NumberFormatException: For input string: "04/12/2012 14:44"

I have a programme with the following code:
In XXX.java, I set the SVC_APPR_DT_IN_MILLIS with the date value obtained from a record in Oracle database using String.valueOf(date.getTime()) strong text. It is stored as a String:
private void setApprovalDateProperty(Date date) {
setAdditionalProperty(SVC_APPR_DT_IN_MILLIS, String.valueOf(date.getTime()));
}
In YYY.java, I return the Date back by using new Date(Long.valueOf())
private Date getApprovalDate() throws ParseException {
String approvalDateInMillis = this.record
.getAdditionalProperty(XXX.SVC_APPR_DT_IN_MILLIS);
return new Date(Long.valueOf(approvalDateInMillis));
}
For one of the record, It throws below error, where "04/12/2012 14:44:38" is the date of the records in database.
For input string: "04/12/2012 14:44"
java.lang.NumberFormatException: For input string: "04/12/2012 14:44"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
at java.lang.Long.parseLong(Long.java:412)
at java.lang.Long.valueOf(Long.java:518)
at YYY.getApprovalDate(YYY.java:634)
I have checked the database, many records in the database can be processed without any problem, except this one. May I know what is the possible cause of this error? I want to simulate the problem but I have no idea how to replicate it. Anyone has any suggestions?
It sounds like one of the records in the database has been inserted with a faulty version, or that the database is corrupt.
Have you checked what the value of approvalDateInMillis is before the call to Long.valueOf?
You could add e.g.
if (!approvalDateInMillis.matches("^[0-9+]$"))
throw new Error(
String.format("Invalid approvalDateInMillis format: '%s'", approvalDateInMillis));
before the return statement and then continue debugging to see what is really in the database.

Dapper And System.Data.OleDb DbType.Date throwing 'OleDbException : Data type mismatch in criteria expression'

Not sure if I should raise an issue regarding this, so thought I would ask if anybody knew a simple workaround for this first. I am getting an error when I try to use Dapper with OleDbConnection when used in combination with MS Access 2003 (Jet.4.0) (not my choice of database!)
When running the test code below I get an exception 'OleDbException : Data type mismatch in criteria expression'
var count = 0;
using (var conn = new OleDbConnection(connString)) {
conn.Open();
var qry = conn.Query<TestTable>("select * from testtable where CreatedOn <= #CreatedOn;", new { CreatedOn = DateTime.Now });
count = qry.Count();
}
I believe from experience in the past with OleDb dates, is that when setting the DbType to Date, it then changes internally the value for OleDbType property to OleDbTimeStamp instead of OleDbType.Date. I understand this is not because of Dapper, but what 'could' be considered a strange way of linking internally in the OleDbParameter class
When dealing with this either using other ORMs, raw ADO or my own factory objects, I would clean up the command object just prior to running the command and change the OleDbType to Date.
This is not possible with Dapper as far as I can see as the command object appears to be internal. Unfortunately I have not had time to learn the dynamic generation stuff, so I could be missing something simple or I might suggest a fix and contribute rather than simply raise an issue.
Any thoughts?
Lee
It's an old thread but I had the same problem: Access doesn't like DateTime with milliseconds, so you have to add and extension method like this :
public static DateTime Floor(this DateTime date, TimeSpan span)
{
long ticks = date.Ticks / span.Ticks;
return new DateTime(ticks * span.Ticks, date.Kind);
}
And use it when passing parameters:
var qry = conn.Query<TestTable>("select * from testtable where CreatedOn <= #CreatedOn;", new { CreatedOn = DateTime.Now.Floor(TimeSpan.FromSeconds(1)) });
Unfortunately, with current Dapper version (1.42), we cannot add custom TypeHandler for base types (see #206).
If you can modify Dapper (use the cs file and not the DLL) merge this pull request and then you do not have to use Floor on each parameters :
public class DateTimeTypeHandler : SqlMapper.TypeHandler<DateTime>
{
public override DateTime Parse(object value)
{
if (value == null || value is DBNull)
{
return default(DateTime);
}
return (DateTime)value;
}
public override void SetValue(IDbDataParameter parameter, DateTime value)
{
parameter.DbType = DbType.DateTime;
parameter.Value = value.Floor(TimeSpan.FromSeconds(1));
}
}
SqlMapper.AddTypeHandler<DateTime>(new DateTimeTypeHandler());

Cannot add an identity that already exists

I'm using C#4.0 in a simple expense recording app. I'm trying to save to a table with an auto incremented id field, set as the primary key. It works fine the first time I use it, but the second and subsequent time, I get the "Cannot add an identity that already exists" error.
Here's the code I'm having trouble with
public bool SaveClaim(Claim newClaim, bool blNew)
{
bool blSuccess = true;
try
{
expContext.Claims.InsertOnSubmit(newClaim);
expContext.SubmitChanges();
claim = null;
}
catch (Exception e)
{
blSuccess = false;
MessageBox.Show(e.ToString());
}
return blSuccess;
}
I've been working on this all morning, and it's driving me daft. I'd be glad for any help.
Ensure you have the following properties set in your dbml for the identity column of Claim:
Auto Generated Value = true
Auto-Sync = OnInsert
Also ensure that your new Claim object is actually a new object, and not a reuse of the one you previously added.
Maybe you should try updating your designer.
Remove the table Claim, update the server explorer, and add it again.
At least that's what I do when I get this error. It usually shows when I set the identity column on the database after compiling.
Maybe you are trying to UPDATE newClaim using the INSERT method.
If newClaim has an ID and the method expContext.Claims.InsertOnSubmit(newClaim) is trying to insert a record with that ID. That could be the issue.
if (blNew)
expContext.Claims.InsertOnSubmit(newClaim);
else
expContext.Claims.UpdateOnSubmit(newClaim); //-- Assumed method
Additional
Here is a useful thread: MSDN Forums
if (blNew)
{
expContext.Claims.InsertOnSubmit(newClaim);
}

Grails: can I make a validator apply to create only (not update/edit)

I have a domain class that needs to have a date after the day it is created in one of its fields.
class myClass {
Date startDate
String iAmGonnaChangeThisInSeveralDays
static constraints = {
iAmGonnaChangeThisInSeveralDays(nullable:true)
startDate(validator:{
def now = new Date()
def roundedDay = DateUtils.round(now, Calendar.DATE)
def checkAgainst
if(roundedDay>now){
Calendar cal = Calendar.getInstance();
cal.setTime(roundedDay);
cal.add(Calendar.DAY_OF_YEAR, -1); // <--
checkAgainst = cal.getTime();
}
else checkAgainst = roundedDay
return (it >= checkAgainst)
})
}
}
So several days later when I change only the string and call save the save fails because the validator is rechecking the date and it is now in the past. Can I set the validator to fire only on create, or is there some way I can change it to detect if we are creating or editing/updating?
#Rob H
I am not entirely sure how to use your answer. I have the following code causing this error:
myInstance.iAmGonnaChangeThisInSeveralDays = "nachos"
myInstance.save()
if(myInstance.hasErrors()){
println "This keeps happening because of the stupid date problem"
}
You can check if the id is set as an indicator of whether it's a new non-persistent instance or an existing persistent instance:
startDate(validator:{ date, obj ->
if (obj.id) {
// don't check existing instances
return
}
def now = new Date()
...
}
One option might be to specify which properties you want to be validated. From the documentation:
The validate method accepts an
optional List argument which may
contain the names of the properties
that should be validated. When a List
is passed to the validate method, only
the properties defined in the List
will be validated.
Example:
// when saving for the first time:
myInstance.startDate = new Date()
if(myInstance.validate() && myInstance.save()) { ... }
// when updating later
myInstance.iAmGonnaChangeThisInSeveralDays = 'New Value'
myInstance.validate(['iAmGonnaChangeThisInSeveralDays'])
if(myInstance.hasErrors() || !myInstance.save(validate: false)) {
// handle errors
} else {
// handle success
}
This feels a bit hacky, since you're bypassing some built-in Grails goodness. You'll want to be cautious that you aren't bypassing any necessary validation on the domain that would normally happen if you were to just call save(). I'd be interested in seeing others' solutions if there are more elegant ones.
Note: I really don't recommend using save(validate: false) if you can avoid it. It's bound to cause some unforeseen negative consequence down the road unless you're very careful about how you use it. If you can find an alternative, by all means use it instead.

How to work with zero dates ("0000-00-00") in Hibernate?

I have MySql table that has a date field with zeroes ("0000-00-00") as its default value (field cannot be null, I can't change table structure). Hibernate doesn't like zero dates and throws exception during read or save.
I managed to make it read records by setting MySql connection setting "zeroDateTimeBehavior=convertToNull" that converts zero dates to nulls while retrieving records. It is all working fine until I try to save the record that has null date - it throws exception that date cannot be null.
So the question is - how to save record through Hibernate so date will appear as zeroes in a table?
Thanks.
I'd try to add an Hibernate Interceptor (API, Doc) and try to implement something in the onSave() method.
The following code may work:
static final Date ZERO_DATE = //0000-00-00
public boolean onSave(Object entity,
Serializable id,
Object[] state,
String[] propertyNames,
Type[] types)
throws CallbackException {
for(int i = 0; i< propertyNames.length; i++) {
if(propertyNames[i].equals("dateFieldName") && state[i]==null) {
state[i] = ZERO_DATE;
return; //or may continue, if there are several such fields.
}
}
}
Ready and working solution for DATE '0000-00-00' and TIME '00:00:00': How to map MySQL DATE '0000-00-00' & TIME '00:00:00' with Hibernate
Thanks Preston for the code and ChssPly76 for useful comments.