How to prevent static files opening without login in ASP.NET MVC

Hello,
If you are working on mvc application, and uploading pdf, images in your application than you have to prevent those files to open without login the application.
for this you have to use HttpHandler in MVC.

First you have to enable debug mode for static files from WebConfig, because static files route does not go in application pipeline.

Step 1 Enable runAllManagedModulesForAllRequests in webconfig and put Custom httphandler in


<system.webServer>
....
 <modules runAllManagedModulesForAllRequests="true" />
    <handlers>
      <add name="PDF" path="*.pdf" verb="GET" type="ApplicationNameSpace.FileProtectionHandler" resourceType="File" />
      <add name="JPG" path="*.jpg" verb="GET" type="ApplicationNameSpace.FileProtectionHandler" resourceType="File" />
      <add name="PNG" path="*.png" verb="GET" type="ApplicationNameSpace.FileProtectionHandler" resourceType="File" />
      <add name="BMP" path="*.bmp" verb="GET" type="ApplicationNameSpace.FileProtectionHandler" resourceType="File" />
    </handlers>
....
</system.webServer>

Step 2 : Create Custom HttpHandler in RouteConfig file, You can create a separate class instead in App_Start folder.
Here is Complete route.config

Here you have to implement 2 interfaces IHttpHandler and IRequiresSessionState.

namespace ApplicationNamespace
{
 public class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");


            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Account", action = "Login", id = UrlParameter.Optional }
            );
        }
    }


    public class FileProtectionHandler : IHttpHandler, IRequiresSessionState
    {
        public bool IsReusable { get { return true; } }

        public void ProcessRequest(HttpContext context)
        {
            switch (context.Request.HttpMethod)
            {
                case "GET":
                    {
                        if (SessionHelpers.Userid != 0) // if Application is Login
                        {
                            string requestedFile = context.Server.MapPath(context.Request.FilePath);

                            SendContentTypeAndFile(context, requestedFile);
                        }
                        else
                        {
                            if (context.Request.FilePath.Contains("LoginPageLogo")) //it used for login page logo
                            {
                                string requestedFile = context.Server.MapPath(context.Request.FilePath);
                                SendContentTypeAndFile(context, requestedFile);
                            }
                            else
                            {
                                context.Response.Redirect("~/Account/Login");
                            }
                        }
                        break;
                    }
            }

        }

        private HttpContext SendContentTypeAndFile(HttpContext context, String strFile)
        {
            context.Response.ContentType = GetContentType(strFile);
            context.Response.TransmitFile(strFile);
            context.Response.End();
            return context;
        }
        private string GetContentType(string filename)
        {
            // used to set the encoding for the reponse stream
            string res = null;
            FileInfo fileinfo = new FileInfo(filename);
            if (fileinfo.Exists)
            {
                switch (fileinfo.Extension.Remove(0, 1).ToLower())
                {
                    case "pdf":
                        {
                            res = "application/pdf";
                            break;
                        }
                }
                return res;
            }
            return null;
        }
    }
}

Here we are handling appplication login trough Session, if there is session Userid that we saved on Login Time, if it is found than file will out through response.
You have to use those methods SendContentTypeAndFile and GetContentType for file out response.

How to pass dictionary from JQuery Ajax to C# MVC Model

We have a model class in mvc c#, that also contains a dictionary property, and we want to pass data in this dictionary from jquery ajax.

Here we go,
We have a Model Class

 public class ModelClass
    {
      
        private Dictionary<string, string> _parameter= new Dictionary<string, string>();
        public Dictionary<string, string> Parameter{ get { return _parameter; } set { _parameter= value; } }
    }

And Here is Ajax and jquery code to send the dictionary as parameter


var parameter = [];
            parameter.push({ "key": "FromDate", "value": $('#FromDate').val() });
            parameter.push({ "key": "ToDate", "value": $('#ToDate').val() });
            
            var jsonParameters = { "Parameter": parameter };

            $.ajax({
                type: "POST",
                url: '@Url.Action("Home","Index")',
                contentType: 'application/json',
                data: JSON.stringify({ ModelClass: jsonParameters }),
                success: function (data) {
                    
                },
                error: function () {
                    alert('error');
                }
            })


And Here is controller that will accept parameters in ModelClass


public class HomeController : Controller
    {
       public ActionResult Index(ModelClass model) // Here You will get Dictionary as parameter
        {
            return View();
        }
    }

Error log in catch block write Exception Detail in C#

This method helps you to trace or keeping log of your exception in a text file with a formatted manner. Just use as extension method and pass object of you Catch Exception obj.

 

public class ErrorLog
{
 public static void WriteError(Exception ex)
 {
  string err = "";
  try
  {

   string path = System.AppDomain.CurrentDomain.BaseDirectory + "/ErrorLog/" + 
   DateTime.Today.ToString("dd-MM-yy") + ".txt";

   if (!File.Exists(path))
   {
    File.Create(path).Close();
   }
  using (StreamWriter w = File.AppendText(path))
  {
    w.WriteLine("\r\nLog Entry : ");
    w.WriteLine("{0}", DateTime.Now.ToString(CultureInfo.InvariantCulture));
    err = "Error Log at : " + ex.ToString() + "___. Error Message:" + ex.StackTrace;
    w.WriteLine(err);
    w.WriteLine("________________________________________________");
    w.Flush();
    w.Close();
  }
 }
    catch (Exception ex1)
    {
       return;
     }
  }
}


And you can use this extension method anywhere in catch block with class name.


try
{
  //your Code
}
catch(Exception ex)
{
  ErrorLog.WriteError(ex);
}

 

Highlight the tab according to action and controller in asp.net MVC

In Menu bar, while navigating, “Active” class will add in menu item according to your controller and action, that is fixed by you in your html code.

Just use this extension method in your menu item class.

 

public static string IsActive(this HtmlHelper html,
                                      string control,
                                      string action)
        {
            var routeData = html.ViewContext.RouteData;

            var routeAction = (string)routeData.Values["action"];
            var routeControl = (string)routeData.Values["controller"];

            // both must match
            var returnActive = control == routeControl &&
                               action == routeAction;

            return returnActive ? "active" : ""; //Here you can change class name according to your theme like "active" or anything
        }

Now you have to use this method as HTML helper in your razor page.



<li class="@Html.IsActive("About","Index")">
 <a href="@Url.Action("Index","About")">About Us</a>
</li>

                       
                        
 
<li class="@Html.IsActive("Contact","Index")">
 <a href="@Url.Action("Index","Contact")">Contact Us</a>
 </li>


Now if your controller and action will “About” and “Index” then “active” named class will add in you li class.

Multiple email validations in multiple text boxes with comma separate email ids in Javascript

Before Form submit, if you have multiple text boxes for emails like To Email and Cc Email, and both text boxes having multiple email ids with comma separate, then before form submit you can add validation through JQuery or java script.

 

<!DOCTYPE html>
<html>
<body>

<form>
To Email: <textarea name=”ToEmail” id=”ToEmail”></textarea><br>
CC Email: <textarea name=”CCEmail” id=”CCEmail”></textarea><br>
<input type=”submit” value=”Submit”>
</form>
</body>
</html>

 


$('form').submit(function () {
        var ToEmail = $('#ToEmail').val();
        var CCEmail = $('#CCEmail').val();
        var validArray = [];
        var emails = ToEmail.replace(/\s/g, '').split(",");
        Array.prototype.push.apply(emails, CCEmail.replace(/\s/g, '').split(","));
        var valid = true;
        var regex = /^(([^&amp;amp;lt;&amp;amp;gt;()[\]\\.,;:\s@\"]+(\.[^&amp;amp;lt;&amp;amp;gt;()[\]\\.,;:\s@\"]+)*)|(\".+\"))@@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;

        for (var i = 0; i &amp;amp;lt; emails.length; i++) {
            if (emails[i] == "" || !regex.test(emails[i])) {
                valid = false;
            }
            validArray.push(valid);
        }
        var isFalse = validArray.includes(false);
        if (isFalse == true) {
alert("Please enter emails in proper format !");
            return false;
        }
        else {
            return true;
        }
    });

Now Here an array will store comma separate email ids of first text box and then same array will append the more email ids from another text box, for this we have used :


Array.prototype.push.apply(emails, CCEmail.replace(/\s/g, '').split(","));

Above line of code will append second text box email ids into array, that already having values of first textbox.(email)

Note:- If you are working on ASP.NET MVC Razor then in Regex Expression you have to replace @ to @@, because @ will determine as razor syntex.

Editable Text Box In Jquery And Post Data to ASP.NET

 

Here i have a grid, and in grid i have a column with Quanity, so if i want to change this quantity with editable text box.

so Here will be Link tag and text box with some id and selectors.

And this will work if there will multiple editable textboxes are there in table grid.

Here First HTML Code

<a href="JavaScript:Void(0);" id="editqty">@item.Qty</a>
<input type="text" style="width:70px;display:none;" class="form-control" id="qtyValue" value="@item.Qty" data-value="@item.PKId" data-target="@item.Qty" />

So above is html code and only <a> tag will be shown on grid, and when you will click on Link then it will hide and text box will show.
In this jquery code all other text box in grid and all things will be same as previous.
Below is jquery code
$("a[id$='editqty']").each(function () {
$(this).on('click', function () {
$("input[type='text'][id$='qtyValue']").hide();
$("a[id$='editqty']").show();
$(this).next('input[type=text]').show();
$(this).next('input[type=text]').val($(this).html());
$(this).hide();
});
});

$("input[type='text'][id$='qtyValue']").blur(function () {

$(this).prev("a[id$='editqty']").show();
$(this).hide();

var prevValue = $(this).attr('data-target');
var savedValue = $(this).val().trim();
var id = $(this).attr('data-value');

if (prevValue != savedValue)

{

$.ajax({
cache: false,
type: "POST",
url: '@Url.Action("Index","Employee")',
data: { savedValue: savedValue, id: id },
success: function (data) {
alert(data);
},
error: function (xhr, ajaxOptions, thrownError) {
if (xhr.status == 401) {
window.location.href =  "Account/Login/";
}
}
});

}

}

Convert List or any type of object to XML string data in C#

Here is a method to conver any type of object to string xml, this method will take parameters of T type and will return XML string.

public static string ConvertToXML<T>(T obj)
        {
            try
            {

                using (StringWriter stringWriter = new StringWriter(new StringBuilder()))
                {
                    System.Xml.Serialization.XmlSerializer xmlSerializer = new System.Xml.Serialization.XmlSerializer(typeof(T));
                    xmlSerializer.Serialize(stringWriter, obj);
                    XDocument xDoc = XDocument.Parse(stringWriter.ToString());
                    xDoc.Declaration = null;
                    return xDoc.ToString();
                }

            }
            catch (Exception ex)
            {
                return ex;
            }
        }

XML Data Insert,Update with MERGE in sql server

First of all you have to select XML data into a temptable, that will use as SOURCE table in merger statement.

SELECT
		ISNULL(x.v.value('Id[1]', 'int'), '') AS Id,
		ISNULL(x.v.value('Name[1]', 'bit'), '') AS Name,
		ISNULL(x.v.value('Address[1]', 'bit'), '') AS Address,
		ISNULL(x.v.value('Status[1]', 'nvarchar(max)'), '') AS Status,
		ISNULL(x.v.value('MoNumber[1]', 'nvarchar(max)'), '') AS MoNumber,
		ISNULL(x.v.value('Location[1]', 'nvarchar(max)'), '') AS Location,
		ISNULL(x.v.value('Email[1]', 'nvarchar(max)'), '') AS Email
		INTO #TempData
	FROM @XMLData.nodes('/ArrayOfEmployeeAccessModel/EmployeeModel') x (v);

And then you can user MERGER Statement to insert or update according to condition.

MERGE tbl_UpdatedEmployee AS TARGET
		USING #TempData AS SOURCE 
		ON (
		TARGET.PKId = SOURCE.Id 
		) 
		WHEN MATCHED  THEN 
		UPDATE 
		SET TARGET.Name = SOURCE.Name,
                    TARGET.Address= SOURCE.Address,
			
		WHEN NOT MATCHED BY TARGET THEN 
		INSERT (Name,Address,Status,MoNumber,Location,Email) 
		VALUES (SOURCE.Name,SOURCE.Address,SOURCE.Status,SOURCE.MoNumber,SOURCE.Location,SOURCE.Email)
		
Also if you want to get INSERTED or UPDATED rows or data than you can get as resultset, but for this first of all you have to declare a table variable on top then you can get output as table and return as resultset.
DECLARE @output TABLE (Id int,Email VARCHAR(50),Password NVARCHAR(10))
 In Above statement you can declare the columns name which you want to take as output columns, above defined a table variable.
 And now you have to add a statement at the last of merge statement, and you have to put ; (semicolon) at last of OUTPUT data statement.

MERGE tbl_UpdatedEmployee AS TARGET
		USING #TempData AS SOURCE 
		ON (
		TARGET.PKId = SOURCE.Id 
		) 
		WHEN MATCHED  THEN 
		UPDATE 
		SET TARGET.Name = SOURCE.Name,
                    TARGET.Address= SOURCE.Address,
			
		WHEN NOT MATCHED BY TARGET THEN 
		INSERT (Name,Address,Status,MoNumber,Location,Email) 
		VALUES (SOURCE.Name,SOURCE.Address,SOURCE.Status,SOURCE.MoNumber,SOURCE.Location,SOURCE.Email)

               OUTPUT INSERTED.Id,INSERTED.Address,INSERTED.Status INTO @output;
And now you can select your table variable as resultset.
SELECT * FROM @output

For More Detail about MERGE Visit Microsoft MSDN Weblink
Link

Get Enum Description According to language culture or resource file in C#

if i have an enum and i want to show the description on view or in dropdown than, than we can change the description according to resource language file.

Full example below:

We have an Enum First

public enum MeetingType
        {
            [Description("Booked Meeting")]
            APPOINTMENTBOOKED = 1,
            [Description("Prescription Bookings")]
            MEETINGWITHPRESCRIPTIONRENEWAL = 2,
            [Description("Prescription Renewal")]
            PRESCRIPTIONRENEWAL = 3
        }

And then we will add these description strings in our resource files.

After Adding strings or key in resource file we have created a extension method for further use.

First import

using System.Resources;

public static string GetDisplayName(this Enum e)
        {
            var rm = new ResourceManager(typeof(DoctorPanel.Resources.Resource));
            var resourceDisplayName = rm.GetString(ExtensionMethod.EnumDescription(e).Replace(" ",string.Empty));

            return string.IsNullOrWhiteSpace(resourceDisplayName) ? string.Format("[[{0}]]", e) : resourceDisplayName;
        }

And use this method where you want to get enum description according to resource or language wise.

var GetString=YourEnum.GetDisplayName();

we used white space remover because, Resource file keys accept without spaces or you can write your enum description without spaces.