Connection to Oracle Database Via an API Settings File - oracle

I'm trying to learn API's as we have a business case for it. and for the most part I can read and Serialize/Deserialize the data from our Oracle database - HOWEVER, in order to connect to the database im hardcoding the connectionString variable at the top of the page e.g
con = new OracleConnection("Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=my.oracle.host)(PORT=9999)))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=myOracleService)));User Id=XXXXXX;Password=XXXXXX; ");
Ive created the OracleSettingsDB.cs file as below
public class OracleDbSettings{
public string Host{get;set;}
public string Port{get;set;}
public string User{get;set;}
public string Password{get;set;}
public string Service{get;set;}
public string ConnectionString{
get
{
return $"Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST={Host})(PORT={Port})))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME={Service})));User Id={User};Password={Password};";
}
}
}
}
and following on from that added the values to the appsettings.json
"AllowedHosts": "*",
"OracleDbSettings": {
"Host": "my.oracle.host",
"Port":"9999",
"User": "XXXXX",
"Service":"myOracleService",
"Password": "XXXXXX" //Yes I know I shouldnt store this here
}```
I added the connectionString into the Startup.cs
``` var connectionString = Configuration.GetSection(nameof(OracleDbSettings)).Get<OracleDbSettings>();
But what I dont now get is how i reference the connectionString within the Repository file so that I can call
using (OracleConnection con = new OracleConnection(ConnectionString)
Hopefully, someone will be able to point me in the right direction as all the videos Ive watched on Youtube or pages ive found just reference the hardcoded data source - which we dont want to do.
Thanks and Hopefully theres enough information there =]

I'm afraid you need to bind the values in appsettings.json file to your OracleDbSettings model, and I find similar document about how to connect to oracle which matches your using (OracleConnection con = new OracleConnection(ConnectionString), so I provide the tutorial here to solve your requirement. And this is my test details:
I newly created an asp.net core 5 mvc project and create a model like yours:
namespace WebMvcApp.Models
{
public class OracleDbSettings
{
public const string keyword = "OracleDbSettings";
public string Host { get; set; }
public string Port { get; set; }
public string User { get; set; }
public string Password { get; set; }
public string Service { get; set; }
public string ConnectionString
{
get
{
return $"Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST={Host})(PORT={Port})))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME={Service})));User Id={User};Password={Password};";
}
}
}
}
Modify the startup.cs file-> Configure method, and adding these line-code:
var dbSettings = new OracleDbSettings();
Configuration.GetSection(OracleDbSettings.keyword).Bind(dbSettings);
var connect_string = dbSettings.ConnectionString;
And my appsettings.json looks like this:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"OracleDbSettings": {
"Host": "my.oracle.host",
"Port": "9999",
"User": "XXXXX",
"Service": "myOracleService",
"Password": "XXXXXX"
}
}

Related

How to handle multiple items in a POST request

I have a request where there is multple object in the json file . I need to add them via PostMan
This is my Dto
public class CustomerDto
{
[Required(ErrorMessage = "The Id is required")]
public int Id { get; set; }
[Required(ErrorMessage = "The FirstName is required")]
public string FirstName { get; set; }
}
This is my ServiceClass, this is where i add it to a class level customerlist object for now.
public static class CustomerService
{
public static List<CustomerDto> customerList = new List<CustomerDto>() {
new CustomerDto { FirstName = "Joe", Id = 1},
new CustomerDto { FirstName = "Rose", Id = 2},
new CustomerDto { FirstName = "Sid", Id = 3 },
};
}
This is my Api Post Request
[HttpPost]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public ActionResult<VillaDTO> addCustomer([FromBody]CustomerDTO customerDTO)
{
if (customerDTO== null)
{
return BadRequest(villaDTO);
}
CustomerService.customerList.Add(customerDTO);
return Ok(customerDTO);
}
I try to debug but before it hits the method call it throws the exceptions. I just want to know how my object is populated first.
Thanks for having a look
After updating a bad Json using Json Validator . I now get this error message.
DTO seems to be the issue .
{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "00-58f71fb73f3af573db60c11551cb2093-792cd201f9e3f0d3-00",
"errors": {
"$": [
"The JSON value could not be converted to CustomerManagementAPI.Model.Dto.CustomerDto. Path: $ | LineNumber: 0 | BytePositionInLine: 1."
],
"customerDTO": [
"The customerDTO field is required."
]
}
}
If you're trying to post a collection
[
{
"firstName": "John",
"id": 6
},
{
"firstName": "Anna",
"id": 7
}
]
Have your action accept a collection as well
public IActionResult addCustomer([FromBody] List<CustomerDto> customers) { }

Fetching data from an API in ASP.NET Core MVC

