Strange error with MvcSiteMapProvider. It some how find 2 root nodes - mvcsitemapprovider

I am using MvcSiteMapNode without xml just with the decorator's way. As i said in this post
I am sure that i have only one node with empty root node. Also it always works, except some times that i get this error.
There is more than one node declared without a parent key. The parent
key must be set for all but 1 node in the SiteMap. The node with no
parent key will be considered the root node. Note that when defining
nodes in XML, the XML file must contain the root node.
You can disable XML configuration by setting the
MvcSiteMapProvider_EnableSiteMapFile setting to "false". For an
external DI configuration, you can disable XML parsing by removing the
XmlSiteMapNodeProvider from the MvcSiteMapProvider DI module.
Alternatively, you can set the MvcSiteMapProvider_IncludeRootNodeFromSiteMapFile setting to "false"
to exclude the root node from the XML file, but include all of the
other nodes. For an external DI configuration, this setting can be
found on the constructor of the XmlSiteMapNodeProvider.
SiteMapCacheKey: 'sitemap://localhost/'
Ambiguous Root Nodes:
ParentKey: '' | Controller: 'Home' | Action: 'Index' | Area: 'Admin' |
URL: '/Admin' | Key: 'root' | Source: 'MvcSiteMapNodeAttribute'
ParentKey: '' | Controller: 'Home' | Action: 'Index' | Area: 'Admin' |
URL: '/Admin' | Key: 'root' | Source: 'MvcSiteMapNodeAttribute'
my App.Settings
<add key="MvcSiteMapProvider_EnableSiteMapFile" value="false" />
<add key="MvcSiteMapProvider_IncludeRootNodeFromSiteMapFile" value="false" />
<add key="MvcSiteMapProvider_IncludeAssembliesForScan" value="dllmain,dll2" />
<add key="MvcSiteMapProvider_UseExternalDIContainer" value="false" />
<add key="MvcSiteMapProvider_ScanAssembliesForSiteMapNodes" value="true" />
I think it has to do, with the way sitemap is it initialized. It might be vulnerable to cross-thread operation. It might get double initialized.
Do you have any advice for this?
Thanks in advance.

Please have a look at this answer for help with setting up MvcSiteMapProvider with areas. The routes have to be configured using the correct conventions or it won't work right.
If you are certain that you only have 1 node in your entire site that has not set the parent node (or has set it to null or empty string) AND you are using [MvcSiteMapNode] attributes, this could be caused by the assemblies being loaded into the AppDomain more than one time. Check the AppDomain.CurrentDomain.GetAssemblies() method to see if your target assemblies (in this case dllmain and dll2) are in the result more than once.

Related

Is there a way to set the minlevel of a NLog logger via a variable?

