AJ's bloghttps://ajdotnet.wordpress.com
Thoughts and informations I think worthwhile to share...Wed, 10 Jan 2018 16:10:41 +0000enhourly1http://wordpress.com/https://s2.wp.com/i/buttonw-com.pngAJ's bloghttps://ajdotnet.wordpress.com
WCF Policy – Part 11: Famous Last Wordshttps://ajdotnet.wordpress.com/2015/03/28/wcf-policy-part-11-famous-last-words/
https://ajdotnet.wordpress.com/2015/03/28/wcf-policy-part-11-famous-last-words/#respondSat, 28 Mar 2015 14:21:10 +0000http://ajdotnet.wordpress.com/?p=1190]]>Our policy works. Every aspect – defining the standard, switching it on, publishing the policy assertion, evaluating it for the client proxy, default behavior, and making the information accessible on client and server – contributes to a system where all pieces work together.

The policy plays well with WCF. The application developer can switch the policy on, and everything else happens automatically (with minor exceptions, e.g. registering the policy importer). If needs be he can access the information similar to other built in information (again, with minor exceptions). This is very close to what’s provided by WCF out of the box.

And what’s more, it builds on standards that are not platform dependent: WSDL, WS-Policy, SOAP. Other platforms offer similar capabilities, for example Metro for the Java world. (This work is actually based on project where cross platform availability was demanded.)

On the other hand, we had to do quite a lot to make it work. Question is, when and why would you want to do this?

Having a WCF Policy is certainly nice. Building a WCF Policy however is something that needs to be decided carefully.

Creating policies is certainly not part of the every-day-work of the average developer. Rather it’s part of the foundation laid out by experienced developers or some framework team in the organization. Policies are also usually cross cutting concerns, orthogonal to the business demands, and perhaps optional. And finally the effort is only justifiable for demands occurring regularly.

The biggest obstacle in my opinion is that implementing a WCF Policy requires a familiarity with the internal workings of the WCF that goes beyond what the average developer – including service developers – need and usually have. On the other hand, should you have someone with that skill, then policies might be a means to provide complex demands to other application developers in a seamless and easy-to-use way, and shield them from WCF intricacies.

In other words: Custom WCF Policies may be a rare demand. But at times, and if circumstances allow, they can be very handy.

Did I forget something? Oh, yes. You can find the sample application on github…

Our policy was defined in a way that extended the behavior of clients and services. Still we needed a BindingElementfor exporting the policy assertion (and we took a shortcut on top of that). However, in order to use BindingElementsyou need a custom binding (no WsHttpBinding or other). Should you have another binding already in place, you need to change this – which however implies an unnecessarily complicated translation from other bindings to custom bindings. Yaron’s converter might help with this.

Policies relying on bindings.

Some demands do not affect the behavior of the service, but the message content on the wire. Examples include custom encodings, compression, or similar requirements. These demands should be realized by bindings instead of behaviors. Unfortunately this requires quite a bit more effort.

I cannot see any reason why the above tasks have to be so complicated or why they require so much effort. Specialized bindings, such as WsHttpBinding build internally on binding elements, so there should be a straight forward translation between bindings. Similarly WCF channels are a simple pipeline, which is a pattern that is common enough. Why are the stages nearly set in stone, why does it take so much effort to introduce extensions?

WCF is at times rather complex due to the complexity of the protocols that need to be configured. Adding unnecessarily (I think) to this complexity is just annoying.

Just my 0,02€.

That’s all for now folks, AJ.NET

Filed under: .NET, .NET Framework, C#, SOA, Software Architecture, Software Development, WCF]]>https://ajdotnet.wordpress.com/2015/03/15/wcf-policy-part-10-addendum-extending-bindings/feed/0ajdotnetWCF Policy – Part 9: Making the Information Accessible on the Serverhttps://ajdotnet.wordpress.com/2015/02/15/wcf-policy-part-9-making-the-information-accessible-on-the-server/
https://ajdotnet.wordpress.com/2015/02/15/wcf-policy-part-9-making-the-information-accessible-on-the-server/#commentsSun, 15 Feb 2015 13:14:13 +0000http://ajdotnet.wordpress.com/?p=1184]]>On the client we can access the tracking information. On the server this would also come in handy, e.g. to add additional tracking entries, say for lengthy operations, such as database calls.

Whenever an application developer needs access to the current context during a service call, he does so via OperationContext. And OperationContext provides with its property Extensions exactly the extension point we need – if we can place an object in there, that implements our ITrackingInformation.

Operation extensions are classes implementing IExtension<OperationContext>. Providing a class that implements both, this interface and ITrackingInformation, is a simple exercise: Just deriving from TrackingInformation – the object we used to temporarily maintain the tracking information – and implementing the interface methods trivially is sufficient:

Now we need to change our message inspector to maintain the tracking information in an extension, rather than a temporary object. As on the client, due to some foresight, we only need to change one method:

After the first posts addressed the design time aspects, this post concludes the runtime aspects of our policy. The following image shows the related components at runtime:

And this screenshot shows the result generated from a sample application:

Our policy implementation is finished at this point, however, there is another post coming, looking at aspects we did not touch.

That’s all for now folks, AJ.NET

Filed under: .NET, .NET Framework, C#, SOA, Software Architecture, Software Development, WCF]]>https://ajdotnet.wordpress.com/2015/02/15/wcf-policy-part-9-making-the-information-accessible-on-the-server/feed/1ajdotnetWCF Policy – Part 8: Making the Information Available on the Clienthttps://ajdotnet.wordpress.com/2015/01/31/wcf-policy-part-8-making-the-information-available-on-the-client/
https://ajdotnet.wordpress.com/2015/01/31/wcf-policy-part-8-making-the-information-available-on-the-client/#commentsSat, 31 Jan 2015 14:37:23 +0000http://ajdotnet.wordpress.com/?p=1176]]>Our policy has its default behavior. All the information is collected, it just is not available to the developer yet. So let’s take care of that.

We already have the basics covered, namely we have an interface ITrackingInformation through which the application developer should have access to the information. All we need to do is to build a bridge between message inspectors and the application code.

On the client the application developer uses the generated client proxy class, thus we need to pass in the tracking information to that object. The class derives from ClientBase<TChannel> and thus inherits the property Endpointof type ServiceEndpoint. This class in turn maintains a collection of endpoint behaviors. With a custom behavior which implements our interface, the developer has the gate to our policy. Going one step further, this behavior can also register a message inspector in IEndpointBehavior.ApplyClientBehavior, which utilizes the information passed in, instead of a temporary object, as we did when we implemented this last time.

And given the fact that I “kind of had this in mind”, the changes to the message inspector are also minor: We need an addition constructor and member for the information passed in, which is boilerplate enough. Additionally the method to get the tracking information object changes slightly:

There is one thing left: The contract behavior created during code generation is still in place and still registers its own message inspector. This is still necessary in cases where the application developer does not provide the above endpoint behavior, but hurts if he does. Luckily the contract behavior’s ApplyClientBehavior method is called after the endpoint behavior’s method. So all we need to do is to check:

Filed under: .NET, .NET Framework, C#, SOA, Software Architecture, Software Development, WCF]]>https://ajdotnet.wordpress.com/2015/01/31/wcf-policy-part-8-making-the-information-available-on-the-client/feed/2ajdotnetWCF Policy – Part 7: Implementing the Default Behaviorhttps://ajdotnet.wordpress.com/2015/01/24/wcf-policy-part-7-implementing-the-default-behavior/
https://ajdotnet.wordpress.com/2015/01/24/wcf-policy-part-7-implementing-the-default-behavior/#commentsSat, 24 Jan 2015 13:43:32 +0000http://ajdotnet.wordpress.com/?p=1174]]>Our policy demands that we read and manipulate the messages going in and out, on client and service. The WCF component designated for this demand is a message inspector, which is available in two flavors, designated by the interface: IClientMessageInspectorfor the client, and IDispatchMessageInspectorfor the service. Both interfaces provide two methods; one is called for the incoming message, the other for the outgoing message. The respective runtimes – ClientRuntimeund DispatchRuntime– each maintain a collection of respective message inspector instances.

