WebClient SendValues() method changes datetime value - c#

I use WebClient class to send a response acknowledge message in an mvc 3 project. Message is sending from one action method on a project to another projects action method.
Surprisingly the date parameter is 3 hours later, on recieving data.
For example if my sending date is receving data is "2012-08-14 13:42:50Z" i see "2012-08-14 16:42:50Z" on the other side.
Here is a simplified code sample of my case;
NameValueCollection ack = new NameValueCollection();
ack.Add("RESID", form.RESPONSE.ID.ToString());
ack.Add("A_DateTime", DateTime.Now.ToString("u")); //2012-08-14 13:42:50Z
using (var client = new WebClient())
{
client.Encoding = System.Text.Encoding.UTF8;
var result = client.UploadValues("http://localhost:11578/HPM/ResponseAck", ack);
}
//HPM Controller:
ResponseAck(HttpPostResponseAckMessage response)
{
//Here response.Date vale is 2012-08-14 16:42:50Z ???
}
It seems to me its about sneaky little serialization monsters changing it cause of some culture specific issue. But i don't know the real cause so the solution.
Edit:
public class HttpPostResponseAckMessage
{
public int RESID { get; set; }
public DateTime A_DateTime { get; set; }
}

You should either change the culture of the current thread or convert and process all dates in a fixed format such as UTC.
You can change the current culture of the thread using the following code:
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-EN");

Ok, I think its about expecting mvc model binder to parse a formated datetime.
With the "u" format model binder thinks the datetime is UTC.
So my solution will be changing the type of property A_DateTime to string and will parsing it internaly.
Hope this helps someone else like me.
Thanks all.

Related

c# -ModelState.IsValid returns false only when resource language changed?

I have one field on my razor view as following
#Html.TextBoxFor(model => model.Duration, new { #class = "form-control txtSite input-large rounded-custom", name = "Duration", #type = "number", min = "0", id = "durationId", required = "true", Tabindex = "1", value = "0" })
#Html.ValidationMessageFor(model => model.Duration, "", new { style = "color: red" })
I used entity model structure in MVC .The field duration is defined in database table "Activity" (Same model i used on razor) as Float. But the entity metadata shows it as Double as follows.
public Nullable<double> Duration { get; set; }
I used partial class as Activity.cs for required validations as follows
[MetadataTypeAttribute(typeof(Activity.Metadata))]
public partial class Activity
{
internal sealed class Metadata
{
[Required(ErrorMessageResourceType = typeof(Resources.Common), ErrorMessageResourceName = "PleaseEnterDuration")]
public Nullable<double> Duration { get; set; }
}
}
on Controller my code is like this
[HttpPost]
public ActionResult AddActivity(Activity model)
{
if (ModelState.IsValid)
{
//Some Code
}
}
The strange is my code works well for float values when my Resource language to display labels is English and its not working when i change it into another language (french).here ModelState.IsValid returning false. And I am getting error as
"The value 3.5(any float value) is invalid for Duration."
how to fix it for another resource language?. Any help will be appreciated
You are getting that error because your site's culture is set to a language (French) that does not use a dot . as a decimal separator. However the entry for Duration has a dot in it so your model's state is evaluating to invalid.
In other words your site (server side) is in French culture but the browser or whatever client you are using is NOT in French.
Fix
You need to synch the language of the client and the server ON EVERY REQUEST: Make sure your code to set the culture is executed for each request and not just on application startup. The user can switch languages between requests. Setting CurrentCulture to the appropriate language will use that language's numeric formatting, datetime formatting etc.
Additionally, it is suggested but not required to fix your issue, you should also set the CurrentUICulture, it will get labels, messages etc. from your resource file for the language (If you have any resource files).
Follow #orhun.begendi answer above to set the above 2 items.
You can easily override your global.asax.cs file like this
protected void Application_AcquireRequestState(object sender, EventArgs e)
{
//Create culture info object
CultureInfo ci = new CultureInfo("en");
if(Request.Url.Host.Equals("yourdomain.com", StringComparison.InvariantCultureIgnoreCase))
{
ci = new CultureInfo("fr"); //in your case
}
System.Threading.Thread.CurrentThread.CurrentUICulture = ci;
System.Threading.Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(ci.Name);
}
Also you can set in begin_request method.
Further information you can check this link
https://www.codeproject.com/articles/778040/beginners-tutorial-on-globalization-and-localizati

WSDL generated service reference returning null

Im have some issues with a service reference to an external source (added it using the supplied wsdl in Visual Studio 2015).
The situation is that the request i run seems to reach the server fine. I also seems to get a response of the expected xml format (added TextWriterTraceListener). But the OutType class i get back in the code (in this case the GetBankCertificateOutType) is always null.
The console application ive built to illustrate is very simple, utilizing the public test account. It looks as follows:
static void Main(string[] args)
{
//instantiates client from the service reference
var client = new PkiServicePortTypeClient();
var time = DateTime.UtcNow;
Random r = new Random();
string reqId = r.Next(100, 999).ToString();
var outType = client.GetBankCertificate(*full params on github*);
//This line will throw nullexception since outType is always null
//BUT a valid response is actually received (although returning aa application statusCode that represents error at this stage)
var response = outType.GetBankCertificateResponse;
}
Ive tried to locate the problem but have been unsuccessful sofar. So wanted to see if someone has some good tip on how to debug this or perhaps has a solution.
I built a complete, minimal, console sample project (including the source wsdl) to illustrtate the issue which is located here.
I've downloaded and inspected your solution, and I found this in trace.log
GetBankCertificateRequest at tribute {http://www.w3.org/XML/1998/namespace}id had invalid value '360817' of type '{http://www .w3.org/2001/XML Schema}ID'
After I played with id value of GetBankCertificateRequest I got back the right value (instead of null).
var outType = client.GetBankCertificate(new GetBankCertificateInType {
RequestHeader = new RequestHeaderType {
SenderId = "360817",
CustomerId = "360817",
RequestId = reqId,
Environment = EnvironmentType.test,
EnvironmentSpecified = true,
InterfaceVersion = "1",
Timestamp = time
},
GetBankCertificateRequest = new GetBankCertificateRequest {
BankRootCertificateSerialNo = "1111110002",
//id = "",
RequestId = reqId,
Timestamp = time
}
});
There is no description for this property according to documentation (PKI service description v2.3.pdf) except some xml type annotation (xml:id). The concrete schema description is missing.

Same code but getting different result

When I use below code I am getting different result on my developer pc and my remote server.
string _QsDateTime = "12.11.2016 21:30";
var _CountryZone = DateTimeZoneProviders.Tzdb["TUR"];
var _DatePattern = LocalDateTimePattern.CreateWithCurrentCulture("yyyy-MM-dd HH:mm:ss");
var _LocalTime = _DatePattern.Parse(_QsDateTime).Value;
var _LocalTime2TargetZoneTime = _LocalTime.InZoneStrictly(_CountryZone);
var _TargetZone2Utc = _LocalTime2TargetZoneTime.WithZone(DateTimeZone.Utc).ToDateTimeUtc();
_QsDateTime = _TargetZone2Utc.ToString("yyyy-MM-dd HH:mm:ss");
Developer PC result is: "2016-11-12 19:30:00"
Remote server result is: "2016-12-11 19:30:00"
Remote server specs is Windows 2012 server English Developer PC specs is Windows 7 Turkish but both of them regional date time setting are same.
Why I am getting different result?
I'm not too much familiar with Noda Time but I have a few things to say:
DateTimeZoneProviders.Tzdb does not have a time zone identifier as TUR as far as I know, you should use Europe/Istanbul instead.
When you create a LocalDateTimePattern with CreateWithCurrentCulture method, it uses current culture settings and these are different in your both server. Be careful about that.
LocalDateTimePattern.Parse method use the rules of the current pattern. Your string is 12.11.2016 21:30 but your pattern is yyyy-MM-dd HH:mm:ss. You see my point, don't you?
If you really get different results in your servers, you shouldn't blame your last line since both en-US and tr-TR cultures uses GregorianCalendar as a Calendar property and that doesn't effect the result. You might wanna check LocalDateTimePattern.Parse method line instead.
For example;
using System;
using NodaTime;
using NodaTime.Text;
public class Program
{
public static void Main()
{
string _QsDateTime = "12.11.2016 21:30";
var _CountryZone = DateTimeZoneProviders.Tzdb["Europe/Istanbul"];
var _DatePattern = LocalDateTimePattern.CreateWithCurrentCulture("dd.MM.yyyy HH:mm");
var _LocalTime = _DatePattern.Parse(_QsDateTime).Value;
var _LocalTime2TargetZoneTime = _LocalTime.InZoneStrictly(_CountryZone);
var _TargetZone2Utc = _LocalTime2TargetZoneTime.WithZone(DateTimeZone.Utc).ToDateTimeUtc();
_QsDateTime = _TargetZone2Utc.ToString("yyyy-MM-dd HH:mm:ss");
Console.WriteLine(_QsDateTime);
}
}
generates
2016-11-12 19:30:00
Here a demonstration.

Parsing a generic variable from a Json text

I'm trying to parse the info from a json object obtained via api, but in this request, I'm trying to get just one variable. I just want to get the summonerLevel variable.
{
"test": {
"id":107537,
"name":"test",
"profileIconId":785,
"summonerLevel":30,
"revisionDate":1440089189000
}
}
I've been trying to it with this code and I know that if I write
p.summonerLevel = (int)(obj.test.summonerLevel)
it will work, but the problem is that test is not a static name, and it will be changing within each request I do. Any good example on how to do it?
Thanks
WebClient c = new WebClient();
string data = c.DownloadString("https://las.api.pvp.net/api/lol/las/v1.4/summoner/by-name/"+summonerName+"?api_key=<api-key>");
dynamic obj = JsonConvert.DeserializeObject(data);
p.summonerLevel = (int)(obj.tempName.summonerLevel);
Something like this?
int summonerLevel= (int)JObject.Parse(data).First.First["summonerLevel"];

Validate textbox to accept only valid datetime value using DataAnnotations in mvc3

I want to validate a textbox to accept datetime value using DataAnnotations in MVC3. But I don't have any idea how to do it. Given below is what I'm trying to accomplish my requirement and it's not working.
[DataType(DataType.DateTime, ErrorMessage = "Invalid Datetime")]
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy HH:mm}")]
[Display(Name = "Start Datetime")]
public DateTime? StartDateTime { get; set; }
As When I click on submit button after filling corrupted data first problem is that form get post and later it shows the message that "Invalid date" and second if I enter just date without time still form get post but this time it does not shows the message which is also wrong.
So I just want to know how can I validate my textbox to accept datetime in "dd/MM/yyyy HH:mm" format only using MVC DataAnnotations .
1. Your client side validation is not working. You are seeing error message after the form is submitted - means client side validation is not working properly. To make the client side validation work, ASP.NET MVC assumes that you have jquery.validate.js and jquery.validate.unobtrusive.js referenced on the page. You can download them using NuGet Package Manager on your Visual Studio.
2. Date field is not being validated. You are expecting the DisplayFormat to validate the date format for you. But actually it does not. That is more of about displaying your date on the View.
In order to validate the date format, you need to use your own custom Attribute. Or you can simply use RegularExpression attribute. The most simple example looks like this:
[RegularExpression(#"\d{1,2}/\d{1,2}/\d{2,4}\s\d{1,2}:\d{1,2}", ErrorMessage = "")]
Or if you want to make a custom attribute, then:
public class DateFormatValidation : ValidationAttribute{
protected override bool IsValid(object value){
DateTime date;
var format = "0:dd/MM/yyyy HH:mm"
bool parsed = DateTime.TryParseExact((string)value, format, System.Globalization.CultureInfo.InvariantCulture, DateTimeStyles.None, out date)
if(!parsed)
return false;
return true;
}
}
Then use it like:
[DataType(DataType.DateTime, ErrorMessage = "Invalid Datetime")]
[DateFormatValidation]
[Display(Name = "Start Datetime")]
public DateTime? StartDateTime { get; set; }
I got it from diff website, saying its a problem in chrome and he has fixed it by applying this code.
So check first if it works in firefox then you might be forced to apply this code, however this code skips checking the date format.
$.validator.methods["date"] = function (value, element) { return true; }

Categories