Using NLog v4.4.12, I have this in my App.config
<nlog>
<include file="..\Common\Logs\Variables.xml" />
<rules>
<logger name="*" minlevel="${logLevel}" writeTo="LogFile, Wcf"/>
</rules>
</nlog>
And here is my Variables.xml file content
<?xml version="1.0" encoding="utf-8"?>
<nlog autoReload="true">
<variable name="logLevel" value="Fatal" />
</nlog>
But I get an Exception when launching my app
Unknown log level: ${logLevel}
Am I doing something wrong or is it just impossible?
The goal of this is to eventually have an xml file per project that need to log things so each project can have his own minlevel and be able to change it at runtime via the edition of this xml.
Edit: Adding this code just before the Exception is thrown shows that my variable is there with the desired value.
var nl = NLog.LogManager.Configuration;
if (nl != null)
{
if (nl.Variables.ContainsKey("logLevel"))
{
Console.WriteLine(nl.Variables["logLevel"]);
}
}
** Updated Answer **
NLog ver. 4.6 added support for using NLog-Config-Variables in minLevel. See https://github.com/NLog/NLog/pull/2709
NLog ver. 4.6.7 added support for adjusting minLevel at runtime, by modifying NLog-Config-Variables and calling ReconfigExistingLoggers(). See https://github.com/NLog/NLog/pull/3184
** Original Answer **
Unfortunately you can't use layout renderers (the ${...}) in the <logger> attributes like minLevel, level, etc
There are two options:
Use filters
<logger name="*" writeTo="LogFile, Wcf">
<filters>
<when condition="(level < ${logLevel})" action="Ignore"/>
</filters>
</logger>
Downsides:
less readable
hurt performance more compared to the minLevel attribute
Change the rules in code
var rule = config.LoggingRules[0];
// disable old levels, enable new
rule.DisableLoggingForLevel(LogLevel.Debug);
rule.DisableLoggingForLevel(LogLevel.Trace);
rule.EnableLoggingForLevels(LogLevel.Info, LogLevel.Fatal);
//apply config
LogManager.Configuration = config;
I had my variables in a config file as part of a Service Fabric application, which would vary by environment, and wanted these to override the values in my Nlog.config file.
As per the user above, I came up against the same problem with loglevel when I wished to set a minimum level for it. Rather than hardcoding the levels in the code, I created a variable to retrieve the value from my config file, along the lines of what the original user had done:
var config = context.CodePackageActivationContext.GetConfigurationPackageObject("Config");
ILoggerFactory logger = new LoggerFactory().AddNLog();
var nlogConfigSection = config.Settings.Sections["MyService_NlogSettings"];
I set the variables that could be set, such as connection string etc. using the GlobalDiagnosticsContext, but obviously couldn't set the loglevel this way, due to its dislike of variables!
So instead, I did the following:
LogManager.Configuration.LoggingRules[0].SetLoggingLevels((NLog.LogLevel.FromString(nlogConfigSection.Parameters["AzureNLogLevel"].Value)),
NLog.LogLevel.FromString("Fatal"));
The 'SetloggingLevels' method expects values for Minlevel and MaxLevel of logging, hence my Config value was the min, and I hardcoded "Fatal" as the max since I was after a replication of 'minLevel' type logging, although obviously this too could have been set in my config file.

How to check if extra property in log4net is empty or not

I am using extra property which has to be logged into database at the time of exception.
Please check at this link for extra property usage.
https://www.codeproject.com/articles/140911/log4net-tutorial
I want to add a check in webconfig if that property is not initialized do something otherwise if that property is initialized do something else.
How to do that?
From comment:
log4net.ThreadContext.Properties["Property1"] = someval; I am setting this property in some cases. But when I use %property{Property1} it displays values for cases which I have set. But for those cases where I have not specified values it logs (null) into database column. How to avoid null value and add blank space?
Use the NullText property.
Use this value to indicate a null has been encountered while outputting a string representation of an item.
The default value is (null). This value can be overridden by specifying a value for the log4net.NullText appSetting in the application's .config file.
You can set this in config:
<appSettings>
<add key="log4net.NullText" value="" />
</appSettings>
Or in code:
log4net.Util.SystemInfo.NullText = string.Empty;
Note that if you are using an old version of log4net then the value has to be a single space rather than empty.

Double call to action - prettyfaces - jsf

I am making a page in which I call a PrettyFaces page-load action method:
<url-mapping id="informes-perfil">
<pattern value="/informes/#{informesPerfilMB.codigo}" />
<view-id value="/faces/informes_perfil.xhtml" />
<action onPostback="false">#{informesPerfilMB.load()}</action>
</url-mapping>
For some reason, the informesPerfilMB.load() action is called twice, and the parameter value in the second call is 'null' or 'RES_NOT_FOUND'.
Here is my load method:
public void load() {
if (isPostBack) {
isPostBack = false;
try {
System.out.println(codigo);
informe = informeEJBServiceLocal.getByCodigo(codigo);
this.buscarInformeIngreso();
this.buscarInformeOtroIngreso();
} catch (EJBServiceException e) {
e.printStackTrace();
}
}
}
The isPostBack variable is initialized to false, so this should prevent the method from being called again, but for some reason it is.
This code first prints String: dcc509a6f75849b.
Then when the load is repeated, it prints this: RES_NOT_FOUND
I hope this code helps explain what is happening enough to solve my problem, Thanks.
I've seen this happen on my similar system in the past. I think it's an interaction between faces and prettyfaces with missing files. The RES_NOT_FOUND part comes from the network traffic. There's some likely faces resource (or stylesheet) that it's trying to find in libraries and when it can't, it essentially causes the browser to go to the URL /informes/RES_NOT_FOUND. For some reason, it would often find that resource if I refreshed the page and wouldn't issue a RES_NOT_FOUND URL.
First, I'd open up the page source, and you'll find RES_NOT_FOUND, likely along with the stylesheets. Given the position of it, you might be able to correlate it to the resources loaded in your xhtml files and see which one's missing. If that doesn't help, try the developer tools and see which resources are loaded and which are not. Then make sure the resource is present, deployed, and is in the correct location.
If it's not something that you can control (like a library resource), you can always make sure your setCodigo function ignores values of "RES_NOT_FOUND".
public void setCodigo(String value) {
if (!"RES_NOT_FOUND".equals(value)) {
this.codigo = value;
}
}
You may be able to modify your security or servlet-mapping settings (in WEB.XML) to prevent URLs ending in RES_NOT_FOUND from getting to the prettyfaces pages, but I don't know enough about it to do that.
First, the reason your isPostBack variable is called twice is most likely because you have two instances of the bean, not one singleton instance. There are a few reasons this could be happening:
Your bean is request scoped and multiple requests are being made to the page.
Your bean is being created multiple times by parts of your application that use it and call the load() method.
I also believe it is possible your method is being called twice because of the way you have written your EL expression (I'm not 100% sure):
<action onPostback="false">#{informesPerfilMB.load()}</action>
^^
Note the parenthesis at the end of your method expression. I believe this will force EL to evaluate the method when the expression is evaluated. Your method expression should look like this:
<action onPostback="false">#{informesPerfilMB.load}</action>
You should also check for other places in your application where this method might be called.
Please let me know if this helps.

Bean Autowiring problem

I am starter in mutithreading. I am trying to index my data into solr.For that I was writing the following code
I am getting null pointer exception in the line highlighted
You need to add the following:
<context:annotation-config/>
You need to set the path for autowiring package scan and in your case it will be:
<context:component-scan base-package="a.b.c" />
After it you need to mark the class as candidate for autowiring:
#Component("indexTask")
#Scope("prototype")
IndexTask implements Callable<IndexObject>
{
//ommited
}
Next you can remove indexTask bean configuration from xml file. your package will be created automatically.
Hope it helps.
Autowiring doesn't happen automatically, you need to configure it. See the Spring docs for detail, but essentially you need to add
<context:annotation-config/>

WIX - RegistrySearch returns wrong Installlocation

My WIX-installer shall check for a previously installed version of the software. If there is an older installation it shall be installed in the same path. I'm using RegistrySearch to perform this check.
<Property Id="TARGETDIR">
<RegistrySearch Id="InstallLocation" Root="HKLM" Key="SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\[ANYVERSION]" Name="InstallLocation" Type="directory" Win64="no" />
</Property>
where [ANYVERSION] is defined in
<Upgrade Id="MyGUID">
<UpgradeVersion Property="OLDVERSION" IncludeMinimum="yes" IncludeMaximum="no" Maximum="$(var.VERSION)" Minimum="0.0.0.0" OnlyDetect="no" />
<UpgradeVersion Property="NEWVERSION" IncludeMinimum="no" Minimum="$(var.VERSION)" Maximum="99.99.99.99" IncludeMaximum="no" OnlyDetect="yes" />
<UpgradeVersion Property="EQUALVERSION" IncludeMinimum="yes" Minimum="$(var.VERSION)" Maximum="$(var.VERSION)" IncludeMaximum="yes" OnlyDetect="yes" />
<UpgradeVersion Property="ANYVERSION" IncludeMinimum="yes" Minimum="0.0.0.0" Maximum="99.99.99.99" IncludeMaximum="yes" OnlyDetect="yes" />
</Upgrade>
My check works fine when there is already another version of my software installed.
When there is no earlier installation of my software, the checks works as well with one exception: when there is another application installed which writes an entry (with the name installLocation) without subnode (GUID) in HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall the check returns the installLocation of this application.
What is wrong in my check?
Why is RegistrySearch returning the installLocation of the an entry without a subnode?
Is there a possibility to make this work with registrySearch, or do I need to write my own CustomAction?
That's because ANYVERSION will be empty if none is found, and the path will then be evaluated to HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall.
One solution (not too elegant though) is to capture the registry search in another property, and only set the property that should contain your installation directory (TARGETDIR is probably not the correct choice here either) if ANYVERSION is defined, through a property settings custom action.

Resources