Get local datetime instead of server DateTime in server side code C# - c#

I am using ASP MVC 4.5. I have view to input payment details. I use C# to get current time when user input payment. But after hosting it on server, i found a hot error. It gets another dateTime (may be my server's time) instead of my user's local time!
I want to get user's current time using C#. Should i use C# or javascript?
I think it is easy to get user's time using javascript. But i want to use C# for this. Can you help me?
My web API:
// POST api/PaymentApi
public HttpResponseMessage PostPayment(Payment payment)
{
if (ModelState.IsValid)
{
var mem= db.Members.Where(m => m.MemberID.Equals(payment.MemberID)).FirstOrDefault();
if (mem ==null)
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
}
payment.Date = DateTime.Now;
db.Payments.Add(payment);
db.SaveChanges();
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, payment);
response.Headers.Location = new Uri(Url.Link("DefaultApi", new { id = payment.PaymentID }));
return response;
}
else
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
}
}
I used payment.Date = DateTime.Now.ToLocalTime(); also but not worked!
Many of here answered to use javascript date. That's why i used it. But javascript sends a datetime and my WebApi makes it slightly different.
Javascript: Date:Tue Dec 27 2016 11:04:12 GMT+0600 (Local Standard Time)
C#: Date:{27/12/2016 05:04:12}

It's impossible to get client DateTime at server-side if client is not sending it by itself.

You'll need to get the local date time in javascript and pass it to the server. I recommend you to use ISO8601 format.

DateTime works with local host's clock, e.g. the server. Most payments systems save the dates as relative to UTC, to avoid client/server time differences.
payment.Date = DateTime.UtcNow;

There isn't any way to know the user Local time from the server. What you need to do is send the local time from the client to the server inside the request in UTC format.
Javascript(requires Jquery):
var UTC = new Date().getTime();

Related

BraintreePayments API Query Transactions for a given date

I am trying to query transactions in Braintree Gateway using BraintreePayments API .NET SDK.
There is a note in the documentation which says:
https://developers.braintreepayments.com/reference/request/transaction/search/dotnet
"Time zones specified in the time value will be respected in the search; if you do not specify a time zone, the search will default to the time zone associated with your gateway account. Results will always be returned with time values in UTC"
How can this be specified in the search request API call?
var searchRequest = new TransactionSearchRequest().
CreatedAt.GreaterThanOrEqualTo(DateTime.Now.AddDays(-1));
ResourceCollection<Transaction> results = gateway.Transaction.Search(searchRequest);
Full disclosure: I work at Braintree. If you have any further questions, feel free to contact
support.
According to Microsoft .NET docs, you can use the ConvertTime(DateTime, TimeZoneInfo) method to convert your DateTime object from your time zone to a different time zone.
You could proceed as follows:
// Retrieve the time zone for Eastern Standard Time (U.S. and Canada).
TimeZoneInfo est;
try {
est = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
}
catch (TimeZoneNotFoundException) {
Console.WriteLine("Unable to retrieve the Eastern Standard time zone.");
return;
}
catch (InvalidTimeZoneException) {
Console.WriteLine("Unable to retrieve the Eastern Standard time zone.");
return;
}
//Create a converted time zone DateTime object
DateTime targetTime = TimeZoneInfo.ConvertTime(timeToConvert, est);
//Run search request
var searchRequest = new TransactionSearchRequest().
CreatedAt.GreaterThanOrEqualTo(targetTime.AddDays(-1));

c# how to only get updated objects from web api

I'm polling data to my angular app from a c# web api. Every time all data is polled, even though much of the data haven't changed. I would like to poll only the objects which have actually been updated in any sort of way.
This is my code in my Controller.cs
//Get all details of the available vehicles
[HttpGet]
[Route("api/details")]
public object GetFleetStatusDetails()
{
var fmsData = this.fmsdb.Value.GetFleetStatusDetails();
var data = fmsData.Entries;
List<VehicleDetails> result = new List<VehicleDetails>();
foreach (var item in data)
{
if (item != null)
{
var details = ConvertVehicleDetail(item);
result.Add(details);
}
}
return result;
}
As you can see im converting the data into VehicleDetails which I later add to my VehicleDetails list. The data im getting is in JSON-format. Is there a way of comparing my last poll with the current poll without going to much deeper down into the database? If so how would I do that?
I suggest saving the last state either through the Browser's local storage or using ngrx.
Without knowing what this.fmsdb.Value.GetFleetStatusDetails(); does or the schema of the database you're calling the best guess answer would be to create two endpoints in the API.
The first would use this.fmsdb.Value.GetFleetStatusDetails(); to get the full set of results. Once the data has been downloaded from the endpoint store the current date/time in the angular view and pass that to the second endpoint...
The second endpoint would get the records that have been changed since the date/time you got the first set of data. This assumes that you are storing the updated date time.
[HttpGet]
[Route("api/updateddetails")]
public object GetUpdatedFleetStatusDetails([FromUrl]DateTime date)
{
var fmsData = this.fmsdb.Value.GetUpdatedFleetStatusDetails(date);
return fmsData.Entries
.Where(x => x != null)
.Select(ConvertVehicleDetail);
}
Could give more details if knew what was in this.fmsdb.Value.GetFleetStatusDetails()
PS Haven't tested this code.

