I have a *.resx string that looks like this:
Failed to deserialize an object of type '{0}' from the following string:{1}{2}
This string is being used to log such kinds of errors and currently, the logging statement looks like this:
_logger.LogError(Resources.FailedToDeserialize, typeof(MyType).Name, Environment.NewLine, invalidJsonString);
As you can see - I need to pass Environment.NewLine each time to display my logs correctly for any OS.
I am curious are there any reserved string interpolation words/characters to insert such values?
For example, my string could look like this:
Failed to deserialize an object of type '{0}' from the following string:{NewLine}{2}
And my logging statement would be a bit simpler:
_logger.LogError(Resources.FailedToDeserialize, typeof(MyType).Name, invalidJsonString);
One thing you can do is some form of pre processing on application start up by reading the resource file, replacing your keyword of choice i.e {NewLine} with Environment.NewLine and then use that cached string for the entirety of your application life time.
You can make the fields readonly and do some reflection magic to set the value but this example should give you an idea of how to solve your current problem.
public static class LoggingMessageTemplates
{
//Reference your resource here e.g Resource.FailedToDeserialize
public static string FailedToDeserialize = "Resource.Something {NewLine} Something Else";
public static void FormatMessages()
{
var stringFields = typeof(LoggingMessageTemplates)
.GetFields()
.Where(x => x.FieldType == typeof(string));
foreach(var field in stringFields)
{
if (field.GetValue(null) is not string fieldValue)
{
throw new InvalidCastException($"Failed to cast field {field.Name} to string.");
}
field.SetValue(null, fieldValue.Replace("{NewLine}", Environment.NewLine));
}
}
}
//On application startup, format the resources to use the Environment.NewLine char of the current system.
LoggingMessageTemplates.FormatMessages();
//When logging, reference the LoggingMessageTemplates class rather than the direct resource.
Console.WriteLine(LoggingMessageTemplates.FailedToDeserialize);
//i.e
_logger.LogError(LoggingMessageTemplates.FailedToDeserialize, typeof(MyType).Name, invalidJsonString);
Related
I have properly overwrite commit in InstallerSetup.cs I do not wish to write the user entered value to app.config but rather I want to pass the string Context.Parameters["TESTPARAMETER"]; to another class in form1.cs on load function. I tried string test = InstallerSetup.Context.Parameters["TESTPARAMETER"];
but getting InstallerSetup.Context is null. Please Help.
InstallerSetup.cs
public static string SQLSERVERNAME = "";
public static string HMSTENANTDB;
public static string SQLLOGIN;
public static string SQLPASSWORD;
public override void Commit(IDictionary savedState)
{
base.Commit(savedState);
try
{
SQLSERVERNAME = Context.Parameters["SQLSERVERNAME"];
HMSTENANTDB = Context.Parameters["HMSTENANTDB"];
SQLLOGIN = Context.Parameters["SQLLOGIN"];
SQLPASSWORD = Context.Parameters["SQLPASSWORD"];
}
catch (Exception e)
{
MessageBox.Show("Failed to update the application configuration file : " + e.Message);
base.Rollback(savedState);
}
}
from1.cs
InstallerSetup InsSetup = new InstallerSetup();
string Vsqlserver = InsSetup.Installers.Count.ToString();
string Vtenant = "";
if (InsSetup.Context != null)
{
Vtenant = InsSetup.Context.Parameters["HMSTENANTDB"];
}
else
{
Vtenant = "context is null";
}
As far as I can tell, the issue is that the property values are not being passed into the custom action. That would be the most obvious explanation. A commentfrom the poster says:
"passed those parameters to the custom action...................................... SQLSERVERNAME = Context.Parameters["SQLSERVERNAME"];
etc...
//................there is only these 4 lines in my custom actions"
which is essentially repeating the code that was previously posted.
This is NOT passing the values into the custom action. This is retrieving values which must already have been passed into the custom action.
Assuming that the custom action has been correctly added to (typically) the install nod of the custom action, and also assuming that the property names are in a TextBoxes dialog in the install, the values must be passed in to the custom action via the CustomActionData settings. To use one example, the CustomActionData setting must be something like:
/SQLSERVERNAME=[SQLSERVERNAME]
or /SQLSERVERNAME=[EDITA1] if EDIOTA1 is being used because that's the default property name.
However there is no reference to the TextBoxes (or any other) install dialog in the original question, so it's not really clear where the value of (say) SQLSERVERNAME is supposed to come from. It may be passed in on the msiexec command line, for example.
I'm writing an app which converts keys to use resources from a RESX File. This code was working with local variables before:
public static void AnalyzeConstDeclaration(SyntaxNodeAnalysisContext context)
{
var fieldDeclaration = (FieldDeclarationSyntax)context.Node;
if (false == IsValidFieldDeclaration(context, fieldDeclaration))
{
return;
}
var firstVariable = fieldDeclaration.Declaration.Variables.FirstOrDefault();
var dataFlowAnalysis = context.SemanticModel.AnalyzeDataFlow(firstVariable);
var variableSymbol = context.SemanticModel.GetDeclaredSymbol(firstVariable);
if (dataFlowAnalysis.WrittenOutside.Contains(variableSymbol))
{
return;
}
var firstSymbol = context.SemanticModel.GetDeclaredSymbol(firstVariable);
context.ReportDiagnostic(Diagnostic.Create(Rule, context.Node.GetLocation(), firstSymbol.Name));
}
However when I try to get the dataFlowAnalysis I receive an error:
Additional information: statementOrExpression is not a StatementSyntax or an ExpressionSyntax.
How can Ideally just need to see if anyone has written to this variable outside of the declaration.
DataFlow works by analyzing order of execution within a single method.
It doesn't make sense for class-level fields.
Instead, you should use a simple syntax visitor (or SymbolFinder) to search the entire class for assignments to the field.
You'll probably also want to check whether it's ever passed as a ref parameter.
I'm doing a asp.net/c# project. Currently I have one web page with a label control lblData to display content from a string variable. Please look at the code block below:
string strData = "Data";
lblData.Text = strData;
When I run Parasoft tool to scan the project, I get result as below:
Security issue: Prevent exposure of sensitive data
Leakage of ToString() result via web control.
I think my code violated some standard security practice but I'm not sure how to fix it.
Really appreciate for your time and help.
Is this full code, or you have simplified your example?
I am asking because I was not able to get any violation on your example.
After modifying your example to something like:
protected void Foo(object o)
{
string strData = "Data" + o.ToString() ;
lblData.Text = strData;
}
I am getting following violation:
Violation: Leakage of ToString() result ("strData") via web control
To fix that violation you will need to validate exposed data, it is done by defining in rule configuration validating method and passing your data to that method(by default all methods with prefix 'validate' are treated as validating)
so if you modify your code to something like:
protected void Foo(object o)
{
string strData = "Data" + o.ToString() ;
validateStrData(strData);
lblData.Text = strData;
}
private void validateStrData(string strData)
{
//some validating logic
}
then violation should not be reported
Try this,
lblData.Text = strData.ToString();
I've created a dictionary like so:
public Dictionary<string, string> myValues = new Dictionary<string, string>();
Then in my start method I'm filling out my dictionary like so:
void Start()
{
myValues.Add("device one", "11111111111111");
}
And what I'm trying to do is check the value that I've created in my dictionary, in the above example it would be the 1111111111111, against a string value that is being read in remotely. The check I'm doing is this:
void Update ()
{
// Spawn a model based on the signal the ipad has recievied.
if( myValues["device one"] == outputContent.text)
{
Instantiate(model1, new Vector3(-2.5f, 3.0f,0), Quaternion.identity);
}
}
The message is getting parsed from a wrapper class that takes information from native ipad stuff and passes it direct to unity. The method for getting the message is this:
private void AppendString(string message)
{
outputContent.text += "\n" + message;
}
Now, the thing is, the message getting passed works. When I run my code, the screen gets filled with the information I want. But when I try to check the values I've stored against the ones getting sent in, nothing happens.
How I got my initial hard coded value was by first reading them in from the AppendString method. And I've double checked them to make sure I've got the correct information down.
Can someone please tell me if I'm comparing the values held within my dictionary, to those being read in, is correct?
There's a couple of 'suspicious' spots.
Here, you add \n, are you sure that's included in the dictionary's value?
outputContent.text += "\n" + message;
Also, make sure you compare the strings properly. It may even be a capitalization problem, something that's bitten me many times. Try for instance:
if(String.Equals(myValues["device one"], outputContent.text, StringComparison.OrdinalIgnoreCase)
better replace following line
if( myValues["device one"] == outputContent.text)
with:
if( myValues["device one"].Equals(outputContent.text))
I have a simple function GetPageName(String PageFileName, String LangCode) defined inside a class file. I call this function from default.aspx.cs file, In this function I am not able to use Response.Redirect("Error.aspx") to show user that error has been generated.
Below is example of Code
public static string GetPageName(String PageFileName, String LangCode)
{
String sLangCode = Request("Language");
String pgName = null;
if ( sLangCode.Length > 6)
{
Reponse.Redirect("Error.aspx?msg=Invalid Input");
}
else
{
try
{
String strSql = "SELECT* FROM Table";
Dataset ds = Dataprovider.Connect_SQL(strSql);
}
catch( Exception ex)
{
response.redirect("Error.aspx?msg="+ex.Message);
}
}
return pgName;
}
I have may function defined in Business and Datalayer where i want to trap the error and redirect user to the Error page.
HttpContext.Current.Response.Redirect("error.aspx");
to use it your assembly should reference System.Web.
For a start, in one place you're trying to use:
response.redirect(...);
which wouldn't work anyway - C# is case-sensitive.
But the bigger problem is that normally Response.Redirect uses the Page.Response property to get at the relevant HttpResponse. That isn't available when you're not in a page, of course.
Options:
Use HttpContext.Current.Response to get at the response for the current response for the executing thread
Pass it into the method as a parameter:
// Note: parameter names changed to follow .NET conventions
public static string GetPageName(String pageFileName, String langCode,
HttpResponse response)
{
...
response.Redirect(...);
}
(EDIT: As noted in comments, you also have a SQL Injection vulnerability. Please use parameterized SQL. Likewise showing exception messages directly to users can be a security vulnerability in itself...)