How to read connection strings stored in appsettings file C#

This post is based on a setup of an asp.net core application. Configuration is read in the Startup class upon the Application startup. The Configure method in this class calls the ApiBootstrapper to check whether the connection string for Dev or Production is required.
This can be further used to call the Stored Procedures or query tables using ADO.Net.

Appsettings.json file is the asp.net core config file and is automatically read out. This file contains the Connection Strings is as shown below:

{
	"configSetting": {
		"ConnectionStrings": {
			"ProdConnection": "Data Source=ServerName;Initial Catalog=DBProd;UID=username;PWD=password;",
			"DevConnection": "Data Source=ServerName;Initial Catalog=DBDev;UID=username;PWD=password;"
		},
		"Parameters": {
			"IsProduction": true
			"IsDev": false
		}
	}
}
public class Startup
{
        public IConfiguration Configuration { get; }

	public Startup(IConfiguration configuration)
	{
		Configuration = configuration;
	}	
	
	public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
	{
		////
	
	
		ApiBootstrapper.Initialize(Configuration);
	}
	
}

Below is the code for ApiBootstrapper class:

public class ApiBootstrapper
{
	
	public static void Initialize(IConfiguration configuration)
	{
		CommonUtil.IsProduction = configuration.GetSection(ConfigKeys.configSetting.ToString()).GetSection(ConfigKeys.Log.ToString()).Value.ToString();
		if (Convert.ToBoolean(CommonUtil.IsProduction))
		{
			CommonUtil.ConnectionString = configuration.GetSection("configSetting").GetSection("ConnectionStrings").GetSection("ProdConnection").Value.ToString();
		}
	}
}

The above example shows how we can store Connection Strings for different environments like Dev and Prod and read it based on Config file settings.

If you’re simply using ConnectionStrings section in your appSettings.json file as below:

"ConnectionStrings": {
			"DefaultConnection": "...",
			"AnotherConnection": "..."
		}

The StartUp class will still have the IConfiguration Dependency Injection:

public class Startup
{
	public IConfiguration Configuration { get; }
	
	public Startup(IConfiguration configuration)
	{
		Configuration = configuration;
	}

	//...
}

If you’ve configured e.g. EFCore in your Application and need to refer the DefaultConnection while registering the Service for DBContext, you can do as follows:

public void ConfigureServices(IServiceCollection services)
{
	services.AddDbContext<AppDbContext>(options => 
		options.UseSqlServer(Configuration.GetConnectionStrings("DefaultConnection")));
		
	//...
}

When Configuration.GetConnectionStrings is called here, it will automatically search read the ConnectionStrings form appSettings and search for DefaultConnection.

Managing Custom Errors with Asp.net

You never want your users to see that yellow screen which shows up when a run-time or design-time error occurs in Asp.Net. However, a developer might want to see the error which may help in finding out the issue.

We have the following Custom error modes in Asp.net that can be set in web.config file:

  • Off: shows the actual error on the screen for all users.
  • On: shows only the custom error page and not the error details to all users.
  • RemoteOnly: shows the error details only to the local users where the Application is running. But does not show it to the outside users.

We recently faced a scenario where one of our Asp.Net Application was returning 3xx series status code from IIS Server for non-existent pages. This was flagged as a possible Security flaw by the team.
e.g. https://abc.com/xyz.aspx

So, if the page xyz.aspx does not exist, the Server will return 404 status code by default.

The following CustomErrors setting by default will give 404 status code:

<customErrors mode="Off" defaultRedirect="Error.htm"/>

We have used CustomErrors in our Web.config file which by the default behaviour of Asp.Net will make the IIS send the following response…
• With status code 302: Found, which effectively means a redirect
• Having a Location response header where the resource should be requested (in this case, the generic error page).
In the end, because the generic error page is static and does not change, when that is requested over same session IIS may return the response 304: Not modified.

Asp.Net CustomErrors setting in Web.Config file:

<customErrors mode="On" defaultRedirect="Error.htm"/>

The below setting produces the same result:

<customErrors mode="On" defaultRedirect="Error.htm">
    <error statusCode="404" redirect="FileNotFound.htm" />
</customErrors>

Similarly, you can manage other status codes.

The default behaviour of Asp.Net returning 3xx series status codes is by design for redirect done by Custom Errors and could be a false Security alert.

Prevent form submission with Javascript button click

Suppose you have a html form and you need to prevent the submission of a form based on the input provided in a textbox.
The html input type should be “button” in this case.

<input type="button" value="Submit" onclick="checkInput();">

Below is the Javascript code that gets called on the button click:

function checkInput() {
	var form = document.getElementById('form1');
	var str = document.getElementById("txtBox").value; 
	if (str == "") {
		var r = confirm("Do you want to add the detail in the input box?");
		if (r == true) {
			document.getElementById("txtBox").focus();
		} else {
			form.submit();
		}
	}
	else {
		form.submit();
	}
}