Paypal Api is not redirecting to Express Checkout for the first time payment second time its working fine

My code is written in the C# and I am using Paypal API. for the first time I am making payment from customer then it is redirecting to old paypal page having link
https://www.sandbox.paypal.com/in/cgi-bin/webscr?cmd=_flow&SESSION=gVpVeQy6t1RsmlfDy408oT6n3EL6CXLn3bNYG11jzbks50fwd_qYHvqGcdS&dispatch=50a222a57771920b6a3d7b606239e4d529b525e0b7e69bf0224adecfb0124e9b61f737ba21b0819862118003bc2f4b4f47f01ef0a11094f0
I am debugging the code and receiving the express checkout address "paypal /cgi-bin/webscr?cmd=_express-checkout&token=EC-4M157930054026038" But its redirecting to old paypal page although its working fine when i make payment secont time with same account. But for the first time with new user its getting redirected to old payment page
Here is my paypal code
if (string.IsNullOrEmpty(token1))
{
// Need to be corrected.
DateTime date = DateTime.Now;
Agreement agreement = this.oService.CreateBillingAgreement(apiContext1, Plans1, UserID, date, systemdate).Create(apiContext1);
List<Links>.Enumerator enumerator = agreement.links.GetEnumerator();
while (enumerator.MoveNext())
{
Links current = enumerator.Current;
if (current.rel.ToLower().Trim().Equals("approval_url"))
url1 = current.href;
}
this.Session.Add(name1, (object)agreement.token);
//this.Session.Add(name1, "EC-3LA67769U69944606");
////token1 = "EC-3LA67769U69944606";
this.Session["PlanId"] = (object)agreement.plan.id;
return (ActionResult)this.Redirect(url1);
}
This is the expected behavior as per paypal.
Refer to this ticket : https://www.paypal-techsupport.com/app/account/questions/detail/i_id/1327025
I hope this is the same problem you are facing.

Respond with 304 - Client-side Caching using ASP.NET Webservices