I'm facing problem while fetching data from an API in ASP.NET Core MVC controller (imdb api).
The problem is I cannot deserialize the current JSON object into type
this is my code
List<Movie> movieList = new List<Movie>();
using (var httpClient = new HttpClient())
{
using (var response = await httpClient.GetAsync("https://imdb-api.com/en/API/Title/****/tt0110413"))
{
string apiResponse = await response.Content.ReadAsStringAsync();
var Movie = JsonConvert.DeserializeObject<Movie>(apiResponse);
//movieList = JsonConvert.DeserializeObject<List<Movie>>(apiResponse);
}
}
return View();
My api data looks like this
{
"items": [
{
"id": "tt0111161",
"rank": "1",
},...
]
}
I have an issue with deserialize - any help?
You need to make sure the structure of Movie is corresponding to your json data:
public class Movie {
public List<Item> items { get; set; }
}
public class Item {
public string id { get; set; }
public string rank { get; set; }
}
Use IMDbApiLib.
GitHub:
https://github.com/IMDb-API/IMDbApiLib
Nuget:
https://nuget.org/packages/IMDbApiLib
Movie's TitleData:
https://github.com/IMDb-API/IMDbApiLib/blob/master/IMDbApiLib/Models/TitleData.cs

Client Credentials Grant on CRM Dynamics 2016 On Premise Web API

I am trying to call the CRM Dynamics On Premise 2016 Web API.
I configured Authorization Code Flow using OAuth and it is working. But, i need to set up the Client Credentials flow since many applications are running on background and they can't be prompted with login screen.
Since, its On Premise, we dont have Azure AD.
Where do we go and register our application?
Is there another way to access Web API for On premise dynamics CRM( For example userid,password etc)
Xrm api is accessible via client credentials without any special setup (be it on-prem or on-line) - you just setup S2S user with appropriate permissions, and you can log him in like:
static void InContext(Action<IOrganizationService> callback, Org org)
{
var credentials = new ClientCredentials();
if (!org.IsLocal)
{
credentials.UserName.UserName = org.UserName;
credentials.UserName.Password = org.Password;
}
else
{
credentials.Windows.ClientCredential = new NetworkCredential(org.UserName, org.Password);
}
using (var serviceProxy =
new OrganizationServiceProxy(new Uri(org.OrganizationServiceUri),
null, credentials
, null))
{
callback.Invoke(serviceProxy);
}
}
public class Org
{
public string UserName { get; set; }
public string Password { get; set; }
public string OrganizationServiceUri { get; set; }
public bool IsLocal { get; set; }
public Org()
{
}
public Org(bool isLocal, string userName, string password, string organizationServiceUri)
{
IsLocal = isLocal;
UserName = userName;
Password = password;
OrganizationServiceUri = organizationServiceUri;
DiscoveryServiceUri = discoveryServiceUri;
}
}
And then in your backend code:
var org = new Org(true, "Administrator", "Password",
"http://ondracrm/org/XRMServices/2011/Organization.svc");
InContext((os) => {
// some sample work with organization service
var response = (RetrieveEntityResponse)os.Execute(
new RetrieveEntityRequest
{
LogicalName = "contact",
EntityFilters = EntityFilters.Attributes
});
}, org);

Filtering schema out of NSwag swagger

I have an ASP.NET full framework application with API endpoints. I am using NSwag to generate a swagger document. This all works.
I need to generate a document for only a small subset of the endpoints. The paths are filtered, but the schema is not. How do I filter the schema objects to match the path filtering?
Example:
I have this filter
public class IncludeControllersInSwagger : IOperationProcessor
{
public Task<bool> ProcessAsync(OperationProcessorContext context)
{
return Task.FromResult(
context.ControllerType == typeof(ControllerA));
}
}
And this at startup:
settings.GeneratorSettings.OperationProcessors.Add(new IncludeControllersInSwagger());
The controllers are:
public class AResponse
{
public string Message { get; set; }
public bool Flag { get; set; }
}
public class BResponse
{
public string Message { get; set; }
public int Count { get; set; }
}
[Route("a")]
public class ControllerA : ApiController
{
[HttpGet]
public AResponse Get()
{
return new AResponse
{
Message = "Hello from A",
Flag = true
};
}
}
[Route("b")]
public class ControllerB : ApiController
{
[HttpGet]
public BResponse Get()
{
return new BResponse
{
Message = "Hello from B",
Count = 42
};
}
}
Then the generated swagger contains just one path:
"paths": {
"/a": {
"get": { .. etc
}
}
And that's all, this is correct.
But the schemas contains both:
"schemas": {
"AResponse": {
"type": "object",
"additionalProperties": false,
etc
},
"BResponse": {
"type": "object",
"additionalProperties": false,
etc
}
}
}
The BResponse type should not be there. How do you remove it?
This extra data makes the Schemas section extremely verbose and unsuitable for public documentation in the case where there are over 10 endpoints, and only 2 are exposed via a gateway and therefor documented in swagger.
There is a ISchemaProcessor but it does not return a Boolean like the IOperationProcessor.
Have you tried to add the operation filter as first element?
i.e. OperationProcessors.Insert(0, new IncludeControllersInSwagger())
I think this is important as it will filter out the operation before the dto schemas are generated and added to the document.
This is not an answer to your problem, as you already got an answer that seems to work. I do have a suggestion however. Instead of checking the type of controller in your processor, I would suggest to create a custom attribute:
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
public class IncludeInSwaggerAttribute : Attribute
{
}
Then change your processor to look for this attribute:
public class IncludeInSwaggerOperationProcessor : IOperationProcessor
{
public async Task<bool> ProcessAsync(OperationProcessorContext context)
{
return context.ControllerType.GetCustomAttributes<IncludeInSwaggerAttribute>().Any() ||
context.MethodInfo.GetCustomAttributes<IncludeInSwaggerAttribute>().Any();
}
}
This way, you can add the attribute to any new controller you want to include in swagger without having to change your processor. You can also add the attribute on a single action to only include that action, leaving the rest of the actions in the controller out of swagger.

