So first of all we need content types and fields.

Our example will be 3 content types:

  • Invoices with the fields: tax%, articles (multi lookup), quantity, invoice total, client (lookup)
  • client with the fields: name, address, city, telephone number
  • article with the fields: article name, price per unit , description

In the example that you can download (link will be provided at the bottom) I went a little overboard with the naming of my fields. But you can clearly see what fields are for article, client and invoice. 

All the types of fields can often be challenging to remember all the attributes that are necessary, so I often use this blog to check if I forgot anything.

A good link with explanation about lookups.

Pay attention to this line in his blog:

Checking the field from code showed that the LookupList property of the site column was “Lists/Tasks”, so it was not resolved to the list GUID on feature activation.

Now the way he fixes the issue isn’t that bad, but after looking for some deeper issue as to why it behaved like described I came across another blog writing in depth why and the solution on how to solve it “cleanly”.

The summary of the blog:

So long as you specify Overwrite="true" for Field elements of type Lookup, LookupMulti, TaxonomyFieldType, etc., relative references will work. And you can completely disregard the "created in the same feature" statement in the MSDN reference.

Defining the fields, content type and lists:

Now if you want to define all the content types in a single elements file and all the fields in a single elements file.

No problem what so ever, but  when it’ comes to lookup fields you’re going to have an issue… especially when you are creating lists that use these content types.

The chicken or the egg paradox will happen here. You are defining a lookup field with a soft reference to a list that doesn’t exist yet in the flow of deployment. So your lookup field will be deployed but will not work (lists and fields will be empty)

LookupEmpty

What to do?

1. Either you define all the fields and content types without the lookup fields, define them later in the flow and attach them via a feature receiver to the correct content type

2. Define all the independent content types (content types that does not contain lookup fields) separately, create the lists accordingly and only then define the content type with the lookup fields and create that list as last.

In the end you’ll notice that the first step isn’t the best one, but the easiest one. If you have 80 content types, 70 lists and 400 fields + 30 lookup fields than good luck keeping track…

So the solution has an additional feature with an element “LookupFields” and a feature receiver.

In this feature receiver I’m going to look for the lookup fields in the site columns and add it to the content types. After that I’m calling for a content type update with the attribute true, so that all the changes are being pushed to everything that inherits the content type.

In the next chapter it’s time for some InfoPath talk.

Download:

While we started looking at all the issues that InfoPath can give us, we would have never guessed all the issues that it could give us.

Given elements that we took into account:

  • Not able to be deployed to other farms, new web applications, not even new site collections (all because the list ID would be changed)
  • Code behind (in InfoPath) was not necessary so this was a big plus (if you have ever done code behind than you know what a pain it can be)
  • nice and easy way to design forms
  • generates the entire form for us so that we can style it any way we want
  • some issue that you could have when using the formservices.asmx via sandbox see here

elements that we later discovered during development:

  • at the moment only “deployment” via the formservices.asmx is possible (so when attaching the xsn file to the list, we only found 1 way on how to do this, more on that in a later chapter)
  • if you are using lookup fields in combination with InfoPath you are in for a long way

The SharePoint list form can’t be customized with InfoPath because fields of an unsupported data type are marked as required, or because fields are corrupted. In SharePoint, try deleting the columns or editing the column properties to remove the required attribute.

– Field Name (Lookup)

