What's wrong with my connection string (can not access it through ConfiguratioManager)? - connection-string

I'm trying to connect to Azure SQL, but I get error The underlying provider failed on Open
I discovered that I have put connection string in the wrong app.config - moved it to the executable project's app.config, but still the same result
When I check ConfigurationManager.ConnectionStrings["AzureDatabase"] it returns null. And when I try to connect it just uses default SQLExpress.
When I check build folder of my executable application - there is an <app_name>.exe.config file with "AzureDatabase". I'm stuck on where to search from here
This is my DbContext class
[DbConfigurationType(typeof(AzureDbConfiguration))]
public class ProductDbContext : DbContext
{
//Db sets
static MyContext()
{
//I don't want to change database from code
Database.SetInitializer<MyContext>(null);
}
public MyContext() : base("AzureDatabase") //this is my connectionstring
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//some mappings
}
}
This is AzureDbConfiguration
public class AzureDbConfiguration : DbConfiguration
{
public AzureDbConfiguration()
{
SetExecutionStrategy("System.Data.SqlClient", () => new SqlAzureExecutionStrategy(2, TimeSpan.FromSeconds(10)));
}
}
This is my app.config file
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<connectionStrings>
<add name="AzureDatabase"
connectionString="Server=tcp:xxx.database.windows.net,1433;Initial Catalog=xxx;Persist Security Info=False;User ID=xxxx;Password=xxxxx;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;" providerName="System.Data.SqlClient"/>
</connectionStrings>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
<parameters>
<parameter value="mssqllocaldb" />
</parameters>
</defaultConnectionFactory>
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
</configuration>
Any ideas on what's wrong here?

It turns out the problem was that I was trying to work with app.config from Class library (I was trying to create an integration tests)
One of potential solutions is to create a separate settings file for Class library. You can read about it in this StackOverflow post

Related

Adding Web API as Application to Website in IIS, where does Frontend point to?

I have two separate processes running for my website. The frontend is reactjs and the backend is asp.net core 6.
I have a reactjs website running on localhost:9000 on IIS on a server.
I've added the .net web api published files to the above website as an application with it's own application pool.
In the .env REACT_APP_API_URL: I don't know how to point to the API, before i just used localhost:5000, how do I change this to use the application url?
Tried: */api/controllername, localhost/api/controllername, IPADDRESS/api/controllername,
COMPUTERNAME/api/controllername etc.
Here is the Program.cs
using api;
using api.Services;
using Microsoft.AspNetCore.Authentication.Cookies;
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.UseIIS();
builder.Services.Configure<IISServerOptions>(options =>
{
options.AutomaticAuthentication = false;
});
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddCors(options =>
{
options.AddPolicy("AllowOrigin",
options =>
{
options.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod();
});
});
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.Cookie.Name = "Project.Cookies";
options.ExpireTimeSpan = TimeSpan.FromHours(12);
options.SlidingExpiration = true;
options.LoginPath = "/User/Login";
options.LogoutPath = "/User/Logout";
options.Cookie.IsEssential = true;
});
builder.Services.AddDbContext<DbDataContext>();
builder.Services.AddScoped<IProjectService, ProjectService>();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment() || app.Environment.IsProduction())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseCors();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
Here is the web.config for the backend:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet" arguments=".\api.dll" stdoutLogEnabled="true" stdoutLogFile=".\logs\stdout" hostingModel="inprocess" />
</system.webServer>
</location>
</configuration>
<!--ProjectGuid: -->
And here is the web.config for the reactjs frontend:
<?xml version="1.0"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="React Routes" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
<add input="{REQUEST_URI}" pattern="^/(api)" negate="true" />
</conditions>
<action type="Rewrite" url="/" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
I'm in over my head on how to get these talking to each other.
I can run the dotnet from the commandline and have reactjs talk to that localhost on the server (this wont work when connecting to the website from outside the server). But I need these working in IIS.
Any help would be greatly appreciated.
The front end and the backend application should use same port. In your react project, you should use something like const baseUrl = document.getElementsByTagName('base')[0].getAttribute('href'); or process.env.PORT. And your frontend will start with port which you create the main website. You can find it like below.
The main application and virtual application host in same site with different application. And they also should use same port. You can check my test result.
And you can open the frontend application by clicking the Browse *:8031 in the right panel in my picture.
You can access your api application via https://localhost:8031/api/{apiname or controller/action}.
In your case, it should be http://localhost:port/{hidden by red pen}api/controllername.

How to get DNN to create a sitemap links for custom modules?

We have a DNN website with custom modules which uses Ajax to load Grid Items.
How can I get DNN to create a sitemap for these links as well? I am currently using an external program but would like DNN to generate these sitemaps automatically with all our links.
The site is: https://www.parrot.co.za
You would typically do this by creating a SiteMap provider for your module.
You can find a working example in my DNNSimpleArticle module on GitHub
public class Sitemap : SitemapProvider
{
public override List<SitemapUrl> GetUrls(int portalId, PortalSettings ps, string version)
{
var listOfUrls = new List<SitemapUrl>();
foreach (Article ai in ArticleController.GetAllArticles(portalId))
{
var pageUrl = new SitemapUrl
{
Url =
ArticleController.GetArticleLink(ai.TabID, ai.ArticleId),
Priority = (float)0.5,
LastModified = ai.LastModifiedOnDate,
ChangeFrequency = SitemapChangeFrequency.Daily
};
listOfUrls.Add(pageUrl);
}
return listOfUrls;
}
}
and then you need to register the sitemap with DNN in the .DNN file used during the module's installation
<component type="Config">
<config>
<configFile>web.config</configFile>
<install>
<configuration>
<nodes>
<node path="/configuration/dotnetnuke/sitemap/providers" action="update" key="name" collision="overwrite">
<add name="DNNSimpleArticleSiteMapProvider" type="Christoc.Modules.dnnsimplearticle.Providers.Sitemap.Sitemap, DNNSimpleArticle" providerPath="~\DesktopModules\dnnsimplearticle\Providers\Sitemap\" />
</node>
</nodes>
</configuration>
</install>
<uninstall>
<configuration>
<nodes />
</configuration>
</uninstall>
</config>
</component>

spring camel test using multiple contexts