On the client the contract behavior created by our import extension can add the message inspector in IContractBehavior.ApplyClientBehavior, nothing more than a one-liner:

If the application developer calls a service method on the client proxy class, the WCF creates a message object for the resulting SOAP message. It the proceeds to call IClientMessageInspector.BeforeSendRequest on all message inspectors.

In this method our TrackingClientMessageInspector creates an ITrackingInformation object to maintain the information, creates the first tracking entry for sending the message, passes it to your header class, which will later serialize it as SOAP header, and adds it to the collection of headers. Finally it returns the ITrackingInformation object as correlation state:

// and pass on to outgoing headers tracking.OutgoingHeaders.TrackingEntries.AddRange(tracking.IncomingHeaders.TrackingEntries);

// pass headers via correlation statereturn tracking; }

The WCF proceeds to call the service method, the application developer provided. Afterwards the same process goes backwards for the reply. The WCF calls IDispatchMessageInspector.BeforeSendReply for all message inspectors. It also passes in the correlation state we returned earlier. Without this information we wouldn’t be able to link the two calls in case several requests came in in parallel.

The SOAP message is sent back to the client. There the WCF again creates a message object and calls IClientMessageInspector.AfterReceiveReply for all message inspectors, passing in the correlation state, similar to what we saw on the server.

Let recap that in context: The application developer has put a service behavior on his service. This has lead to a respective contract behavior on the client. And with what we just provided, the two of them are working together at runtime to create a protocol of calls at runtime.

The final topic we have to address is making the information available to the developer.

As a reminder: Our tracking policy is pretty simple: Client and server should keep track of sending and receiving messages, and accumulate that information along a request/reply call as part of the SOAP call. In the end this should create a timing protocol of the complete call.

So far we’ve got the design part covered: The server announces the policy, the client recognizes it. The next major aspect is actually doing something. In this post I’m going to provide some basics we are going to need further on. Classes to maintain the tracking information, as well as SOAP related helpers.

In case you are wondering about this setup: It’s modeled after the MessageHeaders class containing the headers natively supported by the WCF, and the way they are made available in the Messageclass.

We are going to include the information in the SOAP message as SOAP header – we do not want it to interfere with the actual contract and content – thus we need a MessageHeader class that deals with serialization/deserialization. Unfortunately the class supports only serialization of data based on data contracts, which in turn do not support XML attributes. Therefore, if more efficient XML is desired, one needs to take serialization into his own hands. Writing the header can be done by overriding the respective method:

The one pitfall I have found is the way policy expressions are identified and referenced. WS-Policy supports two ways to identify policy expressions, either by a Name attribute, or by a wsu:Id attribute (as shown in part 2 of this series). wsu:Id is used to identify policies residing in the same XML document, Name becomes necessary for policies in separate XML documents, for example imported using wsdl:import. The pitfall I mentioned: WCF does not support policies in separate XML documents, i.e. policy references using the Name attribute.

Now, as long as you are working within WCF on both client and server, this will never be an issues. However if your policy is provided by a Java Metro service, there is a choice, as documented here. Example 19.1 works fine with WCF clients, examples 19.2 and following are not supported. Other technologies may provide similar options, or – even worse – be limited to the Name attribute.

It’s not as if Microsoft doesn’t know the standards, they explained it quite well in “Understanding Web Services Policy”, chapter 2.8, “Referencing Policy Expressions”. They also know about the issue. Unfortunately they are not going to do something about it:

“At this point of time WCF only supports policies included in the same WSDL file and identified via the wsu:ID attribute. Unfortunately, we are not seeing large customer demand supporting policies residing in secondary WSDL documents, so I will be resolving this bug as "Wont Fix".”

Sic!

Having had to support both, .NET and Java, I ended up writing a little command line application, that downloads and patches the WSDL of services using the Name attribute…

Last time I described the client proxy generation as it happens from within Visual Studio (“Add service reference…”). For those who want to use the command line tool svcutil.exe, there are a few things to keep in mind:

It is not sufficient, to provide the app.config via the /config parameter. This configuration file is only for output; to provide a configuration file as input you need to pass it in via the /svcutilConfig parameter.

Additionally the assembly containing the import extension has to be found by svcutil.exe. This works automatically if the assembly resides in the GAC. In other cases the assembly has to be provided using the /reference parameter.

Lastly the namespace for the generated code needs to be provided as it is not automatically inferred by the tool. This involves a somewhat awkward syntax…

All together results in a command line similar to this (line feeds for better readability):

On the client the WCF evaluates policy assertions during proxy generation, for code and configuration. If you try to import a WSDL containing a policy assertion, the WCF does not know – as is the case with our policy assertion so far – the generated configuration will contain the following warning:

To provide respective import logic the WCF provides an interface IPolicyImportExtension. While this is conceptually similar to what is provided for the export, there is one difference: It is not placed on a binding. In fact, it would not make sense to put it on a binding, as the binding configuration configuration does not yet exist; rather it is part of what is going to be generated during the import. That is why the interface has to be implemented by an arbitrary class, which has then to be announced in the configuration:

During import the WSDL will call respective extensions for all policies it finds. Our job is to check whether the we know the policy assertion. If so, we need to remove it, to prevent the above warning from showing up. Within IPolicyImportExtension.ImportPolicy and it with its parameter of type PolicyConversionContext, this is just one line of code to satisfy the WCF and get rid of the warning:

Now we need to do something with our policy assertion. For our tracking policy I want to place a contract behavior on the generated contract, similar to the service behavior on the server side. This is supported by yet another interface, namely IServiceContractGenerationExtension, and again, on behaviors. So we provide a respective behavior and let our importer add that behavior for the contract. Just one additional line of code:

Still during proxy generation, but some time after our importer has done its job, the WCF will call IServiceContractGenerationExtension.GenerateContract on our behavior. At this time the actual contract interface will have already been created using CodeDOM, so we can party on it and manipulate it as we like. In our case add a contract behavior attribute:

All other methods of the behavior are simply empty. Of course we also need to provide the TrackingContractBehaviorAttribute, also – for the time being – with empty methods.

Note: Strictly speaking, we could use the behavior class. But I want to emphasis the fact that the behavior used to manipulate the code is only present during proxy generation, while the one we just added as attribute is present at runtime.

Running the import again will remove the warning in the configuration. And it will also create a contract amended with our attribute:

In case the policy contains more complex parameters, there is more work to do – analyzing the XML from the policy assertion, generating code with parameters – but the general principle stays the same.

This completes the design time aspects of our policy. The following image depicts the process on server and client (i.e what we covered this post and the last) in overview:

First order of the day fulfilled. The service announces the policy in the WSDL for everyone to take notice and act accordingly. The client proxy generation can be taught to evaluate the policy assertion. What’s important: The bridge between server and client is the WSDL and WS-Policy – common standards, nothing WCF-specific. Similar mechanisms can also be set up on other platforms, e.g. Java with Metro.

The next post will be an addendum, before we take care about the runtime aspects. After all, our implementation doesn’t do anything worthwhile yet.

That’s all for now folks, AJ.NET

