Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide custom FieldType support in Field Definitions #1082

Open
jarzimichal opened this issue Sep 28, 2017 · 3 comments
Open

Provide custom FieldType support in Field Definitions #1082

jarzimichal opened this issue Sep 28, 2017 · 3 comments

Comments

@jarzimichal
Copy link

Brief description

I would like to use the custom class for FieldType in FieldDefinition.
Currently SPMeta2 works well only when I use one of the BuiltInFieldTypes, however when I populate the FieldDefinition.FieldType with my custom type (class which I have created), the field is not using my type bu just 'Choice' type...

SharePoint API

SharePoint 2016 On Premise

SPMeta2 API

SPMeta2FileVersion:[1.2.17191.0958]

SPMeta2 model

Here is my model for FieldDefinition

public static FieldDefinition Test=> new MultiChoiceFieldDefinition
        {
			InternalName = "Test",
			Id = new Guid("BC0A44B4-9380-4072-9BEF-FF81083D2FC4"),
			Title = "Test",
			Group = "Test",
			FieldType = "MyType",
			ShowInNewForm = true,
			ShowInDisplayForm = true,
			ShowInEditForm = true,
		    EnforceUniqueValues = false,
		    FillInChoice = true,
		    Choices = new Collection<string>
		    {
		        ""
		    }
        };

here is my custom type code:

public class MyType : SPFieldMultiChoice
    {
        public MyType(SPFieldCollection fields, string fieldName) : base(fields, fieldName)
        {

        }

        public MyType(SPFieldCollection fields, string fieldName, string displayName) : base(fields, fieldName, displayName)
        {

        }
    }

The same field works well when I create it from XML. Here is the snippet.

<Field Name="Test" ID="{D6CCDC3A-4E82-4358-A9B5-04FFCD1C11B3}" DisplayName="Test" Group="Test" Type="MyType" ShowInNewForm="TRUE" ShowInDisplayForm="TRUE" ShowInEditForm ="TRUE" EnforceUniqueValues="FALSE" FillInChoice="TRUE">
    <Default></Default>
    <CHOICES>
      <CHOICE></CHOICE>
    </CHOICES>
  </Field>
@jarzimichal jarzimichal changed the title Provide custom FieldType support in Field Deffinitions Provide custom FieldType support in Field Definitions Sep 28, 2017
@ghost
Copy link

ghost commented Sep 28, 2017

It seems to be hard-coded....

get { return BuiltInFieldTypes.MultiChoice; }

@SubPointSupport
Copy link
Contributor

SubPointSupport commented Sep 28, 2017

Here is what can be done to work around it. This is fast-get-it-done workaround without any elegance.

Right now SPMeta2 does not support custom fields unless plain FieldDefinition is used (which limits ability to specify properties such as choices and so on). You still can FieldDefinition with your custom type but it won't be much help in your case.

So.. for you to get all benefits of existing choice field (or any other field), a few tricks need to be done. These are legit steps, totally within SPMeta2 supportability. We'd need to inherit our own definition and then match it with either existing or inherited model handler.

Some code below, hop that explained well.

// create a new class for your definition
// the goal is to override FieldType returning your own thing

public class MyTypeFieldDefinition : MultiChoiceFieldDefinition {

[ExpectValidation]
        [ExpectRequired]
        [DataMember]
        public override string FieldType
        {
            get { return "MyType"; }
            set
            {

            }
        }
}
// register a model handler to handle your definition
// SPMeta2 has one-to-one mapping between definition and model handler
// we pretty much pointing existing model handler for choice field to MyTypeFieldDefinition
// that works same way for CSOM/SSOM model handlers and provision services
csomProvisionService.ModelHandlers.Add(typeof(MyTypeFieldDefinition), new MultiChoiceFieldModelHandler());

MultiChoiceFieldModelHandler exist in both CSOM/SSOM implementations. Check the following namespaces as you need:

  • SPMeta2.CSOM.ModelHandlers.Fields
  • SPMeta2.SSOM.ModelHandlers.Fields

Same idea with "Standard" definitions.

Internally, these handler would come to a base class FieldModelHandler which crafts basic properties for fields including field type. Field type gets extracted from the definition itself.

Hence we did two tricks - crafted our own definition and married it up with existing model handler.
If SPMeta2 would complain on not found model handler or mismatch, then get a new model handler inherited:

// get CSOM/SSOM model handler for out the box field provision, just override TargetType 
public class MyFieldModelHandler : MultiChoiceFieldModelHandler
    {
        public override Type TargetType
        {
            get { return typeof(MyTypeFieldDefinition); }
        }
}

// Register this instance same way:
csomProvisionService.ModelHandlers.Add(typeof(MyTypeFieldDefinition), new MyFieldModelHandler());

Few ideas on this trick are here:
http://docs.subpointsolutions.com/spmeta2/extensibility/custom-definition.html

Also, let us know if you guys use model serialisation/deserialisation. In this case, additional attributes and registrations are required to get custom definition serialized.

Finally, we'll think on how we can improve custom fields provision and surely let us know your thoughts on that.

@jarzimichal
Copy link
Author

Awesome thanks for very quick reaction!

@avishnyakov avishnyakov added this to the Feb, 2018 - Tech dept #3, 1.2.150 milestone Jan 31, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants