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; }
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); })) ); });
//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)); }); });
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"); }
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"); }
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"); }
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!"); }); });
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); }
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(""); }
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); }
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="); }
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)"); }
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; }
private void GenerateBackendApiService(WebApiMetadata api) { var module = BackendApiServiceGenerator.BackendApiService(api); _codeWriter.WriteModule(module); }