The above code will submit the form if field is not blank. If the field is blank, focus gets set to the textbox field named “txtBox” when clicking on OK button. Clicking on Cancel will again submit the form.

Debug classic asp application hosted on IIS with Visual Studio

Some non .Net Applications like the ones written in classic ASP are required to be debugged in Visual Studio. Since these are not hosted on IIS Express, but on IIS, you need to identify the worker process running your machine or the Server and attach the w3wp.exe with the Debug tool in Visual Studio.

Enable Debugging under IIS classic ASP section as shown below:

Under the Debug menu in Visual Studio, select “Attach to Process”:

There may be multiple worker processes running on the machine depending on how many applications are running under IIS. Match the right one with the correct ProcessID.

Add the debug points in your Asp file and hit the required Page in the browser.

Change Javascript attribute for asp.net textbox using c#

Suppose we have the following asp.net textbox in a UserControl with the onfocusout javascript method that passes validation as 50000 characters.

<telerik:RadTextBox TextMode="MultiLine" ID="txtComments" onfocusout="return CheckLength(this, 50000);" Height="100px"  runat="server" CssClass="TextMulti" Width="99%" EnableSingleInputRendering="False">
</telerik:RadTextBox>

For a particular scenario, you may need to change the number of characters to say 6000.

This can be done dynamincally in the UserControl C# code as below:

txtComments.Attributes["onfocusout"] = "return CheckLength(this, 6000);";

Authorize WebAPI request with ActionFilterAttribute

Action filters let you use pre and post processing logic which can be applied globally, to an action method or Controller class. These are generally used for applying logic for logging, caching, authorization etc. which can be shared across Controllers.

For adding Authorization to a WebAPI, we can use ActionFilterAttributes to enable strict access for a particular role or user. The ActionFilterAttribute class below implements the authorization logic.

The base ActionFilterAttribute class has the following methods that you can override as per the MS documentation:

  • OnActionExecuting – This method is called before a controller action is executed.
  • OnActionExecuted – This method is called after a controller action is executed.
  • OnResultExecuting – This method is called before a controller action result is executed.
  • OnResultExecuted – This method is called after a controller action result is executed.

As an example, you have a class called TokenFilter that inherits from ActionFilterAttribute. This class overrides the following methods OnActionExecuting and OnActionExecuted as below:

public class TokenFilter : ActionFilterAttribute
{


	public override void OnActionExecuting(HttpActionContext actionContext)
	{
		try
		{
			if (CheckValidHeaders(actionContext))
			{
				var auth_token = actionContext.Request.Headers.GetValues("access-token").FirstOrDefault();
				
				var ValidateObj = MyUtils.ValidateToken(auth_token);
				if (!ValidateObj.IsAuthenticated)
				{
					var error = MyUtils.GetNotSignedInErrorMessage();
					var response = actionContext.Request.CreateResponse(System.Net.HttpStatusCode.Unauthorized, error);
					actionContext.Response = response;
				}
				else
				{
					if (!ValidateObj.IsDurationValid)
					{
						auth_token = MyUtils.GenerateToken(email);
						actionContext.Request.Headers.Remove("access-token");
						actionContext.Request.Headers.Add("access-token", auth_token);
					}

					HttpContext.Current.Items.Add("access-token", auth_token);
					
				}
			}
			else
			{
				var response = actionContext.Request.CreateResponse(System.Net.HttpStatusCode.Unauthorized, "error message");
				actionContext.Response = response;
			}
		}
		catch (Exception ex)
		{
			var response = actionContext.Request.CreateResponse(System.Net.HttpStatusCode.Unauthorized, "error message");
			actionContext.Response = response;
		}
	}

The above code OnActionExecuting will check for valid Headers in the request, Validates the auth token and also generates the token if required. The new auth token is again injected into the Request Headers.

The OnActionExecuted method is as below:

public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
    var auth_token = HttpContext.Current.Items["access-token"].ToString();
    actionExecutedContext.Response.Headers.Add("access-token", auth_token);
    var email = HttpContext.Current.Items["emailid"].ToString();
    actionExecutedContext.Response.Headers.Add("emailid", email);
}

Similary, other custom headers can be used to Authorize the request.

The below Authorize Filter class will authorize the user based on email id:

public class AuthorizeUserAttribute : ActionFilterAttribute
{
	bool IsinRole = false;
	public override void OnActionExecuting(HttpActionContext actionContext)
	{
		if (HttpContext.Current.Request.Headers["emailid"] != null)
		{
			var email = HttpContext.Current.Request.Headers["emailid"].ToString();
			 IsinRole = MyUtils.Checkroles(email, "admin");
			if(!IsinRole)
			{
				var response = actionContext.Request.CreateResponse(System.Net.HttpStatusCode.Unauthorized, "error message");
				actionContext.Response = response;
			}
		}

	}
}

The below controller will use the TokenFilter and AuthorizeUser attributes to use the Filter out Unauthorized users as below:

[TokenFilter]
[AuthorizeUser]
public class ValuesController : ApiController
{

}

