示例#1
0
        private void SetEntityDefinitions(WebApiMetadata webApiMetadata)
        {
            if (Target == null)
            {
                throw new WebApiException("Missing 'Target' value.");
            }

            if (Subordinate == null)
            {
                throw new WebApiException("Missing 'Subordinate' value.");
            }

            EntityDefinition targetEntityDefinitions      = webApiMetadata.GetEntityDefinition(Target.LogicalName);
            EntityDefinition subordinateEntityDefinitions = webApiMetadata.GetEntityDefinition(Target.LogicalName);

            if (targetEntityDefinitions.LogicalName != subordinateEntityDefinitions.LogicalName)
            {
                throw new WebApiException("Target and Subordinate must be the same entity type.");
            }

            if (mergeEntities.Contains(targetEntityDefinitions.LogicalName) == false)
            {
                throw new WebApiException(
                          $"Entity with name '{targetEntityDefinitions.LogicalName}' is not supported for merge.");
            }

            entityDefinition = targetEntityDefinitions;
        }
示例#2
0
        public static ModuleMember BackendApiService(WebApiMetadata api)
        => MODULE(new[] { "src", "services" }, ID(api.ServiceName, "Service"), () => {
            IMPORT.DEFAULT("axios", out var @axios).FROM("axios");

            EXPORT.CLASS(ID(api.ServiceName, "Service"), () => {
                api.ApiMethods.ForEach(apiMethod => {
                    var methodUrl = api.GetMethodUrl(apiMethod);

                    //TODO: separate language-specific parts of fluent code DSL
                    //For instance, 'PUBLIC' and 'PRIVATE' are not defined in JavaScript, and 'IMPORT' is not defined in C#

                    PUBLIC.STATIC.FUNCTION(apiMethod.Name, () => {
                        var arguments = apiMethod.Signature.Parameters.Select((parameter, index) => {
                            PARAMETER(parameter.Name, out var @param);
                            return(@param);
                        }).ToList();

                        FINAL("data", out var @data, INITOBJECT(() => {
                            arguments.ForEach(arg => KEY(arg.Name, arg));
                        }));

                        DO.RETURN(@axios
                                  .DOT("post").INVOKE(ANY(methodUrl), @data)
                                  .DOT("then").INVOKE(LAMBDA(@result =>
                                                             DO.RETURN(@result.DOT("data"))
                                                             ))
                                  .DOT("catch").INVOKE(LAMBDA(@err => {
                            USE("console").DOT("log").INVOKE(@err);
                        }))
                                  );
                    });
示例#3
0
        //TODO: add detection & resolution of duplicate names
        public static TypeMember WebApiController(TypeMember middlewareType, WebApiMetadata api) =>
        PUBLIC.CLASS(ID(api.InterfaceType.Name.TrimPrefixFragment("I"), "Controller"), () => {
            EXTENDS <Controller>();
            ATTRIBUTE <RouteAttribute>("api/[controller]");

            PRIVATE.READONLY.FIELD(api.InterfaceType, "_service", out var @serviceField);

            PUBLIC.CONSTRUCTOR(() => {
                PARAMETER(api.InterfaceType, "service", out var @service);
                @serviceField.ASSIGN(@service);
            });

            api.ApiMethods.ForEach(apiMethod => {
                var requestClass = DataTransferObjectGenerator.MethodInvocation(apiMethod);

                PUBLIC.ASYNC.FUNCTION <Task <IActionResult> >(apiMethod.Name, () => {
                    ATTRIBUTE(middlewareType);
                    ATTRIBUTE <HttpPostAttribute>(apiMethod.Name.ToString(CasingStyle.Camel));
                    PARAMETER(requestClass, "requestData", out MethodParameter @requestData, () => {
                        ATTRIBUTE <FromBodyAttribute>();
                    });

                    LOCAL(apiMethod.ReturnType.GenericArguments[0], "resultValue", out LocalVariable resultValueLocal);

                    resultValueLocal.ASSIGN(
                        AWAIT(THIS.DOT(@serviceField).DOT(apiMethod).INVOKE(() => {
                        apiMethod.Signature.Parameters.ForEach(p => ARGUMENT(@requestData.DOT(p.Name.ToString(CasingStyle.Pascal))));
                    }))
                        );

                    DO.RETURN(THIS.DOT("Json").INVOKE(resultValueLocal));
                });
            });
示例#4
0
        public void GetQueryString_When_Select_PrimaryId_And_HasSameEntityLookup_Then_Query_IsValid_Test()
        {
            WebApiMetadata metadata = MockedWebApiMetadata.CreateD365Ce();

            var options = QueryOptions.Select("incidentid");

            var query = options.BuildQueryString(metadata, "incident");

            query.Should().Be("?$select=incidentid");
        }
示例#5
0
        public void GetQueryString_When_Select_Lookup_Then_Query_IsValid_Test()
        {
            WebApiMetadata metadata = MockedWebApiMetadata.CreateD365Ce();

            var options = QueryOptions.Select("createdby", "primarycontactid");

            var query = options.BuildQueryString(metadata, "account");

            query.Should().Be("?$select=_createdby_value,_primarycontactid_value");
        }
示例#6
0
        public void GetQueryString_When_Create_Then_Select_Eq_PrimaryId_Test()
        {
            WebApiMetadata metadata = MockedWebApiMetadata.CreateD365Ce();

            var options = new QueryOptions();

            var query = options.BuildQueryString(metadata, "account");

            query.Should().Be("?$select=accountid");
        }
示例#7
0
        public static TypeMember Controller(WebApiMetadata api) => 
            PUBLIC.CLASS($"{api.Interface.Name.TrimPrefix("I")}Controller", () => {
                EXTENDS<Controller>();
                ATTRIBUTE<RouteAttribute>("api/[controller]");

                PUBLIC.FUNCTION<string>("Index", () => {
                    ATTRIBUTE<HttpGetAttribute>();
                    DO.RETURN("Hello World!");
                });
            });
示例#8
0
        public JObject GetRequestObject(WebApiMetadata webApiMetadata)
        {
            SetEntityDefinitions(webApiMetadata);
            var requestObject = new JObject();

            requestObject.Add(GetTargetProperty());
            requestObject.Add(GetSubordinateProperty());
            requestObject.Add("PerformParentingChecks", ParentingChecks);
            requestObject.Add(GetUpdateContent(webApiMetadata));
            return(requestObject);
        }
        public static JObject EntityToJObject(Entity entity, WebApiMetadata webApiMetadata)
        {
            var jObject = new JObject();

            foreach (KeyValuePair <string, object> attibute in entity.Attributes)
            {
                JProperty jToken = GetJTokenFromAttribute(attibute.Key, attibute.Value, webApiMetadata);
                jObject.Add(jToken);
            }

            return(jObject);
        }
示例#10
0
        public void GetQueryString_When_SetAllColumns_Then_Query_Is_Empty_Test()
        {
            WebApiMetadata metadata = MockedWebApiMetadata.CreateD365Ce();

            var options = new QueryOptions()
                          .Select(new ColumnSet()
            {
                AllColumns = true
            });

            var query = options.BuildQueryString(metadata, "account");

            query.Should().Be("");
        }
示例#11
0
        public void GetQueryString_When_SetOrder_Then_Query_IsValid_Test()
        {
            WebApiMetadata metadata = MockedWebApiMetadata.CreateD365Ce();

            var options = new QueryOptions()
                          .Select(new ColumnSet()
            {
                AllColumns = true
            })
                          .OrderBy("createdby")
                          .OrderByDesc("name");

            var query = options.BuildQueryString(metadata, "account");

            query.Should().Be("?$orderby=_createdby_value,name%20desc");
        }
        public static string GetEntityApiUrl(Entity entity, WebApiMetadata webApiMetadata)
        {
            string entitySetName = webApiMetadata.GetEntitySetName(entity.LogicalName);

            if (entity.KeyAttributes?.Any() == true)
            {
                IEnumerable <string> keys = entity.KeyAttributes.Select(s => $"{s.Key}='{s.Value.ToString().Replace("'", "''")}'");
                return($"{entitySetName}({string.Join("&",keys)})");
            }

            if (entity.Id != Guid.Empty)
            {
                return(entitySetName + entity.Id.ToString("P"));
            }

            return(entitySetName);
        }
        public static JObject ActivityPartyToJObject(ActivityParty activityParty, WebApiMetadata webApiMetadata)
        {
            var jObject = new JObject();

            jObject["participationtypemask"] = (int)activityParty.ParticipationTypeMask;

            if (activityParty.TargetEntity != null)
            {
                jObject[$"partyid_{activityParty.TargetEntity.LogicalName}@odata.bind"] = EntityReferenceTostring(activityParty.TargetEntity, webApiMetadata);
            }

            foreach (KeyValuePair <string, object> attribute in activityParty.Attributes)
            {
                jObject.Add(attribute.Key, JValue.FromObject(attribute.Value));
            }

            return(jObject);
        }
示例#14
0
        public void GetQueryString_When_SetPage_Then_Query_IsValid_Test()
        {
            WebApiMetadata metadata = MockedWebApiMetadata.CreateD365Ce();

            var options = new QueryOptions()
                          .Select(new ColumnSet()
            {
                AllColumns = true
            })
                          .Page(4)
                          .Top(10);

            var query = options.BuildQueryString(metadata, "account");

            WebUtility.UrlDecode(query).Should()
            .Be("?$top=10&$skiptoken=<cookie pagenumber=\"4\" />");


            //query.Should().Be("?$skiptoken=");
        }
示例#15
0
        public void GetQueryString_When_Expand_Lookup_Then_Query_IsValid_Test()
        {
            WebApiMetadata metadata = MockedWebApiMetadata.CreateD365Ce();

            var options = new QueryOptions()
                          .Select(new ColumnSet()
            {
                AllColumns = true
            })
                          .Expand("createdby", "domainname", "businessunitid")
                          .Expand("primarycontactid");

            var query = options.BuildQueryString(metadata, "account");


            WebUtility.UrlDecode(query).Should()
            .Be("?$expand=createdby($select=domainname,businessunitid),primarycontactid($select=contactid)");

            query.Should()
            .Be("?$expand=createdby($select%3Ddomainname,businessunitid),primarycontactid($select%3Dcontactid)");
        }
示例#16
0
        public JProperty GetUpdateContent(WebApiMetadata webApiMetadata)
        {
            var jObject = new JObject();

            jObject["@odata.type"] = $"Microsoft.Dynamics.CRM.{entityDefinition.LogicalName}";
            jObject[entityDefinition.PrimaryIdAttribute] = Target.Id.ToString("D");

            if (UpdateContent == null)
            {
                return(new JProperty("UpdateContent", jObject));
            }

            foreach (KeyValuePair <string, object> attribute in UpdateContent)
            {
                if (jObject.ContainsKey(attribute.Key))
                {
                    continue;
                }

                jObject.Add(RequestEntityParser.GetJTokenFromAttribute(attribute.Key, attribute.Value, webApiMetadata));
            }

            return(new JProperty("UpdateContent", jObject));
        }
        public static JProperty GetJTokenFromAttribute(string key, object value, WebApiMetadata webApiMetadata)
        {
            switch (value)
            {
            case null:
                return(new JProperty(key, null));

            case EntityReference reference:
                return(new JProperty(key + "@odata.bind", EntityReferenceTostring(reference, webApiMetadata)));

            case IEnumerable <ActivityParty> activityParties:
            {
                var jArray = new JArray();

                foreach (ActivityParty activityParty in activityParties)
                {
                    jArray.Add(ActivityPartyToJObject(activityParty, webApiMetadata));
                }

                return(new JProperty(key, jArray));
            }

            case List <Entity> list:
            {
                var objects = new JArray();
                foreach (Entity nestedEntity in list)
                {
                    objects.Add(EntityToJObject(nestedEntity, webApiMetadata));
                }
                return(new JProperty(key, objects));
            }

            default:
                return(new JProperty(key, JValue.FromObject(value)));
            }
        }
        public static string EntityReferenceTostring(EntityReference entityReference, WebApiMetadata webApiMetadata)
        {
            string logicalName   = entityReference.LogicalName.ToLower();
            string entitySetName = webApiMetadata.GetEntitySetName(logicalName);

            if (entityReference.KeyAttributes?.Any() == true)
            {
                IEnumerable <string> keys = entityReference.KeyAttributes.Select(s => $"{s.Key}='{s.Value.ToString().Replace("'", "''")}'");
                return($"{entitySetName}({string.Join("&",keys)})");
            }

            return($"/{entitySetName}{entityReference.Id:P}");
        }
 public EntityReferenceJsonConverter(WebApiMetadata webApiMetadata)
 {
     this.webApiMetadata = webApiMetadata;
 }
示例#20
0
        private void GenerateBackendApiService(WebApiMetadata api)
        {
            var module = BackendApiServiceGenerator.BackendApiService(api);

            _codeWriter.WriteModule(module);
        }