Filed under: .NET, .NET Framework, C#, Design Time, SOA, Software Architecture, Software Development, WCF]]>https://ajdotnet.wordpress.com/2014/12/07/wcf-policy-part-3-evaluating-the-policy-on-the-client/feed/0ajdotnetWCF Policy – Part 2: Advertising the Policyhttps://ajdotnet.wordpress.com/2014/11/29/wcf-policy-part-2-advertising-the-policy/
https://ajdotnet.wordpress.com/2014/11/29/wcf-policy-part-2-advertising-the-policy/#respondSat, 29 Nov 2014 10:40:41 +0000http://ajdotnet.wordpress.com/?p=1146]]>The last post provided the introduction about what “policy” in the context of WCF is about. Now we are going to go ahead and actually build our own policy.

For this endeavor we keep the actual functionality simple: During a service call, client and server are to add timestamps whenever a message goes out or comes in. Those timestamps shall be maintained in a list that is forwarded with each message, doing so as SOAP header, since this is not part of the regular contracts. This will create a trace of the whole request/response chain. (“Chain” may sound a little presumptuous, but if one service calls others, this might become more of a challenge.) We’ll call this (a little snobbish) “tracking policy”.

Configuring the policy

The first step of the implementation is relatively unspectacular. Since we want to influence the behavior of the service, we need some kind of WCF behavior. I chose a service behavior, other demands may call for a different behavior type. The canonical implementation for a respective attribute looks like this…

… with all the method bodies empty. This is sufficient to be put on a service:

For details on behaviors (including extension elements to be used in configuration rather than code) see here.

Publishing the policy

Now for the first interesting part: How do we insert a policy assertion for our policy into the WSDL? WCF supports writing policy assertions via IPolicyExportExtension, however only for binding elements, not for behaviors. Of course we could provide a respective binding element and ask the developer to configure it – on top of the behavior that he already put on his service. Not exactly comfortable and a source of errors.

There is an alternative, though: Our behavior can add the binding element during the IServiceBehavior.Validate call, as shown here:

(This depends on the employment of a custom binding. I will address the question of other bindings in a later post.)

Now, IServiceBehavior.Validate is obviously not intended for this kind of manipulations, but what the heck, it works, and it makes things easier for the application developer.

Whenever the WSDL is generated, the binding elements implementing IPolicyExportExtension will be asked to insert their policy assertion. IPolicyExportExtension.ExportPolicy will be called and the parameter of type PolicyConversionContext provides the plumbing we need. The policy assertion itself is nothing more than an arbitrary XML fragment – the identifying part is an XML element – which we can create on the fly:

With this code in place, the WSDL should include the XML we just generated. Perhaps in combination with other policy assertions, depending on how the service is configured, but similar to this:

In our case we only needed the existence of the XML element to publish the policy. More complex policies may need to publish additional information. In this case all you need to do is to include XML attributes and/or elements as you like as children of the root element of the policy assertion. WS-Security Policy goes even further and provides several different policy assertions.

That concludes the server perspective for our policy assertion. The next post will look at it from the client perspective.

That’s all for now folks, AJ.NET

Filed under: .NET, C#, SOA, Software Architecture, Software Development, WCF]]>https://ajdotnet.wordpress.com/2014/11/29/wcf-policy-part-2-advertising-the-policy/feed/0ajdotnetWCF Policy – Part 1: What is policy about?https://ajdotnet.wordpress.com/2014/11/23/wcf-policy-part-1-what-is-policy-about/
https://ajdotnet.wordpress.com/2014/11/23/wcf-policy-part-1-what-is-policy-about/#respondSun, 23 Nov 2014 13:16:06 +0000http://ajdotnet.wordpress.com/?p=1140]]>Remember what I described during the introduction? Switch a feature on on the server, and the WCF takes care that this information gets pushed through to the client, at runtime client and server work together to fulfill the demand, and on top of it the developer can interfere if necessary.

Add the tiny fact that the “feature” in question usually adheres to some standard, and you have a policy and its implementation – in our case a “WCF Policy”. Let’s look into this a little more in detail, as this defines our to-do-list for the upcoming posts.

The world of services is based on various standards. These standards provide the set of features to choose from. Defining how a standard is employed by a particular service is actually defining the policy for said service.

Now, bringing this – so far abstract – concept of a policy to live in WCF includes several aspects:

Initially the developer needs some way to activate the feature on the service (or – rarely – the client), i.e. to switch it on and configure the details.

At design time the policy has to be advertised by the service. The most basic aspects like transport protocol and message format are already addressed in the WSDL and XSD. For everything that goes beyond that we have WS-Policy. On the server the information needs to be put into the WSDL, on the client it needs to be evaluated to generate a respective client proxy.

At runtime the policy has to be implemented by some runtime component; again, client and server.

Additionally, information implied by the policy should be accessible by the developer. Depending on the actual demand, this may be informal, he may be able to interfere, ore he may actually be required to provide additional input. (Say the username and password for basic authentication.)

Example…

OK, let’s make this a little more tangible and have a look at how it applies to employing WS-Addressing in WCF. This will also define the to-do-list for our own custom policy…

Initially the developer needs to declare that his service uses WS-Addressing. WCF covers WS-Addressing through different bindings. WsHttpBinding does it implicitly, a custom binding configures SOAP and WS-Addressing versions as part of the message encoding:

The binding also takes care of advertising the policy in the WSDL. Since WSDL itself has no knowledge of WS-Addressing, WS-Policy comes into play. WS-Policy is by itself a rather dull standard. It merely defines how to place additional information (particularly for the use of policies) in the WSDL. In our case it might look like this:

The element wsaw:UsingAddressing is called a custom policy assertion provided by WS-Addressing – Metadata – in general an arbitrary XML fragment. WS-Policy also provides means to define combinations and alternatives between policy assertions.

WCF also addresses the client side by generating a client proxy from a respective WSDL. This process includes handling policy assertions and generating the respective configuration (e.g. by choosing the appropriate binding) or code.

At runtime the actual behavior kicks in: The WCF client automatically generates a message ID for the SOAP request and includes it in the message as SOAP header:

The server takes the message ID and includes it in the reply message using the RelatesTo SOAP header.

Additionally the developer can access the message ID on the server and manipulate it, as he likes.

Summary…

To summarize this, here’s what makes up a policy in WCF:

During design:

Definition of the underlying standard

During development:

A way to switch the policy on and to configure as necessary

Advertising the policy in the WSDL

Evaluating the policy assertion during client proxy generation

During runtime:

Establishing the default behavior on server and client

Providing an interface to the developer

And this defines what we’re going to have to do – in the following posts…

That’s all for now folks, AJ.NET

Filed under: .NET, .NET Framework, SOA, Software Architecture, Software Development, WCF]]>https://ajdotnet.wordpress.com/2014/11/23/wcf-policy-part-1-what-is-policy-about/feed/0ajdotnetBuilding Your Own Policy with WCFhttps://ajdotnet.wordpress.com/2014/11/23/building-your-own-policy-with-wcf/
https://ajdotnet.wordpress.com/2014/11/23/building-your-own-policy-with-wcf/#respondSun, 23 Nov 2014 12:55:00 +0000http://ajdotnet.wordpress.com/?p=1133]]>Flexibility and extensibility of WCF is really great. You need a feature provided by the platform? Just switch it on, via code or configuration, and all the bits and pieces follow suit. The fact is advertised in the WSDL; the client proxy generation will pick that up and produce respective code and configuration; both, client and server, do their part to make it work at runtime; and last not least the developer usually gets the means to access or manipulate the respective information, should the need arise.

Wouldn’t it be nice to have the same apply to your custom demands, demands not covered by the platform? Demands like…

New versions of standards you need to support, but which are not supported by the platform yet.