When you will see this error it’s either 2 things, the lookup in the list points to nothing (maybe an inconsistency with the parent content type, see if the lookup field in the content type is also not working, if it is, just edit the field, change nothing, ok – ok and try the InfoPath form again.

The second way is the hard way.. depending on how you deploy your lookup field this can be an issue, with or without webID…. (will be explained in chapter 3)

  • did I mention the “deployment procedure” already? Glimlach
  • even the white spacing in the manifest.xsf file will give you issues when editing it (manifest.xsf is an internal file in the .xsn file)

for InfoPath it’s not the same if the structure of your node is

<node>

</node>

while it must be <Node></Node>

These are the things that I can think of at the moment, if more come to mind I will add them here.

Next chapter is about content types and fields (also how to deploy a lookup that InfoPath can work with)

Situation: :

A project must be implemented with a lot of InfoPath forms (around 50), only problem is… InfoPath isn’t designed by default to be “deployable”. But a positive side is that there is no code behind in the InfoPath form, so only the form designer is used.

Also we have around 70 content types and around 400 fields, so a lot of stuff that needs to be done and implemented.

I’ll skip forward to the InfoPath designs and deployment.

If you are asking yourself the question, can an InfoPath form be deployed without going via the InfoPath form services, or a forms library… than the answer is yes…. but…

As I’ve previously said, InfoPath is not “deployable as a solution” by design. The xsn file is actually a cabinet file that contains multiple files.

explanation about the .xsn file from FileExt

The XSN file type is primarily associated with ‘InfoPath’ by Microsoft Corporation. InfoPath is the Microsoft Office information gathering and management program. The .XSN file is a kind of cabinet (CAB) file that contains additional parts and files. 

Also you cannot deploy InfoPath via the other 2 ways (InfoPath form services or via a forms library) because there are the content types to consider. And they are all connected via a certain hierarchy. If I would deploy the forms via any of the other ways that I loose that connection in the hierarchy and the content type would exist on it’s own.

OK: so we’ve set the scene, we know all possible outcomes and which way to follow… , this one is going to be bumpy.

Step 1: Create all the fields and content types first – content analysis

Step 2: let’s say that each content type has a list (to keep things simple)

you can add multiple content types to the list and via list settings –> Form settings you can select the content type and customize (or create) the InfoPath form

ListFormSettings

and in the form settings page you can select the content type for which you want to customize the new/edit/display form.

CustomizeIP

If you use “Customize form” via the ribbon, than you’ll only customize (or create) the default content type.

CustomizeInfoPathViaList

Step 3: create a couple of InfoPath forms per content type

Ok, now the setup is complete and we have all the components that we need, all we need to do now is to be able to reproduce all this stuff via code to another farm…

Today I noticed a good tool that you can use to create your own module elements files including extraction of the aspx file and automatic creation of the feature file as well.

This tool is created by Stefan stanev and can be found here.

But as I was using this I noticed that Views and Connections of connected webparts are not being extracted. So I’ve mailed Stefan and asked him if I could re-use some of his code and added some extra code so that the webpart connections are included.

The reason why I’m releasing this in a codeplex project as a webpart is because I believe that this could come in very handy for us SP developers. No longer creating the module elements file via code. Just click together what you want on a page and extract the module.

The codeplex project can be found here. Some styling still needs to be done.

First I’ve created a sandboxed solution, but this wasn’t possible because I use the SPLimitedWebPartManager . And as you can see, this is not usable in a sandboxed solution.

Ok, let’s start by explaining the module element.

In the elements file you can define multiple <Module> elements, all the possible attributes are listed below:

  1. includeFolders: (optional,string) – actually couldn’t find a single document/blog/page that describes what this attribute is for…

Karine (Bosch) found the answer:

Apparently when you have some files in your module element that need to be put in a subfolder of the library you use this attribute..

So you define includeFolders as ??-??

<Module Name=”PublishingLayoutsPreviewImages” Url=”_catalogs/masterpage” IncludeFolders=”??-??” Path=”” RootWebOnly=”TRUE”>
<File Url=”BlackVertical.png” Name=”Preview Images/BlackVertical.png” Type=”GhostableInLibrary”>
</File>
</Module>

But this didn’t actually work for me.. so use at own risk Glimlach . Don’t really think you’ll ever need this.

Also somebody noted that it add the files to all child folders.. but this I don’t believe to be the behavior.

I’ll try to find it out in code how this part behaves, will get back to this one.

  1. HyperlinkBaseUrl: (optional,string) – This specifies the absolute url to be the base url of the hyperlinks… while I have set this and deployed to other sites (different from the base url) everything still worked, so really didn’t find any real value in this attribute
  2. List: (optional, integer) – Type of list where the files included in this module should be provisioned.

Let’s go to the onet.xml file where we can find an example on this one. As you can see the master page gallery has an typeId of 116. In the module node there is a defaultmasterpage example that has list defined to 116. So the defaultmasterpage is being deployed to this library.

image_thumb2

  1. Name: (required, string) – contains the name of the file set. Nothing really special here.. just provide a name

moduleNameError

  1. Path: (optional,string) – specifies the physical path of where the files are in the features folder. By default SharePoint expects the files to be in the same folder as the feature file. But you can also define the path attribute per file node
  2. RootWebOnly: (optional, boolean) – set to false by default, if you are installing the module only in the top level web site of the site collection than you must set this to true
  3. SetupPath: (optional,string) – specifies the physical path to a folder in the 14 hivetemplate that contains a file to include in the module.

Let’s say that you want viewpage.aspx in the pages directory under the template directory than your attribute should look like

SetupPath=”pagesviewpage.aspx”

  1. Url: (optional,string) – Specifies the virtual path of the folder in which to place the files of the module. This attribute is also used to provision a folder inside a list. If the Path is not specified, the value of this attribute will be used for the physical path also.

As you can read here , we are creating a full trusted proxy with also some CAS principles.

The Full trusted proxy should be finished and now it’s time to write a Sandbox Solution that will be using this logger.

1. Make sure the Full trusted proxy is deployed at farm level and that the feature is activated.

2 Because we are calling from a partially trusted application we need to tell the DLL that this can be expected and is ok.

Go to AssemblyInfo.CS

image

And add a line at the bottom:

image

Ok now re-deploy the Trusted Proxy.

3. Create a new project under the current Visual Studio solution (Sandboxed)

3. a. Before we can use the full trusted proxy, we first need to make a reference to it’s DLL file. But first we need to add something to the Full trusted proxy.

4. Create a new code file “Logger.cs” and enter the code below, as you can see the ULSProxyArgs are being instantiated and than passed via the ExecuteRegisteredProxyOperation.

image

5. Now add a feature receiver and for this example we will create for each content type a new list + logging everything that we do.

image

image

6. Checks are being done and all the exceptions are being caught and logged. But we can also created our own exceptions and pass information to the SP logs.

7. Finally we should see something like the picture below appearing in the logs.

image

 

Now if you get into some trouble and get errors like: An operation is not legal in the current state.

Than double check the Feature receiver of the trusted proxy and what assembly and type name it passes. This is most the time the problem/solution.

Logger Code: icon_home_skydrive

The last few days I had a couple of problems with a Sandbox solution..

I created a trusted proxy to be able to log everything that happened in the sandbox solution to the SharePoint logs. Now it isn’t possible to write directly to the SharePoint logs from within the sandbox solution. Because the SharePoint logging framework relies on APIs that are not available within the sandbox.

This kind of sucks because writing code without any form of logging.. well it’s just not done..

Also, us SharePoint developers had almost all of the time the luxury to write full trusted code… Just put the assembly in the GAC and all is ok… Well with sandbox there is no GAC to speak off and this provides a somewhat different way of coding..

First of all: CAS

Here is a good list of all the execution models. Especially the sentence: “The solution runs using an isolated, low-privilege process” is the most important one.. keyword “low-privilege” ..

Also Tyler holmes blogged about it here with even the mention that we in fact expose our applications to all kinds of unnecessary security risks.

Found a “whitepaper” about Code Access Security in SharePoint 2007 for Administrators and an MSDN link for CAS in WSS 3.0 and MOSS 2007 .

Here is also the msdn link for SecurityAction enumeration .

And last but not least, the start for the entire explanation about Code Access Security .

Alright.. Now that the foundation is there let’s get started…

1. Open Visual studio and select empty SP project (name: TrustedProxyLogger) –> Farm solution

2. Add a code file (.cs) and give it “ProxyLogger” as name

3. next add 3 usings (Microsoft.SharePoint, Microsoft.SharePoint.UserCode and Microsoft.SharePoint.Administration)

4. Now you can add “: SPProxyOperation” behind the class name

image

5.What you have to do now is to override the execute method and fill in everything needed to be able to log all the information to the SharePoint Logs

image

6. Explanation of the above code part

a. check if the args are not null (if they are your code may crash and nothing appears in the SP logs

b. depends on the actions that you want to do “RunWithElevatedPrivileges” is needed. But you can leave it out here Glimlach, just wanted to show that you can do “normal” SharePoint coding here but keep in mind that you are in a full trusted assembly and at FARM level. (more on that later)

c. rest is normal stuff to be able to write trace to the SP logs.

Next up is the ULSProxyArgs class that we have to create (you’ll most likely got the red lines below the ULSProxyArgs ulsargs = args as ULSProxyArgs line..

image

7. as you can see there are 4 properties (Source, Message, Category Name and LogExpression)

a. as you can see the class must inherit SPProxyOperationArgs

b. there are constructors in place to fill the arguments so in fact you can make the properties private if you want, because they don’t need to be accessible to outside the class

c. the constructor without arguments is private because I don’t want the developer to instantiate an argument class without the basics (Category Name and a source)

image

8. in the private constructor I do some checks to see if everything is filled in or not null

image

9. we must also set the proxy args class as serializable and for our first CAS instruction we add the SharePointPermission

a. as we can see in the MSDN explanation of the Security Action enumeration

linkdemand: The immediate caller is required to have been granted the specified permission.

Since the framework of the SharePoint solutions is set to Framework 3.5 there is no need for the second part of the explanation: Do not use in Framework 4.

If SP 15 comes than this will most likely be in Framework 4 and you’ll have to change this.

b. Objectmodel = true : the explanation of MSDN is… Set this property to make a security request or demand for accessing the SP Object model…

Both of the attributes make up for the security call…

Now let’s go back to our ProxyLogger class and apply the CAS that we need..

image

10. If you set the CAS of the execute method as in the image above.. you compiler will not complain…But your code analysis will say the following:

Warning    1    CA2126 : Microsoft.Security : ‘ProxyLogger’ has one or more overridable methods with link demands that are not matched by an inheritance demand. Apply the following inheritance demands to the type: [SharePointPermission(SecurityAction.InheritanceDemand, ObjectModel = true)] 

So if we read this correctly than some CAS is already set? OK, reflector time on the SharePoint assembly (microsoft.SharePoint.dll –> Microsoft.SharePoint.UserCode namespace –> SPOperation class)

image

As we can see above the class name.. some CAS is already set in the SharePoint assemblies..

Because we’ve only used the linkdemand action the code analysis complains that there is no additional security set. And that extra security is InheritanceDemand

MSDN explanation: Add this security metadata to tell the runtime that a class must have the permission represented by the security metadata attribute to inherit from your class. So in other words.. When I call the class and I have already some security set, it will inherit that security.

So we change our code to this and all is good in code analysis wonderland…

image

As you can see, I didn’t set any CAS on the execute method.. This is because I’ve set all the security needed at Class level.. all the methods in the class will inherit this CAS setting so no need to add CAS to method level..

11. and last but not least we need to create a feature receiver so that when the feature is activated our trusted proxy will be registered for farm wide use.

12. Add a feature and set the name and description to whatever you want. But the scope must be farm level

image

13. as you can see in the code above I’m getting the assembly and full name via one of many ways. Once the new SPProxyOperationType is created than I must add it to the collection of operations and update the Usercodeservice. 

14. if the feature is being deactivated than the Proxy must be removed from the collection, it’s almost exactly the same code but with a .Remove method instead of an Add method.

15. Also the CAS line must be placed above the class name: “[SharePointPermission(SecurityAction.InheritanceDemand, ObjectModel = true), SharePointPermission(SecurityAction.LinkDemand, ObjectModel = true)]”

It’s again needed for the Code access security to work correctly.

Because the length of the blog post I’ve decided to split this post in half. With this blog post you can create full trusted proxies with CAS.

In the second part of the blog post I will take the sandbox side under the loop (think it’s written this way  Glimlach ) and how to call the trusted proxy.

On a personal note: Almost nobody uses it, but in the properties of your visual studio solution, select code analysis tab.. Enable it with “Microsoft minimum recommended rules” and build you code again.

Don’t hate it (trust me, you will , especially when you are going to add stylecop as well) but learn from it. As you can see the code analysis advices you to do something but there are more ways to better coding than the advice of code analysis.

Hope it helps someone Glimlach

hey everyone

Today I’ve found something nice when I was creating a new site collection..

No it wasn’t the central admin that I’ve found.. but in fact when I was choosing my template for the root web

image

I saw that in the “custom” tab , I could choose my template later… now this came in very handy because I had made a backup from an Office 365 site and I needed to create it as root web..

So I of course selected this and clicked on OK.

Now I had the wsp of the site template that I took from the office 365 site, all I had to do was to figure out a way to add this to my site collection (site templates list) and create my root web from this wsp.

Funnily enough SharePoint again provided me with the solution.

image

So now I’ve selected the “Solution gallery” –> uploaded the wsp and I could select the site template that I wanted.

 

Cool feature that I didn’t even know it existed. Glimlach

For my first part I’ve chosen the sandboxed solution. This is the easiest to explain and resource path’s don’t apply here.

We will see later what we can do with MUI sandboxed.

Useful links

Lcid codes

Culture specific list

Ok let’s get starting:

  • Open visual studio Glimlach
  • Select empty SharePoint solution, fill in the url and select sandboxed
  • Create a folder and give the “Resources” as name

 

image

 

  • Now fill the resources directory as you can see above, first an invariant resource and after than culture specific resources (of course if you use different languages than shown be sure to use the correct culture specific code – between resource name and .resx)

image

  • if you build your solution already than you can see in the hidden bin folder that you have 3 language resource satellite assemblies
  • Next is to add these assemblies to your solution package
      • to do this you’ll have to select your solution package file and click on “Advanced” at the bottom of the window
      • Next click on “Add” and select the dll file of the language (for this example we’ll have to do this 3 times (en, fr and nl) but never select the debug directory outside of the development machine, if your solution goes to UAT or production than you’ll have to build the solution in “Release” mode and select those dll’s to add to the package. Never use debug build dll’s to add to your SharePoint solution.
      • as you can see in the print screen below, I’ve selected the dll from the en-US path in the release directory
      • in the “Location” text field you must add a prefix “en-US” to specify for which language the dll stands for.

 

image

 

image

 

  • In the example above you can see that the 3 resource files are added as assemblies.

List Definitions, List Instances, Feature titles and descriptions cannot be set in MUI because of the location of the resource files. Resource files via Sandbox are not stored in the 14 hive directories and thus cannot be used for Multi lingual names

However, if you separate the resource files and deploy them via a separate SharePoint farm solution (wsp) than you can use these files.

I’ve created a separate solution that will be deployed farm wide and contains the resource files in a mapped folder to the 14hiveresources but I gave the resource files the name “MuiSeries1”.

  • Ok, next up is to create the sandboxed webpart that we are going to use
      • purpose of the webpart is to have a sign up form where people give their score about a restaurant that they’ve visited.
      • and we will not be filling in the text fields of the labels because these has to be multilingual of course
      • We have 3 labels (name of the restaurant, score that people will give it and if the food was above/below or just average) , we cannot use encoded literals because they cannot be used in sandbox solutions Encodedliteral – MSDN
      • Now here you can decide to create a separate solution where only the 14 hive resources are being added or you can use the resource files as we’ve created them earlier. In the example that you can download I’ve added both solutions
      • There is one hitch in Sandbox solutions and that is, you cannot use text=”<%Resources:Name of resource file, name of key;” . Your code will not compile and you’ll receive the following error: “The name ‘InitializeControl’ does not exist in the current context” . So instead of putting this in the ascx file, we are going to fill in the labels via code.

image

 

      • So we leave the labels without the “Text” attribute and go into the code behind
        • First we set the label score to be filled in via the sandboxed resources (keep in mind that it’s best case to first add the key “Score Label” to the sandbox resource files, after that auto completion will do the rest)

image

        • Secondly we are going to use SPUtility.GetLocalizedString since this is also possible to use this in a sandbox solution. I’ve created a resourceHelper for this, it’s nothing more than 2 static methods
          • in the first method the language LCID is being retrieved and via an override mechanism the second method is called

image

      • After adding the resourcehelper.cs you can now get the MUI labels as well via the helper

image

 

After this, just deploy the solutions and you’re done. I’ve also added some extra functionality in the webpart, like some multilingual dropdown values Glimlach . Download Code –> click file and download original

Next blog will be about feature resource files… (which you can use in Sandbox as well Glimlach )

hey everyone

Yesterday I gave a presentation about MUI in SharePoint 2010. I had a good time and the audience was great.. Lots of presents were given, if the answer was correct ofcourse…

The slidedeck will also be uploaded to the new BiWUG site early next year, but in the meanwhile you can download them from here as well. Mui-Deepdive.pptx

Feel free to use slides for your own presentations.. Also if you have questions, leave a comment and I’ll reply asap..

I’m also going to write out all the demo’s in a MUI blog series.., Adam Burcher has already done the same SharePoint Baker . But I’ll be giving my meligo twist on it 🙂 .

If you were at the session, thanks for coming and I hope you have learned something..

Have a nice day