I am developing my application in ASP.NET 4.5. I setup a webservice. The webservice get accessed by Jquery using a GET Ajax call. The function has a 'id' parameter and for each id it returns different content.
I want to cache that data both on server and client. On client I already know how to use 'CacheDuration' but the problem is with the client side. I use HttpFox to get the headers of each response.
I've setup the following code at the beginning of the function:
HttpCachePolicy cache = HttpContext.Current.Response.Cache;
cache.SetCacheability(HttpCacheability.Private);
cache.SetExpires(DateTime.Now.AddMinutes((double)10));
cache.SetMaxAge(new TimeSpan(0, 0, 10));
FieldInfo maxAgeField = cache.GetType().GetField(
"_maxAge", BindingFlags.Instance | BindingFlags.NonPublic);
maxAgeField.SetValue(cache, new TimeSpan(0, 10, 0));
What I want to do is to prevent the client from sending a request again for the same ID, and do that for let's say.. 10 minutes. So at the first call the request will be made and we get response 200. At the second time the response header should be 304.
Right now the code above doesn't do that and I want to know how to achieve that. Again, I am talking on client-side caching that return 304, so it want go to the server again for the same 'id' until the cache is expired.
I know that it can be done using the code, so please don't submit IIS type of solutions.
Need your help to solve this.
You will need to implement the last modified header
Response.Cache.SetLastModified(lastWriteTime.Value.ToUniversalTime());
This will allow your client to check for last modified values and not refetch.
You could in theory fake the last modified time to the nearest 10 mins by using
public static DateTime Round10(this DateTime value)
{
var ticksIn10Mins = TimeSpan.FromMinutes(10).Ticks;
DateTime dtReturn = (value.Ticks % ticksIn10Mins == 0) ? value : new DateTime((value.Ticks / ticksIn15Mins + 1) * ticksIn10Mins);
if(dtReturn > DateTime.Now())
{
return dtReturn.AddMinutes(-10);
} else {
return dtReturn;
}
}
Response.Cache.SetLastModified(Round10(DateTime.Now);
This code is untested though

How to get user local time at Page_Load

I have a web page written in ASP.NET and I need to retrieve the end user's local time at Page_Load. I thought about using Javascript to get the local time (by using new Date()) but the problem is that the script is run after the server events.
Any ideas on how to accomplish this?
EDIT: My page is quite complex: it displays a chart with lots of calculated fields from a database, object/fields selection lists, etc; The customer now requested that it should consider the user's timezone and that the timezone should be determined automatically by the web page. The user date is important to determine the chart interval (which day to display data on).
Data loading (since it is so complicated) is done in both Page_Load and Page_PreRender. Giving up these events would require a full page rewrite.
FINAL SOLUTION INSPIRED BY ANSWER:
Here is how I solved the problem eventually. I am keeping the local date in a cookie. Here is the method that sets the cookie:
function SetLocalDateCookie() {
var cookieName = 'LOCALDATE';
var localDate = new Date();
var realMonth = localDate.getMonth() + 1;
var localDateString = localDate.getFullYear() + "/" + realMonth + "/" + localDate.getDate();
setCookie(cookieName, localDateString, 2);
try {
var exdate = new Date();
exdate.setDate(exdate.getDate() + 2);
document.cookie = cookieName + "=" + escape(localDateString) + ";expires=" + exdate.toGMTString();
}
catch (e)
{ }
}
In my Master page I call this method on $(document).ready.
On the page where I use this cookie I added the following code to Page_Init:
if (string.IsNullOrEmpty(CookieHandler.Instance.GetCookie(CookieKeys.LocalDate)))
{
Response.ClearContent();
Response.Write(#"<form id='local' method='post' name='local'>
<script type='text/javascript'>
SetLocalDateCookie();
document.getElementById('local').submit();
</script>
</form>");
Response.Flush();
Response.End();
}
Then I can just use the cookie value in the C# code.
Thank you for your answers/comments!
I'll explain a bit the following code and what lefts for you to do.
At the first request off this page, the code checks if the LocalTime is not already stored in Session and if not it will write a form element, a hidden input and a javascript which will post that form with the local time. The response ends, so your report won't get the chance to be generated.
This submit will immediately create a POST request with the localTime set, then ASP .Net stores this POST value into the Session.
I also added a 302 redirect (Response.Redirect) to the original page, because of the usability. The User made initially a GET request, not a POST, so if he/she wants to refresh the page, the browser will reiterate the last action, which was that form.submit() and not the GET request.
You have now the local time. But you don't have to read it at every request since it can be compared to the UTC time, then with the server's time.
edit: You need to parse the UTC time into a DateTime, but probably it's easy to find the format, though might depend on the user's culture (not sure about this statement).
public ReportPage()
{
this.Init += (o, e) =>
{
// if the local time is not saved yet in Session and the request has not posted the localTime
if (Session["localTime"] == null && String.IsNullOrEmpty(Request.Params["localTime"]))
{
// then clear the content and write some html, a javascript code which submits the local time
Response.ClearContent();
Response.Write(#"<form id='local' method='post' name='local'>
<input type='hidden' id='localTime' name='localTime' />
<script type='text/javascript'>
document.getElementById('localTime').value = new Date();
document.getElementById('local').submit();
</script>
</form>");
//
Response.Flush();
// end the response so PageLoad, PagePreRender etc won't be executed
Response.End();
}
else
{
// if the request contains the localtime, then save it in Session
if (Request.Params["localTime"] != null)
{
Session["localTime"] = Request.Params["localTime"];
// and redirect back to the original url
Response.Redirect(Request.RawUrl);
}
}
};
}
I don't think this would be possible, you can't get the time off the client's local machine at server side.
The only way to achieve this would be using some javascript (as this is client based, so it will use the client's current date/time). But as you've stated, this will be after your server events have been ran, and your web page has been rendered into HTML and sent to the client.
One alternative would be to capture the clients time before the Post Back, but it wouldn't be possible to do this with an inital Page_Load.
How about you place a hidden textbox on the page, attach an OnChange-eventhandler to it in C# and use an OnLoad JavaScript function to set the value to the value you need from the client?
As far as I'm aware, there isn't any way to get the users local time in the Page_Load event as that is executed on the server-side, and would therefore only be aware of the server's local date time.
To get the user's local time you would need to either execute an asynchronous call to the server upon the page loading in JavaScript, or store the local time in a hidden field and then read it on post-back.
Or just use an interstitial page that contains nothing but the js to get local time and redirects to your current page passing the time information via query string or session variable or post

Categories