Homegrown authentication schemes.

Tenants for multi-tenant solutions.

Billing information for services in B2C scenarios.

SLA and diagnostics information for operations

…

Whatever the reason, it would be very nice if we could implement our custom policy in a way that the application developer could use it in a way very similar to policies provided by the platform.

The good news is: It is actually possible to support custom demands in a way very similar to the built-in features of WCF. The not-so-good news: It is not that simple or straight-forward to do, as there a a lot of bits and pieces working together – and no single information source putting them together. Well, this is what I’m trying to accomplish…

Not much to say. WebAPI controllers participate in the scheme we have set up, so the controller is aware what culture the user prefers. The data serialization itself ignores the culture, thus data exchange at the raw level (JSON) is not even affected.

Client side localization.

Apart from a few hints regarding client side validation (which is specifically supported by MVC via unobtrusive validation), everything I presented basically happened on the server.

So, if you build your application using Knockout, Angular, Sencha, or other frameworks – which generate large chunks of the UI employing databinding strategies – you will need to localize on the client as well. The server may still provide the necessary backing in terms of logic and translations e.g. as JSON service.

Taking „client side“ one step further and building container applications based on PhoneGrap/Cordova, you will have to provide everything on the client; you just cannot afford to not render the UI just because the device has no connection right now. Thus you’ll need to address localization completely on the client, functionality as well as information; no server backing in this case, sorry.

Data localization.

For an application used internationally, it may not be sufficient to just localize the UI. You may have to localize your actual data. Formats, content, even business rules.

This may include providing downloadable content in different languages. (That exposé just became a collection, rather than a single file.) Take the different naming schemes into account. International addresses? Have fun. Types of business entities. Currencies, calendars, other units of measurement. (Thank god, we‘re talking about business applications; historians have to deal with the really funny stuff… . (Some people actually think IBAN and BIC are simple… .)

Well, I’m going to leave these topics for someone else. And with that, I conclude this little series. You can find the sources of the sample I built for this series on github (VS2013 project, NuGet packages have to be restored using “Enable NuGet Package Restore”, IIS Express is expected).

That’s all for now folks, AJ.NET

Filed under: .NET, .NET Framework, ASP.NET MVC, HTML5, Internationalization]]>https://ajdotnet.wordpress.com/2014/04/19/asp-net-mvc-i18n-part-10-finish/feed/0ajdotnetASP.NET MVC I18n – Part 9: 3rd Party Controlshttps://ajdotnet.wordpress.com/2014/02/01/asp-net-mvc-i18n-part-9-3rd-party-controls/
https://ajdotnet.wordpress.com/2014/02/01/asp-net-mvc-i18n-part-9-3rd-party-controls/#commentsSat, 01 Feb 2014 14:48:19 +0000http://ajdotnet.wordpress.com/?p=1122]]>Localization quite regularly involves localizing additional 3rd party controls. This is something that your control has – obviously – to support. Fortunately many controls – certainly the commercial ones, such as Telerik do. Unfortunately (but not unexpectedly) each and every one has its own approach to localization.

To get a better feeling for the demands, let’s take a look at the jQuery UI date picker– the canonical example for additional controls.

Using the date picker is relatively simple: It typically is already included in an MVC project, the respective bundles for script and CSS files are readily defined and only need to be included in the _layout.cshtml. That done, a little initialization script (datepicker.initialize.js) will turn a textbox into a date picker:

In order to localize the date picker, you need respective localization files. You can either grab them all (quite simple using the nuget package jQuery.UI.i18n), or you can grab the ones you actually need from github. Using these files, again, causes minimal impact if you simple include them in the bundle as above:

Including the localization scripts will not only register the necessary information, it will actually switch the default language for the date picker. So, if you grabbed the file using nuget, you will end up with Chinese (zh-TW) as date picker region…

With single files, you might include just the one that is actually needed, and avoid that issue. Only you can’t use the nuget package in this cases, as it contains one single script file with all localizations. In any case you could provide your own initialization, that comes after those scripts and sets the date picker region to the correct one, by adjusting the initialization script above:

We have all the information handy and did the same thing for globalize, right?

Wrong actually. Date picker localizations generally exist for the neutral culture (e.g. de) and only those specific cultures that differ form the default one. E.g. there is a localized version for en-GB, but not en-US, or de-DE respectively, as en and de are sufficient. On top of that the date picker does not support a proper fallback strategy, i.e. setting the region to de-DE will end up using the last included region, again zh-TW if you included all regions, not de.

The solution is a mapping from our application‘s supported regions to regions supported by the date picker. You could do this on the server and provide a second attribute (e.g. langDatePicker) beside lang on the html tag. If you grabbed single localization files for the date picker, you could automate this by just scanning the available .js files. Or – for just two regions probably the more sensible approach – just do it in the initialization script:

And now the date picker changes formats, appearance (e.g. first day of the week), etc.:

Verdict

Localizing the date picker control can e done completely in all aspects. But there are also some inconsistencies compared to localizing the validation:

The globalize nuget package comes with single files, the date picker nuget package provides one consolidated file. This makes it harder to include just the one localization needed. (Performance is hardly an argument, as this is addressed by the bundle logic anyway.)

With Globalize you need to set a region explicitly, the date picker does it implicitly with referencing the localization file.

Globalize supports a fallback to the neutral culture if the specific region is not available. Date picker does nothing of the kind and simply ignores the call.

And these are the subtle differences in two packages from the jQuery universe. That might be a good indicator as to what to expect with 3rd party libraries from another source. Bring together a couple of controls, and you’ll have a mighty mishmash.

This is another topic that is widely documented for the most part, but has some notable gaps.

Remember the error from last post:

Having the error message in localized German does not solve the fact that the date is actually in the valid local format in the first place. We should not even get an error.

The basic problem is that jQuery validation uses regular JavaScript methods to do validation, thus some valid data, if in localized format, will produce validation errors. But even worse is the fact that some data validates just fine – but with a wrong value. E.g. point and comma in numeric values switch their meaning from en-US to de-DE, similarly day and month change their position between en-US and fr-FR.

The generally cited answer to solve this issue is to use Globalize from github… which requires a little handiwork.

First…

… you need to grab the globalize.js file from github under lib\ as well as the necessary localizations under lib\cultures\. If you require compressed versions (globalize.min.js below), you’ll have to create them yourself, e.g using http://jscompress.com/, as they are not provided. All files are then placed in the /Scripts folder of your web project.

Note: there is also a nuget package, which will install these files – including all localizations, but still no minified version.

Second…

… the scripts need to be included in our views. There are two options, which can both be found:

For this a call to Globalize.culture is necessary. You could generate the respective call an the server, passing in the current UI culture – which is what you’ll see very often in tutorials. However the information is already available on the client (because we put it there), thus a static script globalize.initialize.js will do (and will benefit http caching):

We have the necessary infrastructure for localization, but jQuery validation does not use it yet. The final step is to wire jQuere validation with the new globalize methods. This is something that everyone has to do. Something that is quite simple. Something that could have been provided. Something that someone could have told you how to do. Guess what? Nobody did. [UPDATE: Turns out, I was wrong, see below. I still kept the following content for the explanations.]

jQuery has an object that provides the necessary validation methods: $.validator.methods. All that is necessary is to reroute them to replacements that make use of the globalization library. For MVC and unobtrusive validation, that requires just 5 methods: number, date, min, max, and range. In yet another additional script file globalize.validation.js:

And now our validation code works just fine, properly recognizing German date and number formats.

UPDATE: Just when I finished writing this post, I stumbled upon John‘s post, which is the first one I found that connects Globalize and jQuery validation both correctly and completely, and even provides a nuget package.