So any Action method that gets called for this Controller, has to have a valid token and a valid role Authorized to access this Controller.


Get great detals on Mobile Phones at Alibaba.

Preserve newline characters in xml asp.net

While using a telerik text box in asp.net in multiline mode, I faced a weird issue where pressing enter was adding spaces and not new line. So, to fix that, I had to use the below css to add new line characters:

div.divTxtBox .txtBoxNewLineFix {
    width: 100% !important;
    white-space: pre !important;
}

RadTextBox aspx code:

<telerik:RadTextBox ID="txtDev"
	Wrap="true" TextMode="MultiLine" runat="server" Width="98%" CssClass="txtBoxNewLineFix" Rows="8">
</telerik:RadTextBox>

Also, while saving the text to the SQL Server database, since I was creating the XML in a C# string, the new line characters were getting replaced with new lines in the XML but it did not replicate in the saved text, so I had to preserve the \r\n characters as below:

private string preserveNewLine(string str)
{
	string sReturnValue;
	sReturnValue = str.Replace("\r\n", "
");

	return sReturnValue;
}

The below xml sample is prepared using StringBuilder in C#:

StringBuilder PlanData = new StringBuilder();
PlanData.AppendLine("<?xml version=\"1.0\" standalone=\"yes\" ?>");
PlanData.Append("<XMLInfo ");
PlanData.Append(" UserDataId=" + "\"" + UserDataId + "\"");
PlanData.Append(" UpdatedBy=" + "\"" + objUser.UserID + "\"");
PlanData.Append(" UpdatedOn=" + "\"" + DateTime.Now.ToString() + "\"");
PlanData.AppendLine(">");
PlanData.AppendLine("<Plans>");

//TO DO loop through data with following lines to add multiple Plan child elements:
Comments = preserveNewLine(Comments);
PlanData.AppendLine("<Plan ID=" + "\"" + ID + "\"" + " Comment=" + "\"" + Comments + "\"" + "/>");

PlanData.AppendLine("</Plans>");
PlanData.AppendLine("</XMLInfo>");

C# sample debug output with new lines converted:

{<?xml version="1.0" standalone="yes" ?>
<XMLInfo  UserDataId="7180" UpdatedBy="1898" UpdatedOn="10/10/2019 6:14:00 PM">
<Plans>
<Plan ID="38685" Comment="1 1111 11111 111111 1111111 11111111 1111   111111

test new line"/>
<Plan ID="38686" Comment="11  2222  2222222    222222      444"/>
}

C# sample debug output with new lines characters preserved:

{<?xml version="1.0" standalone="yes" ?>
<XMLInfo  UserDataId="7180" UpdatedBy="1898" UpdatedOn="10/10/2019 6:39:55 PM">
<Plans>
<Plan ID="38685" Comment="1 1111 11111 111111 1111111 11111111 1111   111111    

test new line"/>
}

So when this xml is saved to SQL Server and pulled back in the Text Box, the new lines will show up correctly.

CSS Media queries adjust to screen width in asp.net

I have two html tables in my Asp.net project, first one has normal html and 2nd one has a Repeater control. Due to some recent changes, it was difficult to align the width of the two tables. Also, I was facing issue on 2 different resolutions as below:

  1. 1920×1080 on my laptop.
  2. 1366×768 on my Desktop.

To solve this, I used the css media queries to cater to minimum width resolution of 1400px for MyTable and for above 1400px width resolution for OthersTable as shown below:

@media only screen and (max-width: 1400px) {
    .MyTable {
        width: 92%;
    }

    .OthersTable {
        width: 90%;
    }
}

@media only screen and (min-width: 1400px) {
    .MyTable {
        width: 90%;
    }

    .OthersTable {
        width: 90%;
    }
}

Media queries introduced in CSS3 let you include some properties only if certain condition is met. In the above case, I’m using screen-width as the condition. Below I’m using the class in my html tables as defined in the media queries in the aspx code.

<table id="divMyTable" visible="false" style="border-collapse: collapse;" class="MyTable" runat="server">
	<tr><td></td></tr>
</table/>			

<table id="divOthersTable" visible="false" style="border-collapse: collapse;" class="OthersTable" runat="server">
	<tr>
		<td></td>
	</tr>
</table>

Asp.net how to escape double quotes in text property aspx file

I recently had a facepalm moment when I experienced an issue with a text property of a user control in my aspx file that had a custom property that included double quotes. Double quotes confused the compiler and made it believe that the ID property of my user control used in cs file didn’t exist.

After wasting some time on the wrong problem, it came down to escaping the double quotes. Aspx files are like XML and need to be treated like one in the text property of attributes used in the form controls.

To escape a double quote you need to use quot; e.g.

HeaderText="This is a &quot;double quote&quot;"

will show up as below:

This is a “double quote”

Similarly for other such characters, use below ones:
 ampersand &   =>   &amp;
 single quotes '   =>   &apos;
 less than <   =>   &lt;
 greater than >   =>   &gt;