Recent Comments


re: Right To Left (RTL) Text Display in Angular and ASP.NET
Tuesday @ 7:03am | by Theo

Any thoughts on support for vertical text for Asian languages?
re: Right To Left (RTL) Text Display in Angular and ASP.NET
Tuesday @ 5:32am | by Vahid

Twitter detects direction of the entered text and then it changes the direction of the input box automatically (client side):
https://github.com/twitter/RTLtextarea/blob/master/src/RTLText.module.js
re: Web Browser Control – Specifying the IE Version
May 21, 2015 @ 8:01am | by Ken

Hi

This entry has been incredibly useful in resolving some issues I've been having with using the browser control under Win7 and IE11. I've played with all the indicated values and find 270F, 2AF9, 2711 work the best so far. Outstanding is that somewhere deep in the bowels I get a dialog box "Message from webpage" "Client side XSL transformations are not supported on your browser". The message does not occur from a desktop browser. I've done a few searches and can't find anything to help. Would you have any pointers on how to resolve this?

Thanks
Ken
re: JSON Serialization of a DataReader
May 18, 2015 @ 11:26am | by Rick Strahl

@Montana - In general I think that using a DataReader is something that should be relegated to a business layer or internal implementation. The exposed interface to an application should usually have something a bit more concrete like an a collection of objects. Some sort of serialization.

If you're doing data work that means some sort of database framework which can be a full fledged ORM like entity framework or something smaller like Dapper, PetaPoco or Massive, or even my SqlDataAccess DAL library (from Westwind Toolkit). You really don't want to be writing manual ADO.NET code but use helpers that return something more user friendly to your application layer.
re: JSON Serialization of a DataReader
May 18, 2015 @ 8:47am | by Montana

Rick Strahl! Man - I've been following your work from back in the Visual FoxPro (5 - I think it was) days! Got out of MS products altogether in favor of Linux platforms when they started killing VFP - and I've recently begun my trek in earnest back into considering MS development tools now that the CEO of MS is a little less of a psychopath.

Great to see a familiar face, I've always respected your work and remember looking to your stuff for guidance and best practices - VFP Magazine man!

Anyhow, you mention in this post you would not recommend using a DataReader for a JSON service, I'm wondering what you *would* use?

My usual approach for data api calls that need JSON serialization would be:
Retrieve any mapped structures via an API Key of some kind, construct[first look in cache] the data objects that house the required model - serialize that into a predictable structure for consumption, cache that data if need be, and move on.

My first pass at this in C# has led me to rendering data from planned queries into Dictionary objects as you've described here. Is this an undesired approach?

Since I haven't found any way to ask SQL Server for a Json object directly yet - I wonder what the best practices here are?
re: Rendering ASP.NET MVC Views to String
May 17, 2015 @ 4:46pm | by Rick Strahl

@Justin - the renderer just creates text. if you have relative links for CSS and images you need to fix up those links dependening on the new location from which the HTML is served. Either make the URLs of the original page absolute or convert them to absolute paths when you're rendering.
re: Rendering ASP.NET MVC Views to String
May 17, 2015 @ 4:29pm | by justin

Hi, thanks for the article.

Just wonder is there a way to keep the css style after rendering the view to string?
looks like all styles are gone.
re: Client Templating with jQuery
May 17, 2015 @ 4:05am | by Terry Lin

Your script works good but I found a bug on your script
var new_html = parseTemplate($("#category-tpl").html(), {id: res[i].id, text: res[i].link} );

parseTemplate() can't parse something like res[i].id ( res.id is fine )
re: Building a better .NET Application Configuration Class - revisited
May 15, 2015 @ 11:31am | by Rick Strahl

@Will - not sure what upgrade() would do. As it stands there Write() method that will write whatever values are on the object. It'll just write out everything that's on the object now, which is what you'd almost always want. Read the values that are in the config file, make any changes, write them back.

You implement the class and you can add any interfaces you want. If you need to implement IPropertyChanged to get change notification you have to implement that yourself.

+++ Rick ---
re: JavaScript JSON Date Parsing and real Dates
May 15, 2015 @ 8:08am | by Frederic

Hi, we also had to create a "custom" date parser for our app.

