(this post was contributed by Brent McBride, Senior Software Engineer on the MDS team).

The below example shows how to create a new model and add new entities in the same call to the MetadataCreate API operation:

 

            Example 1: Add a model and its entities in the same operation.

 

            // Add a new model.

            string modelName = "My New Model Name";

            Metadata metaData = new Metadata();

            metaData.Models = new List<Model> {

                                new Model() {

                                    Identifier = new Identifier() { Name = modelName } } };

 

            // Add new entities to the new model.

            foreach (string entityName in entityNames)

            {

                Entity entity = new Entity();

                entity.Identifier = new ModelContextIdentifier();

                entity.Identifier.Name = entityName;

                 

                metaData.Models[0].Entities.Add(entity);

            }

 

            OperationResult operationResult = new OperationResult();

            client.MetadataCreate(international, metaData, true, out operationResult);

The Metadata DataContract contains several properties that are lists of metadata objects, such as Models, Entities, Versions, Attributes, etc. However, in any single call to a metadata CRUD operation (including MetadataCreate), only one of these properties may be non-empty. Otherwise, the operation returns error 200000 “The operation permits only one metadata property list.” Thus, Example 2 is invalid:

           

            Example 2: Incorrectly add model and entities.

 

            // Add a new model.

            string modelName = "My New Model Name";

            Metadata metaData = new Metadata();

            metaData.Models = new List<Model> {

                                new Model() {

                                    Identifier = new Identifier() { Name = modelName } } };

 

            // Add new entities to the new model.

            metaData.Entities = new List<Entity>();

            foreach (string entityName in entityNames)

            {

                Entity entity = new Entity();

                entity.Identifier = new ModelContextIdentifier();

                entity.Identifier.Name = entityName;

 

                metaData.Entities.Add(entity); // Error! Both Models and Entities cannot be populated.

            }

 

            OperationResult operationResult = new OperationResult();

            client.MetadataCreate(international, metaData, true, out operationResult); 

            // Result: Error 200000

The new entities must be added directly underneath the new model to which they belong, as per Example 1. However, the Metadata.Entities property comes in handy when adding entities to an already existing model, as Example 3 shows:

           

            Example 3: Add entities to a preexisting model.

 

            // Reference an existing model.

            string modelName = "My Existing Model Name";

            Metadata metaData = new Metadata();

 

            // Add new entities to the existing model.

            metaData.Entities = new List<Entity>();

            foreach (string entityName in entityNames)

            {

                Entity entity = new Entity();

                entity.Identifier = new ModelContextIdentifier();

                entity.Identifier.Name = entityName;

                entity.Identifier.ModelId = new Identifier { Name = modelName };

 

                metaData.Entities.Add(entity); // No error this time because the Models property is empty.

            }

 

            OperationResult operationResult = new OperationResult();

            client.MetadataCreate(international, metaData, true, out operationResult); 

As shown in the highlighted line of Example 3, each entity must reference the model to which it pertains. Without this context, the operation returns error 120003 “The user does not have permission or the object ID not valid”. This error message is intentionally ambiguous for the sake of security. Using the same error code for both insufficient permissions and invalid IDs makes it harder for an attacker to glean information about the attack surface. Although Example 3 only deals with creating entities, the same principle could also apply to other API operations and metadata objects such as attributes. Error 120003 could occur if there is not enough contextual information provided for the operation to uniquely identify a referenced metadata object.

 

© 2010 Microsoft Corporation.  All rights reserved.  This information is provided “as-is”. Information and views expressed, including URL and other Internet Web site references, may change without notice. You bear the risk of using this information. Examples are provided for illustration only.  Provision of this information does not provide you with any legal rights to any intellectual property in any Microsoft product. You may copy and use this information for your internal, reference purposes only.