I have two camel contexts (A and B) at different xml using Spring. When I load just one context my junit works, but when a I try to load both contexts the Endpoint inject fail running junit.
So, someone have a sample how to use Test using multiple context with spring camel?
Spring Test
public class BaseSpringTest extends CamelSpringTestSupport
{
protected AbstractXmlApplicationContext createApplicationContext()
{
return new ClassPathXmlApplicationContext("camel-config.xml");
}
}
My file camel-config.xml
<beans>
<context:annotation-config/>
<import resource="classpath:camel-test-dao.xml" />
<import resource="classpath:camel-contextA.xml"/>
<import resource="classpath:camel-contextB.xml"/>
</beans>
My contexts:
<camelContext xmlns="camel.apache.org/schema/spring" id="contextA">
...
</camelContext>
<camelContext xmlns="camel.apache.org/schema/spring" id="contextB">
...
</camelContext>
My unit test, failing at inject Endpoint:
#EndpointInject(uri = "direct:myroute", context="contextB")
private Endpoint eFooTest;
Stacktrace:
org.apache.camel.spring.GenericBeansException: Error post processing bean: com.mycompany.test.FooTest; nested exception is java.lang.NullPointerException
at org.apache.camel.spring.CamelBeanPostProcessor.postProcessBeforeInitialization(CamelBeanPostProcessor.java:154)
at org.apache.camel.test.spring.CamelSpringTestSupport.postProcessTest(CamelSpringTestSupport.java:62)
at org.apache.camel.test.junit4.CamelTestSupport.doSetUp(CamelTestSupport.java:319)
at org.apache.camel.test.junit4.CamelTestSupport.setUp(CamelTestSupport.java:238)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:55)
at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:55)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: java.lang.NullPointerException
at org.apache.camel.impl.CamelPostProcessorHelper.matchContext(CamelPostProcessorHelper.java:84)
at org.apache.camel.impl.DefaultCamelBeanPostProcessor$1.doWith(DefaultCamelBeanPostProcessor.java:181)
at org.apache.camel.util.ReflectionHelper.doWithFields(ReflectionHelper.java:73)
at org.apache.camel.impl.DefaultCamelBeanPostProcessor.injectFields(DefaultCamelBeanPostProcessor.java:168)
at org.apache.camel.impl.DefaultCamelBeanPostProcessor.postProcessBeforeInitialization(DefaultCamelBeanPostProcessor.java:82)
at org.apache.camel.spring.CamelBeanPostProcessor.postProcessBeforeInitialization(CamelBeanPostProcessor.java:148)
... 31 more
Apparently there is a bug at CamelBeanPostProcessor, when there are more one context a null value is returned!
if (contexts != null && contexts.size() == 1) {
#XmlTransient
private final DefaultCamelBeanPostProcessor delegate = new DefaultCamelBeanPostProcessor() {
#Override
public CamelContext getOrLookupCamelContext() {
if (camelContext == null) {
if (camelId != null) {
LOG.trace("Looking up CamelContext by id: {} from Spring ApplicationContext: {}", camelId, applicationContext);
camelContext = applicationContext.getBean(camelId, CamelContext.class);
} else {
// lookup by type and grab the single CamelContext if exists
LOG.trace("Looking up CamelContext by type from Spring ApplicationContext: {}", applicationContext);
Map<String, CamelContext> contexts = applicationContext.getBeansOfType(CamelContext.class);
if (contexts != null && contexts.size() == 1) {
camelContext = contexts.values().iterator().next();
}
}
}
return camelContext;
}
Camel 2.16.2
Spring 4.1.5
JDK 1.7
JDK 1.8
Thanks #Jorge-c, but using routeContext we continuous having just one single CamelContext.
To use multiply contexts at unit test don't use CamelSpringTestSupport, there are a bug.
public class BaseSpringTest extends CamelSpringTestSupport {...}
Use "#RunWith(SpringJUnit4ClassRunner.class)"
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration("/camel-my-root-spring-config.xml")
public class BaseSpringJUnit4
{
#EndpointInject(uri = "direct:myroute", context="contextB")
private Endpoint eFooTest;
}
This works! Doesn't forget to put explicitilly context="contextB" in the endpoint annotation
Camel 2.16.2
Spring 4.1.5
JDK 1.7
JDK 1.8
I've been struggling with this for a while as well. Finally I managed a workaround which allows me to use the original routes xml files used in production but combined into a single camel context to be able to use it for testing. This way I'm able to inject mocks for bean endpoints and check the complete process by asserting on the mocks.
There are two different bundles. One from invoicing and another for emailing. The routes orchestrate the process.
First I externalized the routes on the production xml files. Spring context (invoicing-spring-context.xml) and routes (invoicing-routes.xml) file for invoicing bundle:
<?xml version="1.0" encoding="UTF-8"?>
<beans ...>
...
<camelContext id="invoicingCamelContext"
xmlns="http://camel.apache.org/schema/spring">
<routeContextRef ref="invoicingRoutes"/>
</camelContext>
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<beans ...>
<routeContext id="invoicingRoutes" xmlns="http://camel.apache.org/schema/spring">
<route id="planner" autoStartup="true">
<from uri="quartz://planner?cron=0+0+23+16+*+?" />
<to uri="direct:invoicing" />
</route>
<route id="invoicing" autoStartup="true">
<from uri="direct:invoicing?exchangePattern=InOut" />
<to uri="bean:invoicer?method=generateInvoices" />
<to uri="direct-vm:emailing" />
</route>
</routeContext>
</beans>
Spring context (emailing-spring-context.xml) and routes (emailing-routes.xml) for emailing bundle:
<?xml version="1.0" encoding="UTF-8"?>
<beans ...>
...
<camelContext id="emailingCamelContext"
xmlns="http://camel.apache.org/schema/spring">
<routeContextRef ref="emailingRoutes"/>
</camelContext>
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<beans ...>
<routeContext id="emailingRoutes" xmlns="http://camel.apache.org/schema/spring">
<route id="emailing" autoStartup="true">
<from uri="direct-vm:emailing" />
<to uri="bean:emailer?method=createEmails" />
<to uri="bean:emailer?method=sendEmails" />
</route>
</routeContext>
</beans>
Then for testing purposes I created another spring context (complete-process-test-spring-context.xml) which imports both routes files:
<?xml version="1.0" encoding="UTF-8"?>
<beans ...>
...
<camelContext id="completeProcessTestCamelContext"
xmlns="http://camel.apache.org/schema/spring">
<routeContextRef ref="invoicingRoutes"/>
<routeContextRef ref="emailingRoutes"/>
</camelContext>
</beans>
And the test class looks like:
public class CompleteProcessTest extends CamelSpringTestSupport {
#Test
public void completeProcess() {
...
invoicerMock.generateInvoices(EasyMock.isA(Exchange.class));
emailerMock.createEmails(EasyMock.isA(Exchange.class));
emailerMock.sendEmails(EasyMock.isA(Exchange.class));
EasyMock.replay(invoicerMock);
EasyMock.replay(emailerMock);
this.template.requestBody(this.context.getEndpoint("direct://invoicing"), "");
EasyMock.verify(invoicerMock);
EasyMock.verify(emailerMock);
}
#Override
protected AbstractApplicationContext createApplicationContext() {
return new ClassPathXmlApplicationContext("classpath:/META-INF/spring/invoicing-routes.xml",
"classpath:/META-INF/spring/emailing-routes.xml",
"classpath:/META-INF/spring/complete-process-test-spring-context.xml");
}
...
}

Decompressing Web Api response

I am compressing web Api responses with following config
<system.webServer>
<httpCompression directory="%SystemDrive%\inetpub\temp\IIS Temporary Compressed Files">
<scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll" />
<dynamicTypes>
<add mimeType="text/*" enabled="true" />
<add mimeType="application/*" enabled="true" />
<add mimeType="*/*" enabled="false" />
</dynamicTypes>
<staticTypes>
<add mimeType="text/*" enabled="true" />
<add mimeType="application/*" enabled="true" />
<add mimeType="*/*" enabled="false" />
</staticTypes>
</httpCompression>
<urlCompression doStaticCompression="true" doDynamicCompression="true" />
Now when i consume this in a Win Form applications and try to do the follwoing
var rawData = await response.Content.ReadAsStringAsync();
var deserializedData = JsonConvert.DeserializeObject<Employees[]>(rawData).ToList();
it fails on
var deserializedData = JsonConvert.DeserializeObject(rawData).ToList();
the Error message is
{"Unexpected character encountered while parsing value: . Path '', line 0, position 0."}
I guess this is due to the fact that content is gziped and not being deserialized. Can anyone suggest a solution ? This works locally fine as local IIS is not gzip enabled
You need to enable automatic GZip decompression:
var handler = new HttpClientHandler { AutomaticDecompression = DecompressionMethods.GZip };
var client = new HttpClient(handler);

WCF + Silverlight + HttpContext.Current.Session is null

my problem....
i am tryingo to access session from Silverlight and WCF basicHttpBinding...
i saw some posts where it's possible (http://www.dotnetspider.com/Silverlight-Tutorial-317.aspx)
Mys cenario is:
Silvelright 4 FW 3.5
in web.config i have
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="ViewModelDemo.Web.Service1Behavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="ViewModelDemo.Web.Service1Behavior" name="ViewModelDemo.Web.Service1">
<endpoint address="" binding="basicHttpBinding" contract="ViewModelDemo.Web.Service1">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
</system.serviceModel>
and my service:
[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
public class Service1
{
[OperationContract]
publicvoid Test()
{
var session = System.Web.HttpContext.Current.Session;
}
}
and it''s call
var client = new Service1Client();
client.GetUserMacroFunctionsCompleted += new System.EventHandler<GetUserMacroFunctionsCompletedEventArgs>(client_GetUserMacroFunctionsCompleted);
client.GetUserMacroFunctionsAsync();
void client_GetUserMacroFunctionsCompleted(object sender, GetUserMacroFunctionsCompletedEventArgs e)
{
var test = ((Collection<Function>)e.Result);
}
HttpContext.Current is always null!
Any suggestions?
Yes HttpContext must be always null because your service configuration doesn't setup ASP.NET compatibility and your service doesn't require ASP.NET compatibility.
Add this to your configuration:
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
And change AspNetCompatibilityRequirements so that your service cannot be hosted without former configuration:
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
This link probably to help you.
http://blogs.msdn.com/b/sajay/archive/2006/08/03/687361.aspx
aspNetCompatibilityEnabled="true" doesn't help me till I set allowCookies="true" on the client binding configuration.
Update your web.config file to include
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
</system.serviceModel>
This should work, or else also change the AspNetCompatibilityRequirementsMode attribute on the contract to Required.

Resources