I have the following function signuture:
public JsonResult PopulateGrid(int page, Guid? accountId, Guid? systemUserId, Guid? branchId, DateTime? fromDate, DateTime? toDate, HomeVisitType? homeVisitType)
Every single parameter is bound just fine except toDate which turns out to be always null.
When inspecting the Request.QueryString["toDate"] it retrives the right value which is 30/09/2010.
It seems that DateTime expects another format when binding.
What is the right format?
A quick test on my system shows that it expects the data in MM/DD/YYYY and not DD/MM/YYYY which is probably why you're having problems. My guess is that if you try the same date on the fromDate you'll also have the same null issue.
I've changed the current culture in my app to one that uses the DD/MM/YYYY and it seemed to have no effect. Seems to have the same problem with the , decimal for a language that uses 10,01 instead of 10.01...
Update from someone a developer on the ASP.Net team.
"This is intentional. Anything that is part of the URI (note the 'Uniform' in URI) is interpreted as if it were coming from the invariant culture. This is so that a user in the U.S. who copies a link and sends it over IM to a friend in the U.K. can be confident that his friend will see the exact same page (as opposed to an HTTP 500 due to a DateTime conversion error, for example). In general, dates passed in RouteData or QueryString should be in the format yyyy-mm-dd so as to be unambiguous across cultures.
If you need to interpret a QueryString or RouteData parameter in a culture-aware manner, pull it in as a string, then convert it to the desired type manually, passing in the desired culture. (DateTime.Parse has overloads that allow you to specify a culture.) If you do this, I recommend also taking the desired culture as a QueryString or a RouteData parameter so that the 'Uniform' part of URI isn't lost, e.g. the URL will look something like ...?culture=fr-fr&date=01-10-1990."
Related
I have a TimeSpan property on an object which binds to a time value in a SQL Server database using EF Core. I would like to have an input on a form in an ASP.NET Core 2.2 MVC project where a user can enter a time value such as "9:00 AM" and bind it to this TimeSpan property. The built in property binding in MVC does not handle this well. Could someone provide sample code to add a way to setup binding to TimeSpan properties without having to manually receive and convert the property in the post controller method?
Generally speaking, there's the DisplayFormat attribute that can be applied to your property:
[DisplayFormat(DataFormatString = "{0:hh:mm tt}", ApplyFormatInEditMode = true)]
public TimeSpan MyTimeSpan { get; set; }
The ApplyFormatInEditMode property of the attribute determines whether this format will be used for parsing the value as well.
However, you've also got to contend with some HTML5-specific stuff here. By default, a TimeSpan property will be rendered as an input of type "time". Which modern browsers will replace with a time control. It will be localized to the user, allowing entry of 12 hour and AM/PM where appropriate. However, the value of this input must be in ISO format: hh:mm:ss (24-hour time, no AM/PM). If you set the value of the input to something like 9:00 AM instead of 09:00:00, then it will be treated by the browser as the same as null, and the control will be rendered unset with any value.
Additionally, relying on a specific binding format leaves no room for user variances in input. If one user enters the time in 24-hour format, the binding will fail when it hits the server, because it won't be in the expected format. You'd need to have custom client-side validation to ensure that the user sticks to the appropriate format.
Your best bet is to simply send and receive ISO (hh:mm:ss). Client-side then, you can either rely on the browser control and/or progressively enhance the input with some JS library for time entry. Under the hood, you'll be dealing only with ISO times, but then you can present a localized user-focused format for display/entry.
I'm writing DateTime Formatter in ASP.NET MVC and need to format the datetime based on cultural info.
My model's property binds DateTime.Now volue to the view and as a result the view is displaying 3/21/2017 9:38:37 AM as a datetime.
I'm looking for the way to display 3/21/2017 or 21/3/2017 and etc based on the culture.
What is the best way to do it. I tried a few examples from
https://msdn.microsoft.com/en-us/library/5hh873ya(v=vs.90).aspx
<span>String.Format("{0:d}", #Model.ToString())</span>
But the view still display the full datetime value: 3/21/2017 9:38:37 AM
I know that might be easy question but anywhere need some input on that.
What is the best way to handle something like that?
C# has come helpers built into the DateTime class. You can do this to only get the date.
DateTime.Now.ToShortDateString();
Or using your code assuming mode is an instance of DateTime:
#Model.ToShortDateString()
I have an action method with the following signature,
ActionResult Search(string searchQuery)
This gets called from a partial view on button submit from a form. Problem is, please look at the 2 patterns below. When I submit my search key from my page it uses the following url (suppose search key is tool)
Search/?searchQuery=tool
But then if I click on a tool then,
Search/tool?searchQuery=garden
Now my method is reading tool in the parameter instead of garden (which is expected of course). I presume this is to do with incorrect presentation of items from both the context of the item itself and that of search.
Is there a nice way of resolving this issue? I want to read the query string term and search for it from the main search context i.e. Search/?searchQuery=<term> no matter where I am.
To get the QueryString, in your controller you should write something like this:
var mystring =Request.QueryString["searchQuery"];
This will get the query string no matter where is placed in your url.
Rename the input to
ActionResult Search(string searchQuery)
The model binder will then deserialize the query string param to that input value. It will work for both route params and query string params.
I want to display multiple languages and UI cultures on my website. I have enabled the IIS 7 flag which picks up culture from the browser automatically as so:
<globalization
enableClientBasedCulture="true"
culture="en-GB"
uiCulture="auto:en"/>
This works perfectly in that the correct Resources files are loaded, and the correct culture is displayed (0.00 for GB; 0,00 for DE).
However this has had an unexpected problem of interferring with my external services, for example here is the code for interfacing with PayPal.
var paymentDetails = new PaymentDetailsType
{
ItemTotal = new BasicAmountType
{
currencyID = currencyCode,
Value = basket.SubTotal.ToString("0.00")
},
...
}
This code basically creates a string formatted like so '50.25', however as PayPal always requires a dot decimal point, when a culture is selected that has a comma as a decimal point (for example DE - German) the ToString("0.00") generates '50,25' and so my code fails.
What would be the best method to correct this? I still want the culture set to the user's culture, however I want to set certain parts of my code to use my own culture.
I know I can feed in a specific culture to the ToString() method, but this seems very hackish. Any more professional clean approaches?
Have a look at the InvariantCulture.
Value = basket.SubTotal.ToString("0.00", CultureInfo.InvariantCulture)
Here's a link to the overload of ToString() that takes a second System.IFormatProvider parameter:
http://msdn.microsoft.com/en-us/library/d8ztz0sa.aspx
The server is hosting Asp.net mvc3 app and the Browser culture is set to da (Danish)
GET request url: /get?d=1.1 (note that the decimal separator is .)
return: da;1,1 (note that the decimal separator is ,)
GET request url: /get?d=1,1 (the decimal separator is ,)
return: Exception Details: System.ArgumentException: The parameters dictionary contains a null entry for parameter 'd' of non-nullable type 'System.Decimal' for method 'System.Web.Mvc.ContentResult get(System.Decimal)' in 'Intranet.Controllers.OrderController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter. Parameter name: parameters
But given the same input to a post request, the results are exactly opposite.
POST request url: /get2 (form data d=1.1)
return: Exception ...
POST request url: /get2 (form data d=1,1)
return: da;1,1
I suppose the POST request is working as expected. But why does the GET request behave differently? How does the default model binder work in this case.
When you send the data through a post, the locales take effect. When you send the data through a GET, it always uses the invariant locale.
It seems this is done because you could copy and paste an URL, and send it to someone in another country. If the language of the browser was considered when a parameter is included in the URL (GET) the URL would break (it's more obvious if you think about date formats than decimal separators).
Among other places, it's mentioned here by a member of the .Net team: http://forums.asp.net/t/1461209.aspx/1?Nullable+DateTime+Action+Parameters+Parsed+in+US+format+irrespective+of+locale+