We want to work with real "dates" format, because we sometimes need to re-format them in a format that our user can choose.

Our app (bridge24.com) connects to a lot of different api (basecamp, trello, asana, aceproject), and not everyone returns dates the same way...

The only thing we're sure of, is that the 10 first characters are yyyy-mm-dd.
Sometimes, it stops there (for a value like "Due Date", there is no "time" for that data.

There is 3 different cases we need to handle.

1. The "easy" one: full string including "timezone" at the end
(yyyy-MM-ddTHH:mm:ss-hh:mm)
easy, just use new Date(input)

2. the "no-timezone" one
(yyyy-MM-ddTHH:mm:ss)
We need to keep it like that when we display it. If we do a "new Date' on it, it apply the current local timezone, and changes the date. So we use "substring" to extract y,m,d,h,m,s, and we call new Date(y,m,d,h,m,s,0). That way, the time is the same in the "date" object than it was on the original string.

3. the "no-time" date
(yyyy-MM-dd)
For that case, like the last one, if we use new Date(value), it applies a local timezone, so it add our localtimezone (in our case, EST, it substract 5 hours), so the day change. "2015-04-19" becomes "2015-04-18T19:00". To prevent it, we need to substr y-m-d from the string, and use new Date(y,m,d,0,0,0,0).

We may need to "mix" these 3 cases, example:
(yyyy-MM-ddT00:00:00), what do we do with that? no timezone, but time provided, and all at 00:00:00... Case 3 will work, and return data like case 2 do. Date object will be in "current timezone"' with hour at 00:00.

It works fine for now with all different API we're connecting to.

Yes, there is certainly some performance issues of all these substring ... but we don't "feel" it, and at the end, our dates are easier to work with.
re: Problems with opening CHM Help files from Network or Internet
May 14, 2015 @ 12:15am | by Alan Bourke

You can also use the PowerShell 'unblock-File' commandlet at the prompt, which is useful for scripting this, running it on batches of files, and so on.
re: Building a better .NET Application Configuration Class - revisited
May 13, 2015 @ 3:59pm | by Will

I like this. I've got some pretty complex types I need to represent in my application settings, and I think this is the solution. I have two questions (which may their answers in this article):

1. How would I go about implementing the Settings.Upgrade() method? Is that handled by this class?

2. Is it possible to bind values to the properties in this class, and have the listening controls change to reflect changes to the class values? This is pretty important.

Of course; I am certain that in the worst case scenario both of these can be implemented. I just do not want to have to do so if they have been taken int account already.
re: A WebAPI Basic Authentication MessageHandler
May 13, 2015 @ 9:59am | by mike

I think you should move the comment about disabling basic authentication to the top of the article. It took me a while to find something that referenced that problem, and that 'disabling it for IIS' meant disabling it in web.config (if feature delegation is allowed).

This was the one problem I had, as the request would come in but nothing told me about the IIS/basic auth issue. For those who don't know, if basic authentication is enabled in web.config, IIS will intercept the authentication routine and your authorization/authentication handlers and attributes will never be hit while debugging.

Thanks, though. The rest of the article was great!
re: Getting and setting max zIndex with jQuery
May 13, 2015 @ 9:44am | by Mat Polutta

I just used the plugin combined with jquery-idleTimeout.js to get a jQuery Dialog to pop over a Telerik RadWindow (hosting a RadEditor). Our scenario calls for a session timing-out dialog to prompt a user to continue using the Web Application to create an Idea or Comment on the site. After 25 minutes, the dialog pops. But it was being hidden when a RadWindow (creates an iframe) was used.
re: Creating a dynamic, extensible C# Expando Object
May 13, 2015 @ 7:18am | by Rick Strahl

Sure it should work in any .NET code.
re: Creating a dynamic, extensible C# Expando Object
May 13, 2015 @ 12:10am | by Kam Minter

Rick,

I have a question, can this be used in a wpf program? The reason I ask is that I want to basically put together two tables with strongly typed properties and with a couple of dynamic properties.
re: Embedding JavaScript Strings from an ASP.NET Page
May 12, 2015 @ 6:29am | by Rob

Yes, that's true in that respect.

The OWASP guide recommends to escape all characters less than 256 (rather than less than 32 or above 127 like you have there). This is to be "extra safe" and to guard against anything that might be able to get round angle bracket encoding in future.

Any chance you could put a message on your post to inform Googlers about the new way (JavaScriptStringEncode function)?
re: WSDL Imports without WSDL.exe
May 10, 2015 @ 10:10pm | by Raja Nadar

Hey Rick

excellent post. was very helpful, especially the external-schema-include part.

one thing i would like to add is that if the external schema contains, additionally referenced external types, then the code generation fails. the solution is to recursively add the external-schemas. (and ensure there are no loops by having an uber HashSet<string> of Schema Uris)

your post was super helpful, and hope this additional tip helps somebody with
nested schema-includes.

sample code:

// Download and inject any imported schemas (ie. WCF generated WSDL)            
foreach (XmlSchema wsdlSchema in sd.Types.Schemas)
{
    // Loop through all detected imports in the main schema
    ImportIncludedSchemasRecursively(wsdlUrl, importer, wsdlSchema);
}
 
// later code
 
// class level variable
private static readonly HashSet<string> IncludedSchemas = new HashSet<string>();
 
private static void ImportIncludedSchemasRecursively(string mainWsdlUrl, ServiceDescriptionImporter importer, XmlSchema currentWsdlSchema)
{
    foreach (XmlSchemaObject externalSchema in currentWsdlSchema.Includes)
    {
        // Read each external schema into a schema object and add to importer
        if (externalSchema is XmlSchemaImport)
        {
            Uri baseUri = new Uri(mainWsdlUrl);
            Uri schemaUri = new Uri(baseUri, ((XmlSchemaExternal)externalSchema).SchemaLocation);
 
            if (!IncludedSchemas.Contains(schemaUri.ToString()))
            {
                IncludedSchemas.Add(schemaUri.ToString());
 
                WebClient http = new WebClient();
                Stream schemaStream = http.OpenRead(schemaUri);
 
                System.Xml.Schema.XmlSchema schema = XmlSchema.Read(schemaStream, null);
                importer.Schemas.Add(schema);
 
                ImportIncludedSchemasRecursively(mainWsdlUrl.ToString(), importer, schema);
            }
        }
    }
}

re: Passing multiple simple POST Values to ASP.NET Web API
May 10, 2015 @ 8:47pm | by Rick Strahl

@Dan - the difference is that ASP.NET AJAX with ASMX was basically RPC based so it only knew how to POST data and automatically wrapped the messages for you. If you look at the actual data going over the wire you'll find that the actual client code sent a complex object as well. The framework just knew about the assumptions and knows how to take this complex object and parse that into the parameters when the ASMX method is called.

Web API can't make these same assumptions as you can pass ANYTHING to it. Therefore there are more restrictions on the actual interface you can pass. I'd argue that passing complex parameters in a REST call is not really clean as it doesn't describe what's actually happening underneath. If you have a model that describes the structure on the other hand you are EXACTLY describing what's happening.

As outlined in the post there are two options to do what you're doing:

* Create a ViewModel that includes each parameter as a property
* Use dynamic types which translate into JObject values

Additionally if you really want to be able to do this using exactly that syntax you could create a custom MessageHandler that could do what you want. Maybe with a custom attribute that identifies when this should happen. Wouldn't be hard to do either. But it's something that has to be explicitly designated.
re: Passing multiple simple POST Values to ASP.NET Web API
May 10, 2015 @ 4:17pm | by Dan H

Thanks for sharing your solution Rick. I am migrating a project previously done with asmx and was able to adapt your solution for my purposes and it worked for the majority of cases. However, I have a number of (former) asmx methods that accept one or more complex types along with some simple parameter types, and that's where things seem to break down. I just don't see any way to get this to work with web api.

Consider a method like this:

public ValidationResult SaveEvent(EventInfo e, List<UserInfo> inviteList, long currentUserID, string token)
{
     ValidateToken(currentUserID, token);
 
     return ValidationManager.ValidateAndSaveEvent(e, inviteList, currentUserID);
}


It seems that my only option for this is to create a single (view) model that encompasses the first two complex-type parameters. And if I did that, I might as well have that model also include the last two simple parameters, otherwise I'd have to pass the last two parameters via querystring while passing the model parameter in the form body.

Needless to say this requires much more work than it seems like it should, especially since everything was working fine when it was asmx. Any suggestions?
re: Embedding JavaScript Strings from an ASP.NET Page
May 10, 2015 @ 1:09pm | by Rick Strahl

@Rob - Valid point. As you point out this post is really old and it predates the HttpUtility.JavaScriptEncodeString() function. The simple solution to fix the above function would be to just encode < and > as special characters in order to have minimal impact on parsing.
re: Embedding JavaScript Strings from an ASP.NET Page
May 10, 2015 @ 6:35am | by Rob

I know this is an old post, however people will be finding this code via Google and using it in their own websites.

This code is vulnerable to Cross Site Scripting (XSS) and I managed to succeed in generating an attack vector.

The code does not handle </script> tags in the JavaScript code. Such tags will cause the browser to think the script tag is over, leaving the interpretation inside an HTML context but without proper encoding.

See the answer here for more information: http://stackoverflow.com/a/28716574/413180

Info regarding XSS in general: https://www.owasp.org/index.php/Cross-site_Scripting_%28XSS%29

See https://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet for comprehensive details on how to prevent this.

Or just use the new HttpUtility.JavaScriptStringEncode .NET function rather than the code on this blog post.
re: Azure VM Blues: Fighting a losing Performance Battle
May 06, 2015 @ 3:54pm | by Ramesh

We had been building our website in an ASP.NET based CMS system in A2 Azure VM's for past 3 months in US East region. The performance of Azure A2 instances had been terrible throughout. We made a few copies of the VM's by creating images during development and each one was terrible in performance with their AMD Opetron virtualized CPU's.

Finally, after the development was complete, we deployed the code & DB in local datacenter on Xeon processors in VMWare VM. There was a day and night difference in performance and the local server performance was order of magnitudes better than the Azure VM (which usually had plenty of CPU and Memory free in task manager).

Based on our experience, I wouldn't use Azure A2 VM's even for running small load web servers in production.
re: Gotcha: Entity Framework gets slow in long Iteration Loops
May 06, 2015 @ 10:35am | by Tim S.

Now that you have the context split up at DAL or BL level, you might be able to use
Parallel.ForEach instead of ForEach and really watch the cpu's light up.
re: ASP.NET Frameworks and Raw Throughput Performance
May 05, 2015 @ 3:57pm | by Dmitriy

Please add "-k" to your tests. You are showing results which are 5-6 times lower than they atually are
re: Passing multiple POST parameters to Web API Controller Methods
May 05, 2015 @ 3:50pm | by Rick Strahl

I do it in my business layer. I assign the values from parameters to data model and then the business layer validates before saving. If you're using Entity Framework there's a validation API that can be used and my business layer automatically checks any model validations at that time.

If you don't have that you'll have this level of abstraction you have to hook validation up manually. I suppose if you are explicitly passing POST values the assumption is that you don't have a lot of parameters - otherwise a model object makes a lot more sense. If there are just a few it's not difficult to do manual validation if your business layer doesn't already do it for you.

Personally I believe that validation should always go into the business layer and it just happens that MVC/Web API provide model validation externally. But ultimately not all data comes in through a full model update in an application, so you can't rely on that for all of your validation anyway, so a business layer that provides the validation is valuable.

FWIW, I'm using Westwind.Data (http://www.nuget.org/packages/Westwind.Data/) which is a thin layer around EF to provide simpler CRUD abstractions and Validation management for me. It's more of an internal library (meaning there's not a lot of documentation), but it's worked very well for me in a variety of projects large and small.
re: Passing multiple POST parameters to Web API Controller Methods
May 05, 2015 @ 7:52am | by Uikrosoft

Hello Rick, how do you apply validation when passing multiple POST parameters to Web API Controller Methods?
re: Adding minimal OWIN Identity Authentication to an Existing ASP.NET MVC Application
May 04, 2015 @ 12:11pm | by Chris

Excellent article! Was very usefull for me.
re: Using Cordova and Visual Studio to build iOS Mobile Apps
May 04, 2015 @ 2:34am | by CordovaIosRemoteDebugger

Hi Rick. Thank you for your answer. I opened a question at stackoverflow. The problem seems to be in the plugin implementation:

http://stackoverflow.com/questions/29971259/visual-studio-hangs-when-remote-debugging-a-cordova-ios-app

By the way: What did you mean with 'RTM'?
re: Adding minimal OWIN Identity Authentication to an Existing ASP.NET MVC Application
May 02, 2015 @ 8:35am | by Jeff P.

I'm starting to see that the things I'm not using, that you are referencing, are in the Microsoft.AspNet.Identity.Owin package, which to this point I haven't added a reference to. For example the app builder extension method for UseExternalSignInCookie(). That's pretty frustrating that you need more dependencies and that the existing code is broken just from a version upgrade. Will let you know if this gets me there...
Great Article
April 30, 2015 @ 4:49pm | by Matt

Great Article Rick! I look forward to putting some of this is use in my up coming project.
re: Using Cordova and Visual Studio to build iOS Mobile Apps
April 30, 2015 @ 12:40pm | by Rick Strahl

I suppose that depends on the plug-in. I use a few plug-ins for managing the UI display (statusbar for example) and haven't seen any debugging issues.

But debugging or even running with plug-ins through an emulator or across a remote connection is definitely tricky. I expect that to get addressed before RTM though.
re: Using Cordova and Visual Studio to build iOS Mobile Apps
April 30, 2015 @ 4:48am | by CordovaIosRemoteDebugger

During remote debugging an iOS cordova app, did you also notice that Visual Studio hangs when you set a breakpoint to inspect a result of a cordova plugin?

A breakpoint on a line which is executed before calling a cordova plugin works without problems... Also storing the result of a cordova plugin in a variable and then inspecting it using another click event handler works.
re: ASP.NET MVC, Localization and Westwind.Globalization for Db Resources
April 30, 2015 @ 3:43am | by David

By the way Rick, it looks like a little pressure on the ASP.Net team seems to have worked, and they have now committed to bringing back Single File Generators, to support T4 and resx files. The team hope to have that for next release of VS2015.
re: Adding minimal OWIN Identity Authentication to an Existing ASP.NET MVC Application
April 29, 2015 @ 12:28pm | by Jeff P.

Yeah, it's weird that a major version update would break stuff. But your article gives me some ideas to experiment with, so I'll see what I can do. I'll post back here if I discover anything interesting.
re: Adding minimal OWIN Identity Authentication to an Existing ASP.NET MVC Application
April 29, 2015 @ 11:49am | by Rick Strahl

@Jeff - I lifted the code from the original templates, so I'm just doing what the default implementation would do which I assume is safe. When I run into problems like this sadly this is my go-to solution: Check what the default templates do and then adjust my code to match.

I didn't look closely at the lower level AuthenticationManager methods to see what's needed given that the code does what it's supposed to using ExternalLinkLoginInfoAsync(). Have you tied using that instead? Also notice the use of app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie) instead of your app.SetDefaultSignInAsAuthenticationType().

Bummer to hear that this broke for you though - that really shouldn't be happening with components that are as integral as this.
re: Adding minimal OWIN Identity Authentication to an Existing ASP.NET MVC Application
April 29, 2015 @ 10:52am | by Jeff P.

I went through this exercise with my open source forum app, and mostly it works pretty well. However, something changed dramatically in v3.x of the OWIN stack, and it breaks. I haven't been able to figure out why and it's completely frustrating. I assume it's something configuration related, but I can't nail it down.

http://stackoverflow.com/questions/28704700/updating-owin-from-2-1-to-3-0-1-breaks-external-auth

I notice that you're calling GetExternalLoginInfoAsync from the AuthenticationManager. I'm using GetAuthenticationResult. Any idea what the difference is?
re: A jquery-watch Plug-in for watching CSS styles and Attributes
April 29, 2015 @ 10:40am | by Rob

Hi Rick,

I have a tracking pixel on the page:

<img src="images/pixel.aspx?login=123" id="beacon" alt="img" width="1" height="1"/>

The asp.net server returns pixel.gif once I record the pageview and other parameters in the url. All this is working great. I tried the script below to watch when the attr_src changes and nothing happens, the callback is not raised? Is this possible?

What I want to do is check that login on the server and if not valid I will send back an expired.gif and then raise the error on the client's machine, if I can detect the image src change.

// hook up the watcher
$("#beacon").watch({
// specify CSS styles or attribute names to monitor
properties: "attr_src",

// callback function when a change is detected
callback: function (data, i) {
var propChanged = data.props[i];
var newValue = data.vals[i];

console.log("src",newValue)
var el = this;
var el$ = $(this);

// do what you need based on changes
// or do your own checks
}
});
re: Adding minimal OWIN Identity Authentication to an Existing ASP.NET MVC Application
April 29, 2015 @ 10:27am | by Jonathas Morais

What about a SAML integration?
I'm keen to integrate .NET apps with an Identity Server, which in turn contains several Services and Identity Providers but there's not much material out there explaining how to do it in .NET.

Nice post by the way!

Thanks.
re: ASP.NET MVC Postbacks and HtmlHelper Controls ignoring Model Changes
April 28, 2015 @ 12:08am | by Serge

Thanks Rick, spend half a day guessing where does Html.TextBoxFor getting its values as my model is null! I started to suspect it takes it from POST when I found this article.
So non intuitive and leads to lazy coding when people would skip updating properties of the model before returning it and relying on ASP.NET to do plumbing.
re: Using FontAwesome Fonts for HTML Radio Buttons and Checkboxes
April 23, 2015 @ 10:49am | by Rick Strahl

@twomm - did you get this resolved? I have not seen the issue unless there's a problem with CSS maps not matching the actual elements. If you use MVC make sure you use the adjusted CSS as described in the post so that you get around the injected validation element.
re: Using FontAwesome Fonts for HTML Radio Buttons and Checkboxes
April 23, 2015 @ 3:09am | by twomm

Nice, however, I first had the same issue as Allen (keyboard/mouse).
I think it was an issue with the element IDs.
re: Passing multiple simple POST Values to ASP.NET Web API
April 22, 2015 @ 1:24pm | by Sagar Mummidivarapu

I used your code but still my post method receives null values.
I found that the below code supports only form passed values but what if I send Json request like this: { itemId: "10626217", lookupType: "0" } (multipleBodyparameters is always null)

// only read if there's content and it's form data
if (contentType == null || contentType.MediaType != "application/x-www-form-urlencoded")
{
// Nope no data
result = null;
}
else
{
// parsing the string like firstname=Hongmei&lastname=ASDASD
result = request.Content.ReadAsFormDataAsync().Result;
}
re: Routing to a Controller with no View in Angular
April 21, 2015 @ 9:11am | by Brian

Don't use ng-view. Set up routes and listen for the $routeChangeStart and $routeChangeSuccess events, then evaluate the updated $routeParams.
Great information
April 21, 2015 @ 7:05am | by Ivo Botusharov

Thank you very much for your investigation and the provided information. I was just wondering why in ASP.NET MVC 5 scaffold templates the data annotation on the Delete action methods is: [HttpPost] instead of [HttpDelete] which would be more appropriate in terms of http standard. Thanks again!
re: Azure VM Blues: Fighting a losing Performance Battle
April 21, 2015 @ 6:26am | by Patrick

I am with you 100% on Azure performance issues.

I had a 2008R2 VM at GoDaddy for years, but they will not move to 2012.

I am now have a 2012R2 www.webline-services.com. The uptime has been great and the performance too. I know this sounds like a plug, but it is not. When I moved from GoDaddy I went to a few other hosts and it was a nightmare. It is on my blog.
re: Hosting the Razor Engine for Templating in Non-Web Applications
April 20, 2015 @ 11:56pm | by Renato

Hi Rick,

thank you for the great post. Is there any way you can think of to get "Razor Intellisense" working at runtime in an editor? Something like your WinForm example with integrated Razor Intellisense in the "Template to Render" textbox.
re: Back to Basics: UTC and TimeZones in .NET Web Apps
April 19, 2015 @ 8:48pm | by Matt Johnson

I've blogged with detail in response to one particularly problematic part of this blog post.
http://codeofmatt.com/2015/04/20/beware-the-edge-cases-of-time/

Cheers!
re: Back to Basics: UTC and TimeZones in .NET Web Apps
April 19, 2015 @ 4:06pm | by Matt Johnson

Great post. Thanks for bringing awareness to my favorite subject! Though if you don't mind, I'm going to tear it apart. :) Allow me to clarify a few points:

TimeZoneInfo.ConvertTimeFromUtc will throw an exception if passed a DateTime with Local kind. If it's unspecified, it will assume UTC. So the ToTimeZoneTime extension method will not behave as it says in the comments, accepting a Utc or local time. The input time parameter must be in terms of UTC. The way you used it, coming from DateTime.UtcNow, is just fine.

Regarding caching - It's good to hold on to a TimeZoneInfo object for as long as you need it within the local scope. However, I don't recommend building your own cache, as the FindSystemTimeZoneById method already uses a lookup cache internally.

Next, with regard to displaying the time zone names in a drop-down - While there's nothing inherently wrong with your approach, it's important to note that the DisplayName property will be localized by the OS language of the server (which might not be English). The usual localization methods in .NET don't apply to the TimeZoneInfo object. In a multilingual app, one may need to use the TimeZoneInfo.Id to look up a display name from a resource file, rather than use the DisplayName property. Alternatively, one could use my TimeZoneNames library. (http://mj1856.github.io/TimeZoneNames/)

With regard to capturing the user's default time zone. Sorry, but the approach you describe is flawed. The problem is that every implementation of JavaScript is free to present time zones in whatever manner they wish. The spec is not refined enough to rely on it having any particular set of values. In particular, the example you show of "Hawaiian Standard Time" mapping back to the TimeZoneInfo ID is just a coincidence. Worldwide, typically they will NOT match up. Also, the JavaScript names will indeed switch out for DST, while the TimeZoneInfo.Id will not. So "Eastern Standard Time" will always be the ID for the US Eastern time zone, even when JavaScript shows "Eastern Daylight Time". Additionally, some browsers will just show an abbreviation (HST, EST, EDT, etc.), or may localize the time zone string to the user's language.

Time zone detection is actually quite difficult, which is why it makes sense to ask your user in a drop-down list. There are libraries like jsTimeZoneDetect which try to guess your time zone, but it is not 100% accurate. There is the JavaScript getTimeZoneOffset method, but that only returns the offset associated with the date you called it on - which is not enough to determine the actual time zone. There's also a newer way, supported by Chrome and Opera, but not IE, FF, or Safari: Intl.DateTimeFormat().resolvedOptions().timeZone - Hopefully that will catch on in other browsers, but today - there's no universal way to detect the time zone.

Moving along - The GetUserTime method looks fine, but in your GetUtcUserTime method, there's a bug. You call ToUniversalTime on the result of the time zone conversion. So that's DateTime.ToUniversalTime, which will still use the time zone of the server - not the destination time zone. You would need to use TimeZoneInfo.ConvertTimeToUtc to avoid that problem, rather than ToUniversalTime. However, I'm a bit confused why you would need this method to begin with, or what it's actually doing. If the time is in the user's time zone, then you would just have one call to TimeZoneInfo.ConvertTimeToUtc. If the time is in the server's time zone, then you would just have one call to DateTime.ToUniversalTime. The mix here doesn't make a lot of sense.

Moving further down your post, in the section on Date range queries - again, calling ToUniversalTime on a DateTime will use the server's local time zone, not the user's time zone. So the query boundaries are not correctly aligned to the user. Again, you'd need to use TimeZoneInfo.ConvertTimeToUtc.

In the User Captured Time section, the DateMath function could just be a single call to TimeZoneInfo.ConvertTimeToUtc, passing in the user's time zone. The manual manipulation of offsets is not only unnecessarily, but it's slightly flawed in that you expect the "offset" and "offsetLocal" values to be reflecting the offset for the same "start" time, but that's defined by the user's time zone - so you're not really referring to the same instant. This will show up if either time zone is near a DST transition. It's possible that your local time zone could be on one side of the transition, and the user's time zone could be on the other side.

The same easy-to-make mistake is in you AdjustTimeZoneOffset class. It will work if the "localTime" parameter has Kind=Local, or Kind=Utc, but not necessarily will it be correct in all cases when Kind=Unspecified. Think of it this way - the TimeZoneInfo.GetUtcOffset(DateTime) *prefers* to work with Unspecified kinds, as those mean that the time is relative to to the time zone of that particular TimeZoneInfo object. When it gets a Local or Utc kind, it converts to that time zone first. (This is inverted from most of the other methods that assume Unspecified means Local or Utc).

The theme throughout all of this feedback is that you should be working directly with the user's time zone and UTC - avoiding your own servers local time zone whenever possible. Really, the time zone of the server should be considered irrelevant. Avoid any use of "local" time (DateTime.Now, DateTime.ToUniversalTime, DateTime.ToLocalTime, DateTimeKind.Local, etc.) and everything will be much simpler.

Nitpick: "DayLight Savings Time" => "Daylight Saving Time". Daylight is one word, and the second word should have no "s" at the end. Think "I'm saving daylight during this time" - which is arguable, but nonetheless, that's the term's origin.

With regard to DateTimeOffset - I'll disagree with you completely. DateTimeOffset is essential in a web application, and it addresses much more than just a single scenario. You're also not tied to a single time zone, as the offset can be adjusted to any time zone you might be in. The offset doesn't track the time zone, just the offset for the time zone that happens to be in effect. Remember, there's much more to a time zone than just an offset, as many time zones switch between more than one offset due to daylight saving time.

The essential part you're missing about DateTimeOffset is that it's the only way to effectively disambiguate between ambiguous local values. For example, if you have 2014-11-02 01:00 as a DateTime, and you're in the US Pacific time zone, you have a problem because you don't know if that's PDT (-07:00), or PST (-08:00). The DateTimeOffset keeps the offset intact, so you affirmatively know which of the two possibilities you're using. If you store a UTC time, or if the time zone doesn't use DST (like Hawaii), then you're OK. But in cases where the time zone uses DST, not storing the offset could mean that you are losing data - you'd potentially be using a value as an hour before or after the intended moment.

You're right about the performance of DateTime.Now, and TimeZoneInfo. In fact Noda Time is one of the ways you can improve upon performance, as it is thoroughly optimized for perf.

Speaking of Noda Time, I'll disagree with you that you have to replace everything throughout your system. Sure, if you do, you'll have a lot less opportunity to make mistakes, but you certainly can just use Noda Time where it makes sense. I've personally worked on systems that needed to do time zone conversions using IANA time zones (ex. "America/Los_Angeles"), but tracked everything else in DateTime and DateTimeOffset types. It's actually quite common to see Noda Time used extensively in application logic, but left completely out of the DTOs and persistence layers. In some technologies, like Entity Framework, you couldn't use Noda Time directly if you wanted to - because there's no where to hook it up. Others, such as Json.Net, Dapper, and RavenDB have extension libraries for Noda Time so you can use it there if you want to, but there's still no hard requirement that you do.

In general, I think your post is great in that you are covering most of the areas of concern, where attention needs to be paid to converting between time zones. But like many things, the devil is in the details. Even you, who are more familiar with these functions than most, still were able to make mistakes like calling ToUniversalTime on a non-local DateTime, or calling GetUtcOffset with a value from a different time zone. Noda Time won't let you get into trouble, because the API prevents you from calling methods that have confusing or ambiguous behavior.

Hope this feedback was helpful.
-Matt
re: Azure VM Blues: Fighting a losing Performance Battle
April 19, 2015 @ 5:55am | by Randall Tomes

Been using azure for over a year now.
I am on my 6th vm and this one is a small windows server 2008 vm.
Using mvc5 with one simple call to a one table sql database. Nothing else. After a few hours with zero traffic, the machine locks up and has to be reset via the azure portal.

I have also tried webroles and had issues with file content (the entire website) being overwritten with old versions of the website from weeks or months prior. Basically like some auto rollback feature is broken and acts on its own. It consistently has done this 10+ times until I gave up using web roles.

Their support is clueless and they don't even understand azure themselves. Its like the blind leading the blind.

Are there any other more serious, "legitimate" and affordable cloud computing companies that I can use to host .net applications?