How to override Elmah applicationname set in Web.config - asp.net-mvc

We have a multi-tenanted MVC app, meaning that exactly the same app is published to multiple IIS virtual directories / applications, and then the app its self works out who it is, and skins its self (css) accordingly.
This is all very well, but anything logged by ELMAH in our elmah database gets logged under the same applicationName, as this is pulled out of Web.Config elmah section below where everything would be logged as "MyappName" :
<configuration>
[...]
<elmah>
<security allowRemoteAccess="false" />
<errorLog
type="Elmah.SqlErrorLog, Elmah"
connectionStringName="elmah"
applicationName="MyappName" />
</elmah>
</configuration>
The question is therefore how to override the applicationName setting from web.config with something specific so we can distinguish errors for a given tenant web site.

As this is configurable within the web.config, ELMAH are already providing you with a way to specify the application name when the application is deployed to different locations - it's just a case of making use of it.
This would generally be something that you would manipulate as part of your deployment steps. If you are doing it manually then it's going to be a pain, but it could be easily manipulated by using a web.config transform.
<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<elmah>
<errorLog applicationName="MyappName" xdt:Transform="SetAttributes" xdt:Locator="Match(name)" />
</elmah>
</configuration>
I wonder if the following might work, if you put the following into your Global.asax:
var service = ServiceCenter.Current;
ServiceCenter.Current = context =>
{
var connectionString = "YOUR CONNECTION STRING";
var container = new ServiceContainer(service(context));
var log = new SqlErrorLog(connectionString) { ApplicationName = "APP NAME HERE" };
container.AddService(typeof(ErrorLog), log);
return container;
};

Related

Can not run MVC Core project When I Publish

I have created an MVC Core Project(VS 2017) with SQL Server Data Base. My project works correctly in Local IIS with my real Host SQL Server. But when I publish my project to real host, the project does not work. Also I tested a simple project(with out database) in real host that it works correctly. I think I have a problem in connection string. what should I do to solve this problem? I will be tankful for your helps.
here are my some codes:
DataContext.cs
public class DataContext : IdentityDbContext<ApplicationUser>
{
private static bool _Created = false;
public DataContext()
{
if (!_Created)
{
_Created = true;
Database.EnsureCreated();
}
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("server = sheva.sepantahost.com;Persist Security Info = False; User ID = hbyby11847; Password = N*w23K+nd5; Initial Catalog = hbyby11847_sheva; ");
}
Web.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath=".\News_SourceIran.exe" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" />
</system.webServer>
</configuration>
my project solution
The application will connect to the database using the identity of the application pool that your IIS website is using. In IIS manager, look at what account that is being used and give that account appropriate permissions in the database.
The exception should also include the account it’s using when trying to connect.

App.config and web.config?

How do i read from app.config and web.config.
app.config reading is as follows .how do i read from web.config
using System.Configuration;
string configvalue1 = ConfigurationManager.AppSettings["countoffiles"];
string configvalue2 = ConfigurationManager.AppSettings["logfilelocation"];
also why do we store in these config files?
And How do i read from a user defined tag <display> in app.config below ??
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<display>
<add key="countoffiles" value="7" />
<add key="logfilelocation" value="abc.txt" />
</display>
</configuration>
what is the difference between values stored in app.config and web.config?
How do i decide where to keep certain data?
i got this error when i added <display> tag to the web.config in MVC application.Any clues on why??
Web.Config is used for applications hosted at IIS (Websites, Webservices)
App.Config is used for any other .NET applications like (WinForms, WPF, Windows Services)
To read from custom section I would go that way:
NameValueCollection displaySection = (NameValueCollection)ConfigurationManager.GetSection("display");
string countoffiles = displaySection ["countoffiles"];
string logfilelocation = displaySection ["logfilelocation"];
In regards to configuring custom sections, please check that article:
https://msdn.microsoft.com/en-us/library/2tw134k3.aspx

Sitecore adding port numbers to all URLs

Wondering if anyone has seen this behavior before. My instance of Sitecore 6.6 appends the port number to all the URLs it generates for my site. So for example, a link to the home page should be "https://example.org", but instead it's generated as "https://example.org:443". Everything functions fine with the port numbers, but it's muddling some stuff we're trying to do with SEO and canonicalization. Does anyone know if there's a setting or setup to not produce the port numbers? (I'm sure I could rewrite the URLs by catching them at the appropriate point in the pipeline, but I'm hoping for a simpler way before I jump to that.)
The Sitecore LinkManager is indeed not so clever. We also experienced this issue with a mix of proxy servers and load balancers. To remove the ports, we have created a custom LinkProvider which removes the port if needed (untested code sample):
public class LinkProvider : Sitecore.Links.LinkProvider
{
public override string GetItemUrl(Item item, UrlOptions options)
{
var url = base.GetItemUrl(item, options);
if (url.StartsWith("https://"))
{
url = url.Replace(":443", string.Empty);
}
return url;
}
}
And configure the new LinkProvider:
<configuration xmlns:set="http://www.sitecore.net/xmlconfig/set/">
<sitecore>
<linkManager defaultProvider="sitecore">
<providers>
<add name="sitecore" set:type="Website.LinkProvider, Website" />
</providers>
</linkManager>
</sitecore>
</configuration>
This is caused by having the 'scheme' property in the configuration/sitecore/sites/site element of the web.config (or patched config) being set to 'http' explicitly, but making requests over SSL. Removing this, or setting it to 'https' resolves the issue.
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
<sites>
<site patch:before="*[#name='website']"
name="my_website"
hostName="my_website.com"
scheme="http"
...
</sites>
</sitecore>
</configuration>
It's a known bug:
https://kb.sitecore.net/articles/913585
There is a patch for releases below 9.1 available here:
https://github.com/SitecoreSupport/Sitecore.Support.93141/releases
I agree with Jan's findings: setting externalPort on the site node in the configuration convinces Sitecore to exclude the port in a generated URL. I did a full write-up on my blog, including using the result for canonical URL tags.
http://findgnosis.com/2017/06/26/hiding-port-urls-produced-sitecores-linkmanager/
LinkManager:
You can cheat the LinkManager by adding port="443" externalPort="80" to your site-definition in <sites>. Don't know if this will cause other issues though.
<configuration>
<sitecore>
<sites>
<site name="website" port="443" externalPort="80" />
</sites>
</sitecore>
</configuration>
MediaManager:
If you know the url, set the Media.MediaLinkServerUrl-setting, to prevent Sitecore from creating the wrong url. Otherwise...
class SslFriendlyMediaProvider : MediaProvider
{
public override string GetMediaUrl(MediaItem item, MediaUrlOptions options)
{
var url = base.GetMediaUrl(item, options);
if(options.AlwaysIncludeServerUrl)
// https://example.com:443/a b?c=123 --> https://example.com/a%20b?c=123
return new Uri(url).AbsoluteUri;
return url;
}
}
Config:
<configuration xmlns:set="http://www.sitecore.net/xmlconfig/set/">
<sitecore>
<mediaLibrary>
<mediaProvider set:type="SslFriendlyMediaProvider, Assembly" />
</mediaLibrary>
</sitecore>
</configuration>

asp.net mvc: disabled RoleManager is still executed

I have a web site where configured with:
<roleManager enabled='false'></roleManager>
But I still can see roleManager being executed in the pipeline (by looking at traces, also I am getting exception when roleManager tries to load roles from SQL providers configured in machine.config)
How can I disable roleManager?
fix
add enableSimpleMembership with value false app setting to your web.config.
cause
<roleManager enabled="false" />
will cause Roles.Enabled flag to be set to false, as expected,
but there is WebMatrix.WebData.WebSecurity that says:
internal static void PreAppStartInit()
{
if (!ConfigUtil.SimpleMembershipEnabled)
return;
...
Roles.Enabled = true;
...
}
this will override roleManager setting (this code is executed before RoleManager module is).
to disable SimpleMembership you can add app setting enableSimpleMembership with value="false" (web.config):
<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
<appSettings>
<add key="enableSimpleMembership" value="false" />
</appSettings>
</configuration>
this will prevent webmatrix from enabling RoleManager.
Another solution (hack) is to remove RoleManager module from the list of modules:
....
<system.webServer>
<modules>
<remove name="RoleManager"/>
</modules>
....
no... I don't think it's correct, even with enableSimpleMembership=false, you'd still need to implement a Dummy RoleProvider, otherwise, exception "The Role Manager feature has not been enabled."
Here's how to implement a dummy RoleProvider:
Turning off only the Role Provider in SimpleMembership

Specifying Roles in web.config of an asp.net MVC application

I am creating an MVC application with forms auth. I am authenticating against active directory and so have created a custom RoleProvider. My application is only concerned with a small set of roles which up until now I have been defining in the appSettings section of my web.config:
<appSettings>
<add key="DirectorRole" value="Domain\Directors" />
<add key="ManagementRole" value="Domain\Managers" />
...
</appSettings>
However I have run into a couple of problems with this approach:
I cannot reference these setting in my contoller data annotations: [Authorize(Roles = ConfigurationManager.AppSettings["DirectorRole"])] as it wont compile so I have to specify the name of the group again: [Authorize(Roles = "Domain\\Directors")].
In my web.config, I would like to specify the groupsToUse for my role provider and just reference a pre-existing list, rather than maintain two seperate lists of the same set of roles.
It seems that there must be a better/reusable way to define the roles in the web.config, can someone point me in the right direction please?
I would prefer using a custom authorize attribute. Like this one.
public class MyAuthorizeAttribute : AuthorizeAttribute {
public MyAuthorizeAttribute(params string[] roleKeys) {
List<string> roles = new List<string>(roleKeys.Length);
//foreach(var roleKey in roleKeys) {
//roles.Add(ConfigurationManager.AppSettings["DirectorRole"]);
//}
var allRoles = (NameValueCollection)ConfigurationManager.GetSection("roles");
foreach(var roleKey in roleKeys) {
roles.Add(allRoles[roleKey]);
}
this.Roles = string.Join(",", roles);
}
}
In your controller, use:
[MyAuthorize("DirectorRole")]
In your web.config
<configSections>
<section
name="roles"
type="System.Configuration.NameValueFileSectionHandler,System, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</configSections>
<roles>
<add key="DirectorRole" value="Domain\Directors" />
<add key="ManagementRole" value="Domain\Managers" />
</roles>
I hope this will solve your first problem just fine. And twiking a little will solve the second one too.
Please have a look at this excellent example, in which author talks about the problem you are facing.
http://www.ryanmwright.com/2010/04/25/dynamic-controlleraction-authorization-in-asp-net-mvc/

Resources