mandag den 23. september 2013

Contact web api from InfoPath Designer 2013

I was having some trouble getting values from my home-brewed web api into a InfoPath Designer 2013 form, so I wanted to document the solution for those of you out there perhaps struggling with this as well.

I was calling a simple 'Hello World'-web api that would return a string. My simple aip looks like this:


namespace ADlookup.Controllers
{
/* model */
public class employee
{
public string employeeId { get; set; }
public string bossId { get; set; }

}


public class ADLookupController : ApiController
{
[HttpGet]
public employee getNearestBossId([FromUri] string id)
{
return new employee()
{
employeeId = id,
bossId = id
};

}
}
}


However, upon calling this api in InfoPath Designer 2013, I got the following error message:



... to indicate the xml structure is invalid.

I didn't get it - when I called the service directly from my browser, valid xml was returned!:



The problem, as it turned out, was of course the one that as opposed to the xml displayed by my browsers, the InfoPath Designer application - correctly - retrieved the data by way of json, the web api's default MO.

So, in order to serve up only XML, for InfoPath to agree with, we'll strip away the web api's possibility of serving up json altogether. Modify your WebApiConfig to resemble the below, though of course take into consideration the routes you have for your own app:


public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);

// tbe below must be enabled if this rest service is used with infopath designer 2013 - it only accepts xml data.
// thus we'll remove the json return type
var formatters = GlobalConfiguration.Configuration.Formatters;
formatters.Remove(formatters.JsonFormatter);

}
}


Now, as we re-publish the web api service, we can try once more the url in InfoPath, which will now allow us to proceed to the next step:


Intriguingly, on a completely different note, the 'get data from http rest service' workflow component in Sharepoint Designer 2013 works off JSON, as opposed to XML! But that's a blog-entry for another rainy day.

Hope this helps someone, anyone,

thanks for reading.

torsdag den 5. september 2013

Prevent browser caching of css and javascript files

A modern browser will attempt to cache content as best it can, to make for a better end-user experience. This works well, but we may run into issues when we deploy a set of different files to the server, yet the client browser insists on serving up the old ones out of its cache.

So here's a tip on how to force the client browser to reload newly deployed files. You can use this with any kind of content file served over an http connection, be it css-files, javascript files, you name it.

The trick is to add an updated querystring value to the content url. For example, instead of



< link media='screen and (max-width: 2560px)' href="~/Content/Site.css" rel="stylesheet" />


... we go ...


< link media='screen and (max-width: 2560px)' href="~/Content/Site.css?v=1.0.4034.343343" rel="stylesheet" />


... instead. With each deployment, the 'v' value changes, which will force the client into retrieving a new version of the file on the server.

I'm myself adding the assembly version into the url. I'm speficially doing this, which works with the ASP.NET MVC framework:


 @{
        string versionId = System.Reflection.Assembly.GetAssembly(typeof(timeRegistrering.Web.Controllers.HomeController)).GetName().Version.ToString();
    }

    < link media='screen and (max-width: 2500px)' href="~/Content/Site.css?v=@{@versionId}" rel="stylesheet" />


The above will render as follows into the browser:


  < link media='screen and (max-width: 2500px)' href="/Content/Site.css?v=1.0.4996.19123" rel="stylesheet" />


As the assembly version changes with every build or publish, the url will change accordingly - and the content will be retrieved 'fresh' from the server, as now the client can no longer find the old version with a different version number.

In order to make your assembly version number auto-increment, you'll want to change the following lines in your 'assemblyInfo.cs' file (as found in the 'Properties' folder in your project):



// You can specify all the values or you can default the Build and Revision Numbers 
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.1")]
[assembly: AssemblyFileVersion("1.0.0.1")]


Should be changed to:


  // You can specify all the values or you can default the Revision and Build Numbers 
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyFileVersion("1.0.*")]


The asterix '*' sign will be replaced with the assembly number automatically, to increment on each build/publish.

HTH.

tirsdag den 3. september 2013

Force Internet Explorer compatibility mode off

The Internet Explorer compatibility-mode is a rendering mode to suit older web-pages, typically below and including IE8. They're usually associated with Intranet-sites, in which legacy components often abounds.

To a web-developer it can be hugely frustrating - I know for me it certainly is - to develop that which beyond your control renders horribly in an otherwise 'healthy' IE browser.

The fix - apart from using a different browser, not always a suitable solution - is to include the following meta-tag in the page header section.


< meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" >


The above MUST be the very first meta-tag included within the header section, or you risk the chance of it not working to your satisfaction. As you include it, and browse to the web page with compatibility mode turned on, the tag will force your IE to load the page with the rendering engine pertaining to the browser itself, and not some legacy rendering instead.

HTH