I am working on a new Asp.Net MVC project
and this time to have better control over the static contents of the application, I am planning to store all content as reusable properties in readonly static variables
. These values are not going to change throughout the application's lifecycle.
Example of usage:
I have created a class holding all messages in static variables so that if I want to change let's say, the default save message I can change it from here without having a need to change every occurrence in the project. This includes validation messages also. (numbers could grow rapidly, depending upon the size of the project)
Other usages: To store all application-related properties such as version, title, keys, and many more. I am also planning to store the button texts and other UI controls-related properties so that they can be easily customized, such as I don't know maybe CSS classes.
And not to mention, apart from the above I also have a number of static classes such as Data Access Helpers and Utility Functions with some static methods.
Sample Class:
public static class Messages
{
public static class Response
{
public readonly static string SUCCESS = "Process completed successfully";
public readonly static string FAILED = "Process failed";
public readonly static string ERROR = "Some error occured";
public readonly static string OPRNOTPERFORMED = "Operation aborted/failed for some unknown reason. Please contact your administrator";
//LOGIN
public readonly static string USERNOTFOUND = "Invalid username or password";
public readonly static string USERINACTIVE = "User is not active. Please contact your administrator";
public readonly static string NOROLEDEFINED = "User does not have any valid authority to access the application. Please contact your administrator";
public readonly static string FORCELOGOUT = "You have been logged out. Please login again";
//MASTERS
public readonly static string NOSTATESFOUND = "No states found in database. please contact your administrator";
public readonly static string APPCHOICENOTFOUND = "Option not found in the database. Please contact your system administrator.";
//COMPANY
public readonly static string INVALIDCOMPANY = "Please sign out from the application and login again before performing further opreations";
}
public static class Description
{
//COMPANY
public readonly static string INVALIDCOMPANY = "Company value changed between 2 consiquent requests. This happens when you left the page idle for so long. Please login again before performing further operations.";
}
public static class Instructions
{
public readonly static string MANDATORY_FIELDS = "Fields marked with <i class='text-warning-dark fw-bold fs-6'>*</i> cannot be blank.";
}
}
As of now, these are all on paper only. I am willing to take this approach so that I can easily customize the text contents according to different clients' needs. But before that, I have a few doubts to clear.
- Does all static variables initialized and stored in memory as we run the web application?
- Does all static variables remain in memory throughout the lifecycle of the web application, irrespective of its usage in the current View?
- Does the compiler replace the occurrences of the static variable with its actual value at the time of converting the source code into bytecode? (I have seen this in java when I decompiled the class file, wherever I used the static variables, it is replaced with its actual value).
Another Example:
public class Select
{
private static readonly SelectListItem defaultChoice = new SelectListItem { Text = "Select", Value = "" };
public static readonly IEnumerable<SelectListItem> ISACTIVE = new List<SelectListItem>
{
new SelectListItem {Text = "Active", Value = "true"},
new SelectListItem {Text = "Inactive", Value = "false"}
};
private static IList<SelectListItem> STATES;
public static IEnumerable<SelectListItem> GetStates(string sessionHash)
{
if (sessionHash == null)
{
return null;
}
if (STATES == null)
{
StateService stateService = new StateService(sessionHash);
ProcessResponse response = stateService.GetStates();
IList<StateModel> statesModel = (IList<StateModel>)response.Data[0];
STATES = new List<SelectListItem>();
STATES.Add(defaultChoice);
foreach (StateModel state in statesModel)
{
STATES.Add(new SelectListItem { Text = state.Name, Value = state.StateId.ToString() });
}
}
return STATES;
}
public static IEnumerable<SelectListItem> AppChoices(IList<AppChoicesModel> choicesModel)
{
IList<SelectListItem> choices = new List<SelectListItem>();
choices.Add(defaultChoice);
if (choicesModel != null && choicesModel.Count > 0)
{
foreach(AppChoicesModel choice in choicesModel)
{
choices.Add(new SelectListItem { Text = choice.Text, Value = choice.Value });
}
}
return choices;
}
}
Usage in View
@model Cygnus.View.Models.Company.CompanyBranch
@using Cygnus.Data.Constants
@{
Layout = "~/Views/Shared/_LayoutDashboard.cshtml";
ViewBag.Title = Titles.Company.BRANCHT;
ViewBag.SubTitle = Titles.Company.BRANCHST;
var moduleName = Routes.Company.BRANCH;
var isActive = Select.ISACTIVE;
var states = Select.GetStates(Session[Codes.SessionParams.HASH].ToString());
Html.RenderPartial(Routes.Commons.PROCRESPONSE);
}
<div class="container-fluid">
<div class="row">
<!-- left column -->
<div id="@string.Format("{0}Form_Container", @moduleName)" class="col-md-7 mt-1 collapse show">
<!-- general form elements -->
<div class="card card-info">
<div class="card-header">
<h3 class="card-title">@ViewBag.SubTitle</h3>
</div>
<!-- /.card-header -->
<!-- form start -->
@using (Html.BeginForm(moduleName, Routes.Company.CONTROLLER, FormMethod.Post, new { @name = moduleName }))
{
@Html.HiddenFor(model => model.CompanyId)
@Html.HiddenFor(model => model.CompanyBranchId)
@Html.AntiForgeryToken()
<div class="card-body">
<div class="row gx-3">
<div class="col-10">
<i class="fas fa-info-circle text-info mr-2"></i>@Html.Raw(@Messages.Instructions.MANDATORY_FIELDS)
</div>
<div class="col-2">
<button class="btn btn-block btn-info btn-flat size-width-auto float-right" value="@Codes.ButtonValue.ADD" name="@Codes.ButtonGroupName.ACTION" ><i class="fas fa-plus-square fa-1xl align-middle mr-2"></i><span class="align-middle">@Codes.ButtonValue.NEW</span></button>
</div>
</div>
<div class="row gx-3 mt-3">
<div class="input-group-sm col">
<label for="Name" class="fw-semibold">@Html.DisplayNameFor(model => model.Name)</label>
@Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control input-required", @placeholder = "Branch Name" } })
@Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger fs-6-5" })
</div>
<div class="input-group-sm col-4">
<label for="Code" class="fw-semibold">@Html.DisplayNameFor(model => model.Code)</label>
@Html.EditorFor(model => model.Code, new { htmlAttributes = new { @class = "form-control input-required", @placeholder = "Branch Code" } })
@Html.ValidationMessageFor(model => model.Code, "", new { @class = "text-danger fs-6-5" })
</div>
</div>
<div class="row gx-3 mt-5px">
<div class="input-group-sm col">
<label for="State" class="fw-semibold">@Html.DisplayNameFor(model => model.State)</label>
@Html.DropDownListFor(model => model.State, states, new { @class = "form-control input-required" })
@Html.ValidationMessageFor(model => model.State, "", new { @class = "text-danger fs-6-5" })
</div>
<div class="input-group-sm col-2">
<label for="Pincode" class="fw-semibold">@Html.DisplayNameFor(model => model.Pincode)</label>
@Html.EditorFor(model => model.Pincode, new { htmlAttributes = new { @class = "form-control input-required", @placeholder = "Pincode" } })
@Html.ValidationMessageFor(model => model.Pincode, "", new { @class = "text-danger fs-6-5" })
</div>
<div class="input-group-sm col">
<label for="BranchType" class="fw-semibold">@Html.DisplayNameFor(model => model.BranchType)</label>
@Html.DropDownListFor(model => model.BranchType, Model.BranchTypeList, new { @class = "form-control input-required" })
@Html.ValidationMessageFor(model => model.BranchType, "", new { @class = "text-danger fs-6-5" })
</div>
</div>
<div class="row gx-3 mt-5px">
<div class="input-group-sm col">
<label for="IsActive" class="fw-semibold">@Html.DisplayNameFor(model => model.IsActive)</label>
@Html.DropDownListFor(model => model.IsActive, isActive, new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.IsActive, "", new { @class = "text-danger fs-6-5" })
</div>
</div>
</div>
<!-- /.card-body -->
<div class="card-footer">
<button type="submit" value="@Codes.ButtonValue.SAVE" name="@Codes.ButtonGroupName.ACTION" class="btn btn-success px-5">@Codes.ButtonValue.SAVE</button>
<div>@Html.ValidationSummary(true, "", new { @class = "text-danger" })</div>
</div>
}
</div>
<!-- /.card -->
</div>
<div class="col-md mt-1">
@{
Html.RenderAction(Routes.Company.BRANCHLIST, Routes.Company.CONTROLLER);
}
</div>
</div>
</div>
@section Scripts {
@Scripts.Render("~/Scripts/Cygnus/Company.js")
<script>
$(function () {
var tableId = "#listOfCompanyBranch";
initDataTableWithDefaultToolbar(tableId, '@moduleName');
attachRowDataEvenOnATag(tableId);
});
function onRowClicked(rowData, row) {
let formElement = $("#@string.Format("{0}Form_Container",moduleName)");
if ($(formElement).is('.collapse:not(.show)'))
$(formElement).collapse("show");
document.getElementById("CompanyBranchId").value = $(row).attr("data-branch");
document.getElementById("CompanyId").value = $(row).attr("data-company");
FillFormControls(formArr["@moduleName"], rowData);
$("#IsActive").val((rowData[13]).toLocaleLowerCase());
}
</script>
}