{"id":1378,"date":"2013-03-13T21:35:02","date_gmt":"2013-03-13T21:35:02","guid":{"rendered":"http:\/\/www.stuartroberts.net\/?p=1378"},"modified":"2013-04-04T12:41:51","modified_gmt":"2013-04-04T11:41:51","slug":"register-code-behind-infopath-form-for-web-browsing","status":"publish","type":"post","link":"http:\/\/www.stuartroberts.net\/index.php\/2013\/03\/13\/register-code-behind-infopath-form-for-web-browsing\/","title":{"rendered":"Register Code Behind InfoPath Form for Web Browsing"},"content":{"rendered":"<p>This post describes how to deploy a web browser compatible InfoPath form, with code-behind, through a SharePoint feature.<\/p>\n<p>Installing and registering an InfoPath form, along with a custom content type is pretty straight forward once you know the required steps.<\/p>\n<p>Start by creating a content type that inherits from the <em>Forms<\/em> type.  The following is a sample content type&#8217;s markup.<\/p>\n<pre lang=\"xml\">\r\n<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Elements xmlns=\"http:\/\/schemas.microsoft.com\/sharepoint\/\">\r\n  <ContentType ID=\"0x0101010076AEDEA7CA2A44B59ECB3D491618E052\"\r\n        Name=\"Custom Form CT\"\r\n        Group=\"Custom\"\r\n        Inherits=\"TRUE\"\r\n        RequireClientRenderingOnNew=\"FALSE\"\r\n        Version=\"0\">\r\n    <FieldRefs>\r\n    <\/FieldRefs>\r\n    <DocumentTemplate TargetName=\"\/FormServerTemplates\/CustomForm.xsn\" \/>\r\n  <\/ContentType> \r\n<\/Elements>\r\n<\/pre>\n<p><!--more--><br \/>\nThe important sections from the above markup are the <em>ID<\/em> and <em>RequireClientRenderingOnNew<\/em> attributes.<\/p>\n<p>For your new content type to be usable in a Forms library (or for that matter the XmlFormView class) and use a web compatible InfoPath form it must inherit from the Form content type, which has an ID of 0x010101. To inherit from this all you have to do is add two zeros and then your own identifier.<\/p>\n<p>The second attribute, <em>RequireClientRenderingOnNew<\/em>, specifies if the browser should use the application specified by the ProgId attribute (not shown here as it&#8217;s inherited from the parent content type) when creating or viewing a form.  By default this is set to true, setting to false will configure the content type to render the form in the browser, using the <em>FormServer.aspx<\/em> page that&#8217;s located in the <em>LAYOUTS<\/em> folder.<\/p>\n<p>The next step is to create your InfoPath form.  For this example, I&#8217;ll create a very simple form with some custom code.<\/p>\n<p>Start by opening InfoPath and add three text boxes of integer type and a button control:<\/p>\n<p><a href=\"http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2013\/03\/Form1.jpg\"><img decoding=\"async\" loading=\"lazy\" src=\"http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2013\/03\/Form1.jpg\" alt=\"InfoPath Form\" width=\"959\" height=\"496\" class=\"aligncenter size-full wp-image-1384\" srcset=\"http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2013\/03\/Form1.jpg 959w, http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2013\/03\/Form1-300x155.jpg 300w\" sizes=\"(max-width: 959px) 100vw, 959px\" \/><\/a><\/p>\n<p>Now to configure the form for web browsing and add some code-behind.<\/p>\n<p>Select the <em>Home<\/em> tab and then click <em>Advanced form options<\/em>:<\/p>\n<p><a href=\"http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2013\/03\/Form-Options.jpg\"><img decoding=\"async\" loading=\"lazy\" src=\"http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2013\/03\/Form-Options.jpg\" alt=\"Form Options\" width=\"683\" height=\"620\" class=\"aligncenter size-full wp-image-1385\" srcset=\"http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2013\/03\/Form-Options.jpg 683w, http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2013\/03\/Form-Options-300x272.jpg 300w\" sizes=\"(max-width: 683px) 100vw, 683px\" \/><\/a><\/p>\n<p>The first thing you need to configure is the security and trust level to <\/em>Domain<\/em>.  This grant the form adequate permissions to be able to deploy it as part of a SharePoint solution.<\/p>\n<p><a href=\"http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2013\/03\/Security-and-Trust.jpg\"><img decoding=\"async\" loading=\"lazy\" src=\"http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2013\/03\/Security-and-Trust.jpg\" alt=\"Security and Trust\" width=\"689\" height=\"468\" class=\"aligncenter size-full wp-image-1386\" srcset=\"http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2013\/03\/Security-and-Trust.jpg 689w, http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2013\/03\/Security-and-Trust-300x203.jpg 300w\" sizes=\"(max-width: 689px) 100vw, 689px\" \/><\/a><\/p>\n<p>Next, ensure the compatibility of the form is set to Web Browser Form:<\/p>\n<p><a href=\"http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2013\/03\/Compatibility.jpg\"><img decoding=\"async\" loading=\"lazy\" src=\"http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2013\/03\/Compatibility.jpg\" alt=\"Web Browser Form\" width=\"691\" height=\"232\" class=\"aligncenter size-full wp-image-1387\" srcset=\"http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2013\/03\/Compatibility.jpg 691w, http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2013\/03\/Compatibility-300x100.jpg 300w\" sizes=\"(max-width: 691px) 100vw, 691px\" \/><\/a><\/p>\n<p>Finally, select your code preference and location:<\/p>\n<p><a href=\"http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2013\/03\/Programming.jpg\"><img decoding=\"async\" loading=\"lazy\" src=\"http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2013\/03\/Programming.jpg\" alt=\"Programming Language\" width=\"690\" height=\"325\" class=\"aligncenter size-full wp-image-1389\" srcset=\"http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2013\/03\/Programming.jpg 690w, http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2013\/03\/Programming-300x141.jpg 300w\" sizes=\"(max-width: 690px) 100vw, 690px\" \/><\/a><\/p>\n<p>Back in the form, right click the button control and select Properties:<\/p>\n<p><a href=\"http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2013\/03\/Button-Properties.jpg\"><img decoding=\"async\" loading=\"lazy\" src=\"http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2013\/03\/Button-Properties.jpg\" alt=\"Button Properties\" width=\"388\" height=\"399\" class=\"aligncenter size-full wp-image-1390\" srcset=\"http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2013\/03\/Button-Properties.jpg 388w, http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2013\/03\/Button-Properties-291x300.jpg 291w\" sizes=\"(max-width: 388px) 100vw, 388px\" \/><\/a>.<\/p>\n<p>Then, click Edit Form Code in the popup dialog:<\/p>\n<p><a href=\"http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2013\/03\/Edit-Form-Code.jpg\"><img decoding=\"async\" loading=\"lazy\" src=\"http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2013\/03\/Edit-Form-Code.jpg\" alt=\"Edit Form Code\" width=\"413\" height=\"334\" class=\"aligncenter size-full wp-image-1391\" srcset=\"http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2013\/03\/Edit-Form-Code.jpg 413w, http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2013\/03\/Edit-Form-Code-300x242.jpg 300w\" sizes=\"(max-width: 413px) 100vw, 413px\" \/><\/a><\/p>\n<p>This will load Visual Studio Tools for Applications with a method for capturing the button click event:<\/p>\n<p><a href=\"http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2013\/03\/Form-VSTA-Code.jpg\"><img decoding=\"async\" loading=\"lazy\" src=\"http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2013\/03\/Form-VSTA-Code.jpg\" alt=\"Form Code\" width=\"1479\" height=\"415\" class=\"aligncenter size-full wp-image-1392\" srcset=\"http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2013\/03\/Form-VSTA-Code.jpg 1479w, http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2013\/03\/Form-VSTA-Code-300x84.jpg 300w, http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2013\/03\/Form-VSTA-Code-1024x287.jpg 1024w\" sizes=\"(max-width: 1479px) 100vw, 1479px\" \/><\/a><\/p>\n<p>Add the following code to this method<\/p>\n<pre lang=\"csharp\">\r\nXPathNavigator value1Node = MainDataSource.CreateNavigator().SelectSingleNode(\"\/my:myFields\/my:group1\/my:Value1\", NamespaceManager);\r\nXPathNavigator value2Node = MainDataSource.CreateNavigator().SelectSingleNode(\"\/my:myFields\/my:group1\/my:Value2\", NamespaceManager);\r\nint value1 = value1Node.ValueAsInt;\r\nint value2 = value2Node.ValueAsInt;\r\n\r\nXPathNavigator totalNode = MainDataSource.CreateNavigator().SelectSingleNode(\"\/my:myFields\/my:group1\/my:Total\", NamespaceManager);\r\nint total = value1 + value2;\r\ntotalNode.SetValue(total.ToString());\r\n<\/pre>\n<p>Simple code, but just to demonstrate deploying a form with code-behind.<\/p>\n<p>Save and close VSTA and return to the form.<\/p>\n<p>Now to publish the form from InfoPath.  Select the <em>Home<\/em> tab, <em>Publish<\/em> and then click <em>Network Location<\/em>:<\/p>\n<p><a href=\"http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2013\/03\/Publish.jpg\"><img decoding=\"async\" loading=\"lazy\" src=\"http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2013\/03\/Publish.jpg\" alt=\"Publish Form\" width=\"639\" height=\"569\" class=\"aligncenter size-full wp-image-1393\" srcset=\"http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2013\/03\/Publish.jpg 639w, http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2013\/03\/Publish-300x267.jpg 300w\" sizes=\"(max-width: 639px) 100vw, 639px\" \/><\/a><\/p>\n<p>Select a location to publish the form (not the same location as the current form) and give it a name:<\/p>\n<p><a href=\"http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2013\/03\/Publish-Location.jpg\"><img decoding=\"async\" loading=\"lazy\" src=\"http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2013\/03\/Publish-Location.jpg\" alt=\"Publish Location\" width=\"572\" height=\"426\" class=\"aligncenter size-full wp-image-1394\" srcset=\"http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2013\/03\/Publish-Location.jpg 572w, http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2013\/03\/Publish-Location-300x223.jpg 300w\" sizes=\"(max-width: 572px) 100vw, 572px\" \/><\/a><\/p>\n<p>Click <em>Next<\/em> and clear the text from the text box, click <em>Next<\/em> again and <em>OK<\/em> to the warning.<\/p>\n<p><a href=\"http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2013\/03\/Publish-Warning.jpg\"><img decoding=\"async\" loading=\"lazy\" src=\"http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2013\/03\/Publish-Warning.jpg\" alt=\"Publish Warning\" width=\"1077\" height=\"371\" class=\"aligncenter size-full wp-image-1395\" srcset=\"http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2013\/03\/Publish-Warning.jpg 1077w, http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2013\/03\/Publish-Warning-300x103.jpg 300w, http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2013\/03\/Publish-Warning-1024x352.jpg 1024w\" sizes=\"(max-width: 1077px) 100vw, 1077px\" \/><\/a><\/p>\n<p>To finish click <em>Publish<\/em> and then <em>Close<\/em>.  Close InfoPath and open your Visual Studio SharePoint project, or create a new one.<\/p>\n<p>From within your SharePoint project, you\u2019ll need to add the published InfoPath form and configure a feature to correctly deploy it. To add the form, create a new module, deleting the Sample.txt file that it automatically creates. Add the published form to this module. Your module\u2019s elements XML file should now look something like the following:<\/p>\n<pre lang=\"xml\">\r\n<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Elements xmlns=\"http:\/\/schemas.microsoft.com\/sharepoint\/\">\r\n  <Module Name=\"FormsModule\" Url=\"PublishedForms\" RootWebOnly=\"TRUE\">\r\n    <File Path=\"XSN\\testform.xsn\" Url=\"testform.xsn\" Type=\"GhostableInLibrary\" \/>\r\n<\/Module>\r\n<\/Elements>\r\n<\/pre>\n<p>Now that you have your form and have added it to your project, the next thing you should do is change the deploy location for the xsn file.  This is an important step, as the InfoPath feature receiver (mentioned in the next paragraph) will only look in the root folder of the feature for candidate files and by default when you add a file to a module it is deployed to its folder.  To do this, select your xsn file in the Solution Explorer, then bring up the Properties pane.<\/p>\n<div id=\"attachment_499\" style=\"width: 300px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2010\/12\/XSN-Properties.png\"><img aria-describedby=\"caption-attachment-499\" decoding=\"async\" loading=\"lazy\" src=\"http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2010\/12\/XSN-Properties-290x300.png\" alt=\"\" title=\"XSN Properties\" width=\"290\" height=\"300\" class=\"size-medium wp-image-499\" srcset=\"http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2010\/12\/XSN-Properties-290x300.png 290w, http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2010\/12\/XSN-Properties.png 329w\" sizes=\"(max-width: 290px) 100vw, 290px\" \/><\/a><p id=\"caption-attachment-499\" class=\"wp-caption-text\">XSN Properties<\/p><\/div>\n<p>Expand the <em>Deployment Location<\/em> node and clear the <em>Path<\/em> attribute.  This will change the deployment location for your xsn file to the root of the relevant feature.<\/p>\n<p>Next, add the assembly for the compiled InfoPath form to your project at the same location as the form.  This will be in the bin folder of the location you specified as the code location for the form.<\/p>\n<p>Do the same for this file as you did for the form and clear the <em>Deployment Location<\/em> node.<\/p>\n<p>Your elements XML should now look something like:<\/p>\n<pre lang=\"xml\">\r\n<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Elements xmlns=\"http:\/\/schemas.microsoft.com\/sharepoint\/\">\r\n  <Module Name=\"FormsModule\" Url=\"PublishedForms\" RootWebOnly=\"TRUE\">\r\n    <File Path=\"testform.xsn\" Url=\"testform.xsn\" Type=\"GhostableInLibrary\" \/>\r\n    <File Path=\"Form1.dll\" Url=\"Form1.dll\" \/>\r\n  <\/Module>\r\n<\/Elements>\r\n<\/pre>\n<p>We don&#8217;t need the assembly deployed to the PublishedForms library, so remove that line from the Elements file, so you end up with:<\/p>\n<pre lang=\"xml\">\r\n<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Elements xmlns=\"http:\/\/schemas.microsoft.com\/sharepoint\/\">\r\n  <Module Name=\"FormsModule\" Url=\"PublishedForms\" RootWebOnly=\"TRUE\">\r\n    <File Path=\"testform.xsn\" Url=\"testform.xsn\" Type=\"GhostableInLibrary\" \/>\r\n  <\/Module>\r\n<\/Elements>\r\n<\/pre>\n<p>Now you have three options.  The first is good if you are not bothered about the content type that is used.  If this is the case, you can ignore the creation of the content type from the start of this post.  This is because if you deploy the form as part of a feature and specify the XsnFeatureReceiver class from the Microsoft.Office.InfoPath.Server assembly as the receiver, your form is automatically registered for web browsing and a suitable content type is created under the <em>Microsoft Office InfoPath<\/em> group with your form associated.  The assembly and class values are shown below.<\/p>\n<p><em>Receiver Assembly<\/em> = Microsoft.Office.InfoPath.Server, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c<br \/>\n<em>Receiver Class<\/em> = Microsoft.Office.InfoPath.Server.Administration.XsnFeatureReceiver<\/p>\n<p>When using this feature receiver, you&#8217;ll also have to add an activation dependency to your feature, otherwise the receiver may not fire.  The dependency is for the <em>InfoPath Forms Service support<\/em> feature with the GUID <em>C88C4FF1-DBF5-4649-AD9F-C6C426EBCBF5<\/em>.<\/p>\n<div id=\"attachment_501\" style=\"width: 310px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2010\/12\/Activation-Dependency.png\"><img aria-describedby=\"caption-attachment-501\" decoding=\"async\" loading=\"lazy\" src=\"http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2010\/12\/Activation-Dependency-300x48.png\" alt=\"\" title=\"Activation Dependency\" width=\"300\" height=\"48\" class=\"size-medium wp-image-501\" srcset=\"http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2010\/12\/Activation-Dependency-300x48.png 300w, http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2010\/12\/Activation-Dependency.png 484w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-501\" class=\"wp-caption-text\">Activation Dependency<\/p><\/div>\n<p>With the second method if you were to deploy the above content type and then the form with the XsnFeatureReceiver feature receiver, not only will your form be registered, but your content type will also be enabled for displaying the form in the browser.  This is only the case if your content type directly inherits from the <em>Form<\/em> content type.  If your content type is once removed then this step will fail.<\/p>\n<p>The last method is for content types that do not directly inherit from the <em>Form<\/em> type.<\/p>\n<p>Add an event handler to the feature that deploys your form, this will remove the reference to any existing receiver that you may be referencing.<\/p>\n<p>Add the <em>Microsoft.Office.InfoPath.Server.dll<\/em> assembly to your project.<\/p>\n<p>Next add the following using declarations:<\/p>\n<pre lang=\"csharp\">\r\nusing System;\r\nusing System.Collections.Generic;\r\nusing System.IO;\r\nusing System.Runtime.InteropServices;\r\nusing System.Security.Permissions;\r\n\r\nusing Microsoft.SharePoint;\r\nusing Microsoft.SharePoint.Administration;\r\nusing Microsoft.SharePoint.Utilities;\r\nusing Microsoft.SharePoint.Security;\r\nusing Microsoft.Office.InfoPath.Server.Administration;\r\n<\/pre>\n<p>This feature will implement the FeatureInstalled, FeatureActivated and FeatureUninstalling events.  On installation we will register all forms that are being deployed as part of your feature. The activated event will update the content type to allow web rendering and uninstalling will unregister the forms from the site collection.<\/p>\n<p>The installed method is shown below.<\/p>\n<pre lang=\"csharp\">\r\npublic override void FeatureInstalled(SPFeatureReceiverProperties properties)\r\n{\r\n    base.FeatureInstalled(properties);\r\n\r\n    FormsService formsService = GetFormsService();\r\n    if (formsService == null)\r\n    {\r\n        throw new ArgumentNullException(\"formsService\",\r\n                        string.Format(\"Unable to retrieve FormsService during installation of \\\"{0}\\\". Argument formsService was null.\"),\r\n                                        properties.Feature.Definition.Name);\r\n    }\r\n\r\n    \/\/ Get list of form templates that are being deployed as part of this feature.\r\n    IEnumerable<String> formTemplates = GetInfoPathFormTemplates(properties.Definition.RootDirectory);\r\n    foreach (string formTemplate in formTemplates)\r\n    {\r\n        if (formsService.FormTemplates.ItemFromFile(formTemplate) == null)\r\n        {\r\n            FormTemplateCollection.RegisterFormTemplate(formTemplate, properties.Definition, false);\r\n        }\r\n    }\r\n}\r\n<\/pre>\n<p>This method gets the FormsService using a custom private method which we&#8217;ll come to later.  The FormsService object allows you to access the currently registered forms.<\/p>\n<p>Next we call the GetInfoPathFormTemplates method, which again is a custom private method.  This method returns a generic list of paths to the forms that are referenced in your feature.  As with the previous method, I&#8217;ll show this later.<\/p>\n<p>The last step of this event is to call the static method <em>RegisterFormTemplate<\/em> of the <em>FormTemplateCollection<\/em> class.  The full namespace for this class is <em>Microsoft.Office.InfoPath.Server.Administration<\/em>.  This method will register the form on the farm.<\/p>\n<p>The uninstall event is very similar but this time unregisters the forms.<\/p>\n<pre lang=\"csharp\">\r\npublic override void FeatureUninstalling(SPFeatureReceiverProperties properties)\r\n{\r\n    base.FeatureUninstalling(properties);\r\n\r\n    FormsService formsService = GetFormsService();\r\n    if (formsService == null)\r\n    {\r\n        throw new ArgumentNullException(\"formsService\",\r\n                            string.Format(\"Unable to retrieve FormsService during uninstallation of \\\"{0}\\\". Argument formsService was null.\"),\r\n                            properties.Feature.Definition.Name);\r\n    }\r\n\r\n    \/\/ Get list of form templates that were deployed as part of this feature.\r\n    IEnumerable<String> formTemplates = GetInfoPathFormTemplates(properties.Definition.RootDirectory);\r\n    foreach (string formTemplate in formTemplates)\r\n    {\r\n        if (formsService.FormTemplates.ItemFromFile(formTemplate) != null)\r\n        {\r\n            formsService.FormTemplates.UnregisterFormTemplate(formTemplate, properties.Definition);\r\n        }\r\n    }\r\n}\r\n<\/pre>\n<p>The main difference here is that to unregister we don&#8217;t call a static method of <em>FormTemplateCollection<\/em> but instead call the <em>UnregisterFormTemplate<\/em> method of the <em>FormTemplates<\/em> property contained in the <em>FormsService<\/em> object that was retrieved at the start of the method.<\/p>\n<p>The two methods used by the installing and activated events are shown below:<\/p>\n<pre lang=\"csharp\">\r\nprivate IEnumerable<String> GetInfoPathFormTemplates(string featureRootPath)\r\n{\r\n    FileInfo[] filesInfo = new DirectoryInfo(featureRootPath).GetFiles(\"*.xsn\");\r\n    List<String> infoPathFormFileSpecs = new List<String>();\r\n    foreach (FileInfo fileInfo in filesInfo)\r\n    {\r\n        infoPathFormFileSpecs.Add(Path.Combine(fileInfo.DirectoryName, fileInfo.Name));\r\n    }\r\n\r\n    return infoPathFormFileSpecs;\r\n}\r\n\r\nprivate FormsService GetFormsService()\r\n{\r\n    FormsService formsService;\r\n    if (SPFarm.Local != null)\r\n    {\r\n        formsService = SPFarm.Local.Services.GetValue<FormsService>(FormsService.ServiceName);\r\n    }\r\n    else\r\n    {\r\n        formsService = SPContext.Current.Site.WebApplication.Farm.Services.GetValue<FormsService>(FormsService.ServiceName);\r\n    }\r\n    return formsService;\r\n}\r\n<\/pre>\n<p><em>GetInfoPathFormTemplates<\/em> looks in the root path of the feature for any file with the xsn extension and returns the path information.<\/p>\n<p><em>GetFormsService<\/em> attempts to get the FormsService object from the local farm, first by referencing the SPFarm object directly.  Where this is null, it tries to retrieve it from SPContext.<\/p>\n<p>The last piece of code to complete the registration is for the activated event.  Here we will be updating a custom content type, twice removed from the <em>Form<\/em> type.<\/p>\n<pre lang=\"csharp\">\r\nprivate const string MINIMALACTIVEXTOOPEN = \"SharePoint.OpenXmlDocuments.2\";\r\n\r\npublic override void FeatureActivated(SPFeatureReceiverProperties properties)\r\n{\r\n    SPSite site = properties.Feature.Parent as SPSite;\r\n    SPWeb currentWeb = site.RootWeb;\r\n\r\n    \/\/ Update the custom content type to allow rendering in web browser.\r\n    SPContentType ct = currentWeb.ContentTypes[new SPContentTypeId(\"0x0101010076AEDEA7CA2A44B59ECB3D491618E05200726740CD03C4478FB0897E6993DDE8D0\")];\r\n    if (ct.NewDocumentControl != MINIMALACTIVEXTOOPEN || ct.RequireClientRenderingOnNew)\r\n    {\r\n        ct.NewDocumentControl = MINIMALACTIVEXTOOPEN;\r\n        \/\/ Ensure the RequireClientRenderingOnNew property is correctly set for web browsing.\r\n        ct.RequireClientRenderingOnNew = false;\r\n\r\n        \/\/ Don't forget to update the content type with the changes.\r\n        ct.Update(true, false);\r\n    }\r\n}\r\n<\/pre>\n<p>As this example feature is scoped to site level, we only need to cast the <em>Parent<\/em> object to SPSite.<\/p>\n<p>Using the root SPWeb object the custom content type is retrieved by its identifier. This could just as easily be a collection of content types, but for this example we are only updating one.<\/p>\n<p>The two properties that are being updated are <em>NewDocumentControl<\/em> and <em>RequireClientRenderingOnNew<\/em>.<\/p>\n<p><em>NewDocumentControl<\/em> identifies the application used to create new document, which for InfoPath forms should be set to &#8220;SharePoint.OpenXmlDocuments.2&#8221;.<\/p>\n<p>The second property, <em>RequireClientRenderingOnNew<\/em> will have already been defined in the content type markup, but it&#8217;s worthwhile making sure at this stage, otherwise  you won&#8217;t be able to view the form in the web browser.<\/p>\n<p>Now when you activate the feature you will have an InfoPath form, with code-behind, that is able to be viewed in the browser.  Remember that for this to work you will require the Enterprise version of SharePoint.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This post describes how to deploy a web browser compatible InfoPath form, with code-behind, through a SharePoint feature. Installing and registering an InfoPath form, along with a custom content type is pretty straight forward once you know the required steps. &hellip; <a href=\"http:\/\/www.stuartroberts.net\/index.php\/2013\/03\/13\/register-code-behind-infopath-form-for-web-browsing\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_mi_skip_tracking":false,"jetpack_post_was_ever_published":false,"jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":[]},"categories":[9,3],"tags":[84,81],"jetpack_publicize_connections":[],"aioseo_notices":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/plx2I-me","_links":{"self":[{"href":"http:\/\/www.stuartroberts.net\/index.php\/wp-json\/wp\/v2\/posts\/1378"}],"collection":[{"href":"http:\/\/www.stuartroberts.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.stuartroberts.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.stuartroberts.net\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.stuartroberts.net\/index.php\/wp-json\/wp\/v2\/comments?post=1378"}],"version-history":[{"count":16,"href":"http:\/\/www.stuartroberts.net\/index.php\/wp-json\/wp\/v2\/posts\/1378\/revisions"}],"predecessor-version":[{"id":1417,"href":"http:\/\/www.stuartroberts.net\/index.php\/wp-json\/wp\/v2\/posts\/1378\/revisions\/1417"}],"wp:attachment":[{"href":"http:\/\/www.stuartroberts.net\/index.php\/wp-json\/wp\/v2\/media?parent=1378"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.stuartroberts.net\/index.php\/wp-json\/wp\/v2\/categories?post=1378"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.stuartroberts.net\/index.php\/wp-json\/wp\/v2\/tags?post=1378"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}