internal async Task <List <ActionInfo> > GenerateFromODataEndPoint(string endpoint) { var uri = new Uri(endpoint); var site = uri.Scheme + "://" + uri.Authority; var httpClient = new HttpClient { BaseAddress = new Uri(site) }; var str = await httpClient.GetStringAsync(uri.PathAndQuery); var js = JsonDocument.Parse(str); var root = js.RootElement; var entitiesLocation = root.GetProperty("@odata.context").GetString(); var types = await AddValues(entitiesLocation); var urls = root.GetProperty("value"); var actions = new List <ActionInfo>(); foreach (var entity in urls.EnumerateArray()) { var kind = entity.GetProperty("kind").GetString(); if (kind != "EntitySet") { continue; } var action = entity.GetProperty("url").GetString(); var nameAction = entity.GetProperty("name").GetString(); var newAction = new ActionInfoOdata(); newAction.ActionName = $"Get{nameAction}"; newAction.ControllerName = action; newAction.Site = entitiesLocation.Replace("$metadata", ""); newAction.Verb = "GET"; newAction.RelativeRequestUrl = action; newAction.ReturnType = types.FindAfterId("array"); actions.Add(newAction); newAction = new ActionInfoOdata(); newAction.ActionName = $"GetOne{nameAction}"; newAction.ControllerName = action; newAction.Site = entitiesLocation.Replace("$metadata", ""); newAction.Verb = "GET"; var type = types.FirstOrDefault(it => it.Name == nameAction || it.id == nameAction); var odatType = type as TypeToGenerateOData; var paramKeys = odatType .Keys .Select(it => odatType.GetProperties().First(pr => pr.Name == it)) .Select(pr => new { orig = pr, Name = pr.Name, IsString = pr.PropertyType.TranslateToBlocklyBlocksType() == "text" }) .ToArray(); var paramKeysStr = string.Join(",", paramKeys.Select(pr => (pr.IsString ? @"\\'" : "") + "{" + pr.Name + "}" + (pr.IsString ? @"\\'" : ""))); newAction.RelativeRequestUrl = $"{action}({paramKeysStr})"; foreach (var item in paramKeys) { //item.orig.PropertyType newAction.Params.Add(item.Name, (item.orig.PropertyType, BindingSourceDefinition.Path)); } newAction.ReturnType = odatType; actions.Add(newAction); } return(actions); }
internal async Task <List <ActionInfo> > GenerateFromODataEndPoint(string endpoint) { var uri = new Uri(endpoint); var site = uri.Scheme + "://" + uri.Authority; var httpClient = new HttpClient { BaseAddress = new Uri(site) }; httpClient.DefaultRequestHeaders.Add("Accept", "application/json"); var str = await httpClient.GetStringAsync(uri.PathAndQuery); var js = JsonDocument.Parse(str); var root = js.RootElement; JsonElement value; var versionOData = 4; if (!root.TryGetProperty("@odata.context", out value)) { versionOData = 3; if (!root.TryGetProperty("odata.metadata", out value)) { throw new ArgumentNullException($"cannot find @odata.context or odata.metadata for {endpoint}") ; } } var entitiesLocation = value.GetString(); var newUri = new UriBuilder(entitiesLocation); if (newUri.Port == 0) { newUri.Port = 80; } entitiesLocation = newUri.Uri.ToString(); var types = await AddValues(entitiesLocation); var urls = root.GetProperty("value"); var actions = new List <ActionInfo>(); foreach (var entity in urls.EnumerateArray()) { if (entity.TryGetProperty("kind", out var kind))//v4 { if (kind.GetString() != "EntitySet") { continue; } } ; var action = entity.GetProperty("url").GetString(); var nameAction = entity.GetProperty("name").GetString(); var newAction = new ActionInfoOdata(); newAction.ActionName = $"GetAll{nameAction}"; newAction.ControllerName = action; newAction.Site = entitiesLocation.Replace("$metadata", ""); newAction.Verb = "GET"; newAction.RelativeRequestUrl = action; newAction.ReturnType = types.FindAfterId("array"); actions.Add(newAction); newAction = new ActionInfoOdata(); newAction.ActionName = $"Get{nameAction}"; newAction.ControllerName = action; newAction.Site = entitiesLocation.Replace("$metadata", ""); newAction.Verb = "GET"; newAction.RelativeRequestUrl = action; var typeBool = types.FindAfterId("Edm.Boolean"); var typeInt = types.FindAfterId("Edm.Int32"); var typeString = types.FindAfterId("Edm.String"); switch (versionOData) { case 4: newAction.Params.Add("$count", (typeBool, BindingSourceDefinition.Query)); break; case 3: newAction.Params.Add("$inlinecount", (typeString, BindingSourceDefinition.Query)); break; default: throw new ArgumentException($"not know odata version {versionOData}"); } newAction.Params.Add("$top", (typeInt, BindingSourceDefinition.Query)); newAction.Params.Add("$skip", (typeInt, BindingSourceDefinition.Query)); newAction.Params.Add("$select", (typeString, BindingSourceDefinition.Query)); newAction.ReturnType = types.FindAfterId("array"); actions.Add(newAction); newAction = new ActionInfoOdata(); newAction.ActionName = $"GetOne{nameAction}"; newAction.ControllerName = action; newAction.Site = entitiesLocation.Replace("$metadata", ""); newAction.Verb = "GET"; var type = types.FirstOrDefault(it => it.Name == nameAction || it.id == nameAction); var odatType = type as TypeToGenerateOData; var paramKeys = odatType .Keys .Select(it => odatType.GetProperties().First(pr => pr.Name == it)) .Select(pr => new { orig = pr, Name = pr.Name, IsString = pr.PropertyType.TranslateToBlocklyBlocksType() == "text" }) .ToArray(); var paramKeysStr = string.Join(",", paramKeys.Select(pr => (pr.IsString ? @"\\'" : "") + "{" + pr.Name + "}" + (pr.IsString ? @"\\'" : ""))); newAction.RelativeRequestUrl = $"{action}({paramKeysStr})"; foreach (var item in paramKeys) { //item.orig.PropertyType newAction.Params.Add(item.Name, (item.orig.PropertyType, BindingSourceDefinition.Path)); } newAction.ReturnType = odatType; actions.Add(newAction); newAction = new ActionInfoOdata(); newAction.ActionName = $"Create {nameAction}"; newAction.ControllerName = action; newAction.Site = entitiesLocation.Replace("$metadata", ""); newAction.Verb = "POST"; newAction.RelativeRequestUrl = $"{action}"; newAction.ReturnType = odatType; newAction.Params.Add(odatType.Name, (odatType, BindingSourceDefinition.Body)); actions.Add(newAction); newAction = new ActionInfoOdata(); newAction.ActionName = $"Modify {nameAction}"; newAction.ControllerName = action; newAction.Site = entitiesLocation.Replace("$metadata", ""); newAction.Verb = "PATCH"; newAction.RelativeRequestUrl = $"{action}({paramKeysStr})"; foreach (var item in paramKeys) { //item.orig.PropertyType newAction.Params.Add(item.Name, (item.orig.PropertyType, BindingSourceDefinition.Path)); } newAction.ReturnType = odatType; newAction.Params.Add(odatType.Name, (odatType, BindingSourceDefinition.Body)); actions.Add(newAction); newAction = new ActionInfoOdata(); newAction.ActionName = $"Delete {nameAction}"; newAction.ControllerName = action; newAction.Site = entitiesLocation.Replace("$metadata", ""); newAction.Verb = "DELETE"; newAction.RelativeRequestUrl = $"{action}({paramKeysStr})"; foreach (var item in paramKeys) { //item.orig.PropertyType newAction.Params.Add(item.Name, (item.orig.PropertyType, BindingSourceDefinition.Path)); } newAction.ReturnType = odatType; actions.Add(newAction); } return(actions); }