Implement OAuth with ASP.NET WebAPI

Hello Friends I would like to ask you that can any one have an example to integrate oAuth in ASP.Net web api with out integrating any packages or Entity framework??i search it a lot but find a various way using nuget packages and other packages but i need the way using simple third party calls because i need this authorization in .net as well as java api's. Can any one help me out in this.
Thanks in advance...
Yes you can do this, i implemented this in my web api using oAuth in web api 2 project.
First, have an asp.net project with oauth is configured since we will take cooy some files into web api project.
Here is the steps:
1) In the web api, add a new class file called "IdentityConfig.cs".
This class will have: ApplicationUser, ApplicationUserManager, ApplicationSignInManager and ApplicationDbContext classes.
2) Make sure that these classes above is under your api namespace so it is accessible through all your controllers.
// Configure the application user manager which is used in this api.
public class ApplicationUser : IdentityUser
{
#region custom properties
public string Name { get; set; }
public int? ZipCode { get; set; }
public long? CountryId { get; set; }
public bool IsDeleted { get; set; }
public bool EmailConfirmed { get; set; }
public DateTime CreatedDate { get; set; }
public long UserId { get; set; }
#endregion
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// Add custom user claims here
return userIdentity;
}
}
public class ApplicationUserManager : UserManager<ApplicationUser>
{
public ApplicationUserManager(IUserStore<ApplicationUser> store)
: base(store)
{
}
public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
{
var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));
// Configure validation logic for usernames
manager.UserValidator = new UserValidator<ApplicationUser>(manager)
{
AllowOnlyAlphanumericUserNames = false,
RequireUniqueEmail = true
};
// Configure validation logic for passwords
manager.PasswordValidator = new PasswordValidator
{
RequiredLength = 6,
RequireNonLetterOrDigit = false,
RequireDigit = false,
RequireLowercase = true,
RequireUppercase = false,
};
// Configure user lockout defaults
manager.UserLockoutEnabledByDefault = true;
manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5);
manager.MaxFailedAccessAttemptsBeforeLockout = 5;
// Register two factor authentication providers. This application uses Phone and Emails as a step of receiving a code for verifying the user
// You can write your own provider and plug it in here.
manager.RegisterTwoFactorProvider("Phone Code", new PhoneNumberTokenProvider<ApplicationUser>
{
MessageFormat = "Your security code is {0}"
});
manager.RegisterTwoFactorProvider("Email Code", new EmailTokenProvider<ApplicationUser>
{
Subject = "Security Code",
BodyFormat = "Your security code is {0}"
});
manager.EmailService = new EmailService();
//manager.SmsService = new SmsService();
var dataProtectionProvider = options.DataProtectionProvider;
if (dataProtectionProvider != null)
{
manager.UserTokenProvider =
new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity"));
}
return manager;
}
}
// Configure the application sign-in manager which is used in this api.
public class ApplicationSignInManager : SignInManager<ApplicationUser, string>
{
public ApplicationSignInManager(ApplicationUserManager userManager, IAuthenticationManager authenticationManager)
: base(userManager, authenticationManager)
{
}
public override Task<ClaimsIdentity> CreateUserIdentityAsync(ApplicationUser user)
{
return user.GenerateUserIdentityAsync((ApplicationUserManager)UserManager);
}
public static ApplicationSignInManager Create(IdentityFactoryOptions<ApplicationSignInManager> options, IOwinContext context)
{
return new ApplicationSignInManager(context.GetUserManager<ApplicationUserManager>(), context.Authentication);
}
}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DBCONNECTIONKEY", throwIfV1Schema: false)
{
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
Note: DBCONNECTIONKEY is the key for the connection string in web.config
3) Add Startup.cs file to the root of your web api. copy the logic from the existing one you have in asp.net. feel free to tweak the configuration context properties as needed in the web api project.
4) Use objects from these classes to sign in users, and manager application user objects as you have in asp.net web app.
That's all :)
Hope this helps.

Resources