Saturday, January 28, 2012

Converting UTC DateTime to local timezone in WP7

I'm currently using the following to convert a DataTime know to be in NZST to NZDT when applicable. I.e. The code will automatically determine if daylight savings should be applied.

    public static DateTime DateTimeFromNzst(DateTime nzstDateTime)
    {
        // Known offset from UTC
        TimeSpan nzstOffset = new TimeSpan(12, 0, 0);
        DateTimeOffset dateTimeOffset = new DateTimeOffset(nzstDateTime, nzstOffset);
        DateTimeOffset dateTimeOffsetConvertedToLocal = TimeZoneInfo.ConvertTime(dateTimeOffset, TimeZoneInfo.Local);
        return dateTimeOffsetConvertedToLocal.DateTime;
    }

It should also be possible to convert from UTC to the local timezone by adjusting the known UTC offset to 0.

    public static DateTime DateTimeFromUtc(DateTime utcDateTime)
    {
        // Known offset from UTC
        TimeSpan utcOffset = new TimeSpan(0, 0, 0);
        DateTimeOffset dateTimeOffset = new DateTimeOffset(utcDateTime, utcOffset);
        DateTimeOffset dateTimeOffsetConvertedToLocal = TimeZoneInfo.ConvertTime(dateTimeOffset, TimeZoneInfo.Local);
        return dateTimeOffsetConvertedToLocal.DateTime;
    }

Friday, January 13, 2012

Salesforce Inbound Change Sets Deploy Error - organization's administration setup lock

During the validation and deployment of an inbound change set into a Salesforce production organisation I often run into the following issue.

I'll start either the validation or deployment action, wait awhile for the spin wheel to complete and then get a failed result.

The failure reason will be given as:

API Name: Deploy Error
Problem: The changes you requested require salesforce.com to temporarily lock your organization's administration setup. However, the administration setup has already been locked by another change. Please wait for the previous action to finish, then try again later.

If I wait for a period of time without any further action another deployment history will appear with the actual results of the action I started. It's like the deployment action splits off at some point and shows as both a failure due to the org admin setup lock and then later a success when it actually completes.

Wednesday, December 14, 2011

Safe URLs for use with Salesforce Custom Buttons/Links and PageReferences

I encountered an issue today with an inherited Salesforce App and references to custom Visualforce pages. As they were, the references would work fine in the development sandbox or when deployed via an unmanaged package. However, when they were deployed via a managed package with the associated namespace the links from the custom buttons would break.

The custom button would have a link to the Visualforce page like:

/apex/TheVisualforcePage?param1={!Opportunity.Id}

The issue is the missing namespace prefix from the Visualforce page when used in a managed package.

To resolve this the Visualforce page reference should be done using URLFOR. Ideally with some form of explicit reference to the page like this:

{!URLFOR($Page.TheVisualforcePage,'',[param1 = opportunity.id])}

However, the $Page Global Variable isn't an available function and results in an error. To help resolve this please go to IdeaExchange: Custom Button: Expose $Page in the URL Content Type and promote the idea.

The same issue occurs within the Apex code with PageReference. There were a number of instances like:

Pagereference ref = new Pagereference('/apex/TheVisualforcePage?param1=' + opportunityId);

The preferred method was to use explicit references to the page.

PageReference p = Page.TheVisualforcePage;
p.getParameters().put('param1', opportunity.id);

See Also:

Friday, December 2, 2011

Salesforce INSUFFICIENT_ACCESS: Upsert requires view all data on a non-unique custom index

INSUFFICIENT_ACCESS: Upsert requires view all data on a non-unique custom index

I recently encountered this error when trying to do an upsert through the Partner API using a particular users session. For other users it works fine.

Here is the same message with the important part emphasised: "INSUFFICIENT_ACCESS: Upsert requires view all data on a non-unique custom index". This also ties back to the Partner API upsert documentation:

If you are upserting an object that has the External ID attribute selected but not the Unique attribute selected, (a non-unique index) your client application must have the permission "View All Data" to execute this call. Having this permission prevents the client application from using upsert to insert an accidental duplicate record because it couldn’t see that the record existed.

The "View All Data" permission is set under the Administrative Permissions section of a profile.

As per its section (Administrative Permissions) and typically only being assigned to the System Administrator profile it is a fairly powerful permission to have. From the help doc:

Permission Name Description Functions Controlled Profiles
View All Data View all organizational data, regardless of sharing settings. View all data owned by other users System Administrator

Tuesday, November 29, 2011

Windows Phone 7 Development tips presentation

Here are the slides from my recent presentation in case you need any of the links.


You may also want to look at:

Friday, November 18, 2011

HTTP/1.1 WebRequest with the Expect: 100-continue header

Ran into an issue today when calling a web service from .NET.
If the Expect: 100-continue HTTP header was included in the request the web server would flip out and return a response that couldn't be parsed. Fiddler gave it as:

HTTP Protocol Violation
Fiddler has detected a protocol violation in session #41.

Cannot parse HTTP response; Status line contains no spaces. Data:

 0
[Fiddler] Response Header parsing failed.
Response Data:
<plaintext>
30 0D 0A 0D 0A                                                           0....                

In .NET is appeared as:

The server committed a protocol violation. Section=ResponseStatusLine

Apparently this header is added automatically by .NET when doing a POST with HTTP/1.1 to indicate that the post data isn't sent with the initial request. So if the web server rejects the request we hasn't wasted time sending all the data up. This has also been a known issue for some time now - See HttpWebRequest and the Expect: 100-continue Header Problem from 2004.

The solution to stop the header being added is relatively simple:

WebRequest request = null;
//...
((HttpWebRequest)request).ServicePoint.Expect100Continue = false;

Monday, November 14, 2011

Getting WP7 Reviews from all Marketplace locales

Currently from the App Hub - Application Details page it is only possible to see the reviews from one locale at a time.

The Windows Phone 7 Review Reader in an online Silverlight application that can aggregate all the results for an app given the Application Id Guid.