European ASP.NET MVC 4 and MVC 5 Hosting

BLOG about ASP.NET MVC 3, ASP.NET MVC 4, and ASP.NET MVC 5 Hosting and Its Technology - Dedicated to European Windows Hosting Customer

ASP.NET MVC 6 Hosting - HostForLIFE.eu :: ASP.NET MVC Request Life Cycle

clock March 12, 2019 09:39 by author Peter

If you have worked on ASP.NET MVC, you must be familiar with how when you type in an URL, the appropriate controller is chosen, and the action fired. Today we will dig a little deeper within the MVC request life cycle. Before we start discussing its life cycle, let's briefly understand the concept of HttpHandlers and HttpModules.

Handlers are responsible for generating the actual response in MVC. They implement the IHttpHandler class and only one handler will execute per request. On the other hand, HttpModules are created in response to life cycle events. Modules can, for example, be used for populating HttpContext objects. A request can use many modules. These classes derive from IHttpModule. We are now ready to learn about the MVC Request Life Cycle. The MVC life cycle can be briefly demonstrated as below,


When a request is fired for the first time, the Application_Start method in the Global.asax file is called. This method calls the RegisterRoutes method as below,
    public class MvcApplication : System.Web.HttpApplication 
        { 
            protected void Application_Start() 
            { 
                AreaRegistration.RegisterAllAreas(); 
                FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 
                RouteConfig.RegisterRoutes(RouteTable.Routes); 
                BundleConfig.RegisterBundles(BundleTable.Bundles); 
            } 
        } 



RegisterRoutes method stores the routes defined in that method, in a static collection in the Routetable class.
Each route has an HttpHandler defined for it. In our case above, the MapRoute method defines the HttpHandler.
Next, the URLRoutingModule is called. It matches the request route with the routes defined in the route table. It calls the GetHttpHandler method which returns an instance of an MVCHandler.

The MVCHandler calls the ProcessRequest method. The controller execution and initialization happens inside this method. ProcessRequest calls ProcessRequestInit, which uses ControllerFactory to select an appropriate controller based on the supplied route. The ControllerFactory calls the Controller Activator which uses the dependency resolver to create an instance of the controller class.

Once the controller is created its Execute method is called.

Now comes the point where the action must be executed. The execute method in the controller calls the ExecuteCore method which calls the InvokeAction method of ActionInvoker. Action Invoker determines which action must be selected based on certain conditions, depending upon the methods available, their names and the action selectors used for them.

Once the action is selected, Authentication & Authorization filters are fired next.
Once the action passes through the authentication and authorization filter checks, the model binding takes place. The information needed for the action to execute is gathered in this step.

OnActionExecuting action filters are fired next. Once the OnActionExecuting filters are executed a response for the action is generated. The thing to note here is that the response is generated at this stage, but not executed.

Next, the OnActionExecuted filters are executed.  Once all the filters have finished executing, the response is finally executed in the ExecuteResult method which is called from the InvokeActionResult by the ActionInvoker. If the response is a view or a partial view, the ViewEngine will render it, else it will be handled appropriately. The ExecuteResult will find the appropriate view using FindView or FindPartialView method. This method will search for the view in specific locations and then render it. This is the final step in generating the response.

If you would like to further dig into the MVC request life cycle, I would highly recommend Alex Wolf’s pluralsight course by the same name.

HostForLIFE.eu ASP.NET MVC 6 Hosting
HostForLIFE.eu is European Windows Hosting Provider which focuses on Windows Platform only. We deliver on-demand hosting solutions including Shared hosting, Reseller Hosting, Cloud Hosting, Dedicated Servers, and IT as a Service for companies of all sizes. We have customers from around the globe, spread across every continent. We serve the hosting needs of the business and professional, government and nonprofit, entertainment and personal use market segments.



ASP.NET MVC 6 Hosting - HostForLIFE.eu :: Create A Password Protected PDF In MVC

clock February 19, 2019 10:37 by author Peter
Sometimes, we need to create a PDF file that opens only when the users put in a password when prompted. Let us see how to create a password-protected PDF file in MVC.

First, let's open Visual Studio and create a new project. We need to select the ASP.NET Web application type.

Select Web API as the template and in the "Add folders and core references" section, we need to select MVC and Web API. Click on "Change Authentication" on the right side pane and select "No Authentication".

 

In the web.config file, let us define one key named Filepath and use it in our code. The PDF file must be present there.

It is good to change the key's value when it's placed in web.config.
<appSettings> 
     <add key="FilePath" value="Anil\PDF\LDEPRD9.pdf"/> 
 </appSettings> 


Add the below code to the Home Controller.
string FilePath = ConfigurationManager.AppSettings["FilePath"].ToString(); 
public ActionResult DownloadFile() 

    try 
    { 
        byte[] bytes = System.IO.File.ReadAllBytes(FilePath); 
        using (MemoryStream inputData = new MemoryStream(bytes)) 
        { 
        using (MemoryStream outputData = new MemoryStream()) 
        { 
        string PDFFilepassword = "123456"; 
        PdfReader reader = new PdfReader(inputData); 
        PdfReader.unethicalreading = true; 
PdfEncryptor.Encrypt(reader, outputData, true, PDFFilepassword, PDFFilepassword, PdfWriter.ALLOW_SCREENREADERS);
        bytes = outputData.ToArray(); 
        Response.AddHeader("content-length", bytes.Length.ToString()); 
        Response.BinaryWrite(bytes); 
        return File(bytes, "application/pdf"); 
       } 
      } 
    } 
    catch (Exception ex) 
    { 
        throw ex; 
    } 


string PDFFilepassword = "123456";   
PdfReader reader = new PdfReader(inputData);   
PdfReader.unethicalreading = true;   
PdfEncryptor.Encrypt(reader, outputData, true, PDFFilepassword, PDFFilepassword, PdfWriter.ALLOW_SCREENREADERS); 


In the PDFFilepassword variable, you can set anything as password - the file name, PAN card number, or you can validate the entered value against the values stored in the database.

In Route.config, we can define the default route with the Controller And ActionName.

Run the website and enter http://localhost:49744/Home/DownloadFile. 

Here, Home is the controller name and DownloadFile is the action name. 

It shows the following Password prompt.

 

After entering the right password and successful authentication, the PDF file will get opened.

HostForLIFE.eu ASP.NET MVC 6 Hosting
HostForLIFE.eu is European Windows Hosting Provider which focuses on Windows Platform only. We deliver on-demand hosting solutions including Shared hosting, Reseller Hosting, Cloud Hosting, Dedicated Servers, and IT as a Service for companies of all sizes. We have customers from around the globe, spread across every continent. We serve the hosting needs of the business and professional, government and nonprofit, entertainment and personal use market segments.



ASP.NET MVC 6 Hosting - HostForLIFE.eu :: Server Sent Events In ASP.NET MVC

clock February 15, 2019 08:14 by author Peter

In some Web Applications, we need to show real time data to the end users, which means if any changes occur (new data available) in the Server, it needs to show an end user. For instance, you are doing chat in Facebook in one tab of your Browser. You opened another tab in the same Browser and send a message to the same user (with whom, you are doing chat in the previous chat). You will see that message will appear in both the tabs and it is called real-time push.

In order to accomplish the functionality, mentioned above, the client sends interval basis AJAX requests to the Server to check, if the data is available or not. ServerSentEvents(SSE) API helps ensure the Server will push the data to the client when the data is available in the Server.

What are Server Sent Events?
SSE is an acronym and stands for Server Sent Events. It is available in HTML5 EventSource JavaScript API. It allows a Web page to get the updates from a Server when any changes occurs in the Server. It is mostly supported by the latest Browsers except Internet Explorer(IE).

Using code
We are going to implement a requirement like there is a link button and click on it and it displays current time each second on an interval basis.
In order to achieve the same, we need to add the following action in HomeController. It sets response content type as text/event-stream. Next, it loops over the date and flushes the data to the Browser.
    public void Message() 
    { 
        Response.ContentType = "text/event-stream"; 
     
        DateTime startDate = DateTime.Now; 
        while (startDate.AddMinutes(1) > DateTime.Now) 
        { 
            Response.Write(string.Format("data: {0}\n\n", DateTime.Now.ToString())); 
            Response.Flush(); 
     
            System.Threading.Thread.Sleep(1000); 
        } 
         
        Response.Close(); 
    }


Once we are done with the Server side implementation, it's time to add the code in the client side to receive the data from the Server and displays it.

First, it adds a href link, which calls initialize() method to implement SSE. Second, it declares a div, where the data will display. Thirdly, it implements Server Sent Events(SSE) through JavaScript with the steps, mentioned below.
    In the first step, it checks whether SSE is available in the Browser or not. If it is null, then it alerts to the end user to use other Browser.
    In the second step, if SSE is available, then it creates EventSource object with passing the URL as a parameter. Subsequently, it injects the events, mentioned below.

        onopen- It calls when the connection is opened to the Server
        onmessage- It calls when the Browser gets any message from the Server
        onclose- It calls when the Server closes the connection.

    <a href="javascript:initialize();" >Click Me To See Magic</a> 
    <div id="targetDiv"></div> 
     
    <script> 
         
        function initialize() { 
            alert("called"); 
     
            if (window.EventSource == undefined) { 
                // If not supported 
                document.getElementById('targetDiv').innerHTML = "Your browser doesn't support Server Sent Events."; 
                return; 
            } else { 
                var source = new EventSource('../Home/Message'); 
     
                source.onopen = function (event) { 
                    document.getElementById('targetDiv').innerHTML += 'Connection Opened.<br>'; 
                }; 
     
                source.onerror = function (event) { 
                    if (event.eventPhase == EventSource.CLOSED) { 
                        document.getElementById('targetDiv').innerHTML += 'Connection Closed.<br>'; 
                    } 
                }; 
     
                source.onmessage = function (event) { 
                    document.getElementById('targetDiv').innerHTML += event.data + '<br>'; 
                }; 
            } 
        } 
    </script>


Output

Here, we discussed about SSE(Server Sent Events). It is very important API available in HTML5. It helps to push data from the Server to the client when any changes occurs in the Server side. If you want to use a bidirectional communication channel, you can use HTML5 Web Sockets API. The disadvantage of SSE is it is Browser dependent. If the Browser doesn't support SSE, then the user can't see the data, but it is easy to use it. You can also use SignalR for realtime pushing the data to the end user.

HostForLIFE.eu ASP.NET MVC 6 Hosting
HostForLIFE.eu is European Windows Hosting Provider which focuses on Windows Platform only. We deliver on-demand hosting solutions including Shared hosting, Reseller Hosting, Cloud Hosting, Dedicated Servers, and IT as a Service for companies of all sizes. We have customers from around the globe, spread across every continent. We serve the hosting needs of the business and professional, government and nonprofit, entertainment and personal use market segments.

 



ASP.NET MVC 6 Hosting - HostForLIFE.eu :: Creating Cascading DropDownList In ASP.NET MVC

clock January 23, 2019 10:46 by author Peter

I have used Entity Framework to fetch the values and used Database First approach. I would also write an article on an Entity Framework but today, I would just show you how to bind the cascading dropdown list in this blog.

I have two dropdownlists. One is for state and the other for city. I would populate the city, which is based on the state selection. You can add as many dropdownlists, as you want. For simplicity, I am using only two dropdowns.

Create table scripts
tblState
    CREATE TABLE [dbo].[tblState]( 
        [stateid] [int] NOT NULL, 
        [statename] [nvarchar](50) NULL, 
    PRIMARY KEY CLUSTERED  
    ( 
        [stateid] ASC 
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
    ) ON [PRIMARY] 
     
    GO  

tblCity

    CREATE TABLE [dbo].[tblCity]( 
        [Cityid] [int] NOT NULL, 
        [CityName] [nvarchar](50) NULL, 
        [stateid] [int] NOT NULL 
    ) ON [PRIMARY] 
     
    GO 
     
    ALTER TABLE [dbo].[tblCity]  WITH CHECK ADD FOREIGN KEY([stateid]) 
    REFERENCES [dbo].[tblState] ([stateid]) 
    GO 
 

I have tblState and tblCity, where I have stateid as Primary key in the tblState table and stateid as the Foreign key in tblCity table. You can insert states and cities from the database as you wish.

Now, with Entity Framework; create your EDMX file. In my case, I have named it ModelDemo.edmx.

Model
I have created a Model and named it Registration. This is not directly required but since I used a strongly typed View, so I have created Model. You can also add Model because if you write the httppost method to save the values to the database, then you would need the model.
    public class Registration 
    { 
    [Required(ErrorMessage = "Enter State")] 
            public string State { get; set; } 
    [Required(ErrorMessage = "Enter City")] 
            public string City { get; set; } 
    }  


Controller
Now, this is my Controller code.
    [HttpGet] 
    public ActionResult Details() 
            { 
                bindState(); 
                return View(); 
            } 
    -------------------------------- 
    public void bindState() 
            { 
                var state = objEF.tblStates.ToList(); 
                List<SelectListItem> li = new List<SelectListItem>(); 
                li.Add(new SelectListItem { Text = "--Select State--", Value = "0" }); 
     
                foreach (var m in state) 
                { 
     
     
                    li.Add(new SelectListItem { Text = m.statename, Value = m.stateid.ToString() }); 
                    ViewBag.state = li; 
     
                } 
            } 
    ---------------------------------- 
    public JsonResult getCity(int id) 
            { 
                var ddlCity = objEF.tblCities.Where(x => x.stateid == id).ToList(); 
                List<SelectListItem> licities = new List<SelectListItem>(); 
     
                licities.Add(new SelectListItem { Text = "--Select State--", Value = "0" }); 
                if (ddlCity != null) 
                { 
                    foreach (var x in ddlCity) 
                    { 
                        licities.Add(new SelectListItem { Text = x.CityName, Value = x.Cityid.ToString() }); 
                    } 
                } 
                return Json(new SelectList(licities, "Value", "Text", JsonRequestBehavior.AllowGet)); 
            }  


Now, if you see my Controller code, I have a httpget method Details(). I am then calling a non-action method bindState() to bind the state ddl. On selection of the state ddl, the getCity() method will be called to bind the city ddl. I have used jQuery to get the Id of the selected item and have passed it to the getCity method to get the cites for the selected state.

I have also used LINQ to get my desired select value w.r.t the Id passed.

View
Right click on action method Details(), followed by clicking Add View. I always prefer a strongly typed View and I have also created a strongly typed View in this case. The name of my View is Details.cshtml.

You need jQuery min.js. Just download it from the NuGet Package, if it’s not there.

    <script src="~/Scripts/jquery-1.10.2.min.js"></script> 
    <script type="text/javascript"> 
         
        $(document).ready(function () { 
     
            $("#State").change(function () { 
                $("#City").empty(); 
                $.ajax({ 
                    type: 'POST', 
                    url: '@Url.Action("getcity")', 
                    dataType: 'json', 
                    data: { id: $("#State").val() }, 
                    success: function (city) { 
     
                        $.each(city, function (i, city) { 
                            $("#City").append('<option value="' 
                                                       + city.Value + '">' 
                                                 + city.Text + '</option>'); 
                        }); 
                    }, 
                    error: function (ex) { 
                        alert('Failed.' + ex); 
                    } 
                }); 
                return false; 
            }) 
        }); 
    </script>  


I have added the jQuery-min.js. From the code given above, we get the Id of the state ddl.

    <div class="form-group"> 
    @Html.LabelFor(model => model.State, htmlAttributes: new { @class = "control-label col-md-2" }) 
                <div class="col-md-10"> 
                    @Html.DropDownListFor(model => model.State, ViewBag.state as List<SelectListItem>, new { style = "width: 200px;" }) 
     
                    @Html.ValidationMessageFor(model => model.State, "", new { @class = "text-danger" }) 
                </div> 
            </div> 
     
            <div class="form-group"> 
     @Html.LabelFor(model => model.City, htmlAttributes: new { @class =     "control-label col-md-2" }) 
                <div class="col-md-10"> 
          @Html.DropDownListFor(model => model.City, new SelectList(string.Empty, "Value", "Text"), "--Select City--", new { style = "width:200px" }) 
     
                    @Html.ValidationMessageFor(model => model.City, "", new { @class = "text-danger" }) 
                </div>   


I have used jQuery to get the ID of the state DDL on .change function and passed it to bind the city ddl.

Now, just run your Application and you should get the output given below and if you do not get it, then check that if you are getting any values in an Id in getCity() method. If not, then check for Id mis-match.

HostForLIFE.eu ASP.NET MVC 6 Hosting
HostForLIFE.eu is European Windows Hosting Provider which focuses on Windows Platform only. We deliver on-demand hosting solutions including Shared hosting, Reseller Hosting, Cloud Hosting, Dedicated Servers, and IT as a Service for companies of all sizes. We have customers from around the globe, spread across every continent. We serve the hosting needs of the business and professional, government and nonprofit, entertainment and personal use market segments.

 



ASP.NET MVC 6 Hosting - HostForLIFE.eu :: How to Call Ajax Method Call with ASP.NET MVC?

clock January 8, 2019 11:41 by author Peter

In this tutorial, let me show you how to call ajax method in ASP.NET MVC.
Controller code here
    [HttpGet] 
    public JsonResult GetAjaxData(string newCode) { 
        return Json(new { 
            Status = "Ajax called succesfully", Message = "Message show succesfully" 
        }, JsonRequestBehavior.AllowGet); 
    } 

View Code Here

    @ { 
        ViewBag.Title = "Index"; 
    } < script src = "~/Scripts/jquery-1.8.2.js" > < /script> 
    <script> 
    function AjaxCall() 
    { 
    $.ajax({ 
    async: false, 
    url: $('#ajaxURL').val(), 
    type: 'GET', 
    cache: false, 
    data: { 
    newCode : "Put the data here" 
    }, 
    success: function (result) { 
    if(result.Status !=''){ 
    alert(result.Status); 
    } 
    else{ 
    alert('Ajax called failed'); 
    } 
    }, 
    error: function (result, textStatus, errorThrown) { 
    alert(errorThrown); 
    } 
    }) 
    } 
    </script > < div > < button value = "Ajax Called" 
    id = "btncalled" 
    onclick = "AjaxCall()" > Ajax Called < /button> 
    </div > @Html.Hidden("ajaxURL", Url.Action("GetAjaxData", "Demo")) 

App_Start-> route config.cs code here

    public static void RegisterRoutes(RouteCollection routes) { 
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 
        routes.MapRoute( 
        name: "Default", 
        url: "{controller}/{action}/{id}", 
        defaults: new { 
            controller = "Demo", action = "Index", id = UrlParameter.Optional 
        }); 
    } 


I hope it works for you! Good luck!

HostForLIFE.eu ASP.NET MVC 6 Hosting
HostForLIFE.eu is European Windows Hosting Provider which focuses on Windows Platform only. We deliver on-demand hosting solutions including Shared hosting, Reseller Hosting, Cloud Hosting, Dedicated Servers, and IT as a Service for companies of all sizes. We have customers from around the globe, spread across every continent. We serve the hosting needs of the business and professional, government and nonprofit, entertainment and personal use market segments.



ASP.NET MVC 5 Hosting - HostForLIFE.eu :: Limit Upload File Type Extensions Via Custom Data Annotation/Attribute

clock December 21, 2018 08:15 by author Peter

Restricting or limiting the file type extensions is a key business requirement. It is not necessary that a business allows all file types to be uploaded via their web application. Sometimes, only image files are accepted by the web application, sometimes only documents, and sometimes the combination of image, documents, and compressed file types are accepted by the web system.

Today, I shall be demonstrating the process of limiting/restricting the desired upload file type extensions by implementing custom data annotation/attribute component on ASP.NET MVC5 platform. This article is not specific to image files only, you can use the provided solution with any type of file format as well.

Following are some prerequisites before you proceed any further in this tutorial.

  • Knowledge of ASP.NET MVC5.
  • Knowledge of HTML.
  • Knowledge of Bootstrap.
  • Knowledge of C# Programming.

You can download the complete source code for this tutorial or you can follow the step by step discussion below. The sample code is being developed in Microsoft Visual Studio 2015 Enterprise.

Let's begin now.

Step 1

Create a new MVC web project and name it as "ImgExtLimit".

Step 2

You need to add/update the "executionTimeout", "maxRequestLength", and "maxAllowedContentLength" property values if not already added in the "Web.config" file, as shown below.
<system.web> 
  <authentication mode="None" /> 
  <compilation debug="true" targetFramework="4.5.2" /> 
  <!-- executionTimeout = 30hrs (the value is in seconds) and maxRequestLength = 1GB (the value is in Bytes) --> 
  <httpRuntime targetFramework="4.5.2" executionTimeout="108000" maxRequestLength="1073741824" /> 
</system.web>    
<system.webServer> 
  <!-- maxAllowedContentLength = 1GB (the value is in Bytes) -->     
  <security> 
    <requestFiltering> 
      <requestLimits maxAllowedContentLength="1073741824" /> 
    </requestFiltering> 
  </security>         
 
</system.webServer> 

 
executionTimeout -> Amount of time required to process your request on the web server. The value is provided in seconds.
maxRequestLength -> Maximum size which your request can capture and send to the web server. The value is provided in bytes.
maxAllowedContentLength -> Maximum allowed size of your content (e.g. file, text data etc.) that is sent to the web server. The value is provided in bytes.

Step 3
Open the "Views->Shared->_Layout.cshtml" file and replace the code with the following.
<!DOCTYPE html> 
<html> 
<head> 
    <meta charset="utf-8" /> 
    <meta name="viewport" content="width=device-width, initial-scale=1.0"> 
    <title>@ViewBag.Title</title> 
    @Styles.Render("~/Content/css") 
    @Scripts.Render("~/bundles/modernizr") 
 
    <!-- Font Awesome --> 
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css" /> 
 
</head> 
<body> 
    <div class="navbar navbar-inverse navbar-fixed-top"> 
        <div class="container"> 
            <div class="navbar-header"> 
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> 
                    <span class="icon-bar"></span> 
                    <span class="icon-bar"></span> 
                    <span class="icon-bar"></span> 
                </button> 
            </div> 
        </div> 
    </div> 
    <div class="container body-content"> 
        @RenderBody() 
        <hr /> 
        <footer> 
            <center> 
                <p><strong>Copyright © @DateTime.Now.Year - <a href="http://wwww.asmak9.com/">Asma's Blog</a>.</strong> All rights reserved.</p> 
            </center> 
        </footer> 
    </div> 
 
    @*Scripts*@ 
    @Scripts.Render("~/bundles/jquery") 
 
    @Scripts.Render("~/bundles/jqueryval") 
    @Scripts.Render("~/bundles/bootstrap") 
 
    @RenderSection("scripts", required: false) 
</body> 
</html>

In the above code, I have simply created a basic default layout page and linked the require libraries into it.

Step 4
Create a new "Helper_Code\Common\AllowExtensionsAttribute.cs" file and add the following code.
//----------------------------------------------------------------------- 
// <copyright file="AllowExtensionsAttribute.cs" company="None"> 
//     Copyright (c) Allow to distribute this code and utilize this code for personal or commercial purpose. 
// </copyright> 
// <author>Asma Khalid</author> 
//----------------------------------------------------------------------- 
 
namespace ImgExtLimit.Helper_Code.Common 

    using System; 
    using System.Collections.Generic; 
    using System.ComponentModel.DataAnnotations; 
    using System.Linq; 
    using System.Web; 
 
    /// <summary> 
    /// File extensions attribute class 
    /// </summary> 
    [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = true)] 
    public class AllowExtensionsAttribute : ValidationAttribute 
    { 
        #region Public / Protected Properties 
 
        /// <summary> 
        /// Gets or sets extensions property. 
        /// </summary> 
        public string Extensions { get; set; } = "png,jpg,jpeg,gif"; 
 
        #endregion 
 
        #region Is valid method 
 
        /// <summary> 
        /// Is valid method. 
        /// </summary> 
        /// <param name="value">Value parameter</param> 
        /// <returns>Returns - true is specify extension matches.</returns> 
        public override bool IsValid(object value) 
        { 
            // Initialization 
            HttpPostedFileBase file = value as HttpPostedFileBase; 
            bool isValid = true; 
 
            // Settings. 
            List<string> allowedExtensions = this.Extensions.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList(); 
 
            // Verification. 
            if (file != null) 
            { 
                // Initialization. 
                var fileName = file.FileName; 
 
                // Settings. 
                isValid = allowedExtensions.Any(y => fileName.EndsWith(y)); 
            } 
 
            // Info 
            return isValid; 
        } 
 
        #endregion 
    } 
}


In ASP.NET MVC 5, creating customized data annotations/attributes is one of the cool features. The ASP.NET MVC 5 platform already contains a default FileExtensions attribute, but, the issue with this pre-built data annotation/attribute is that it is applicable only on string type view model properties and in my case, I am uploading the files via "HttpPostedFileBase" data type view model property. This means that the pre-built data annotation/attribute does not have any means to know the data type of the file(s) that I am uploading which will have  no effect on the limitation that is considered to be applied on the uploaded file type extensions. Of course, there are many other tricks or workarounds to go through while working with the pre-built FileExtensions attribute, but, I prefer the custom data annotation/attribute mechanism, which is much simpler.

So, in the above code, I have created a new class "AllowExtensionsAttribute" (by following the naming convention of custom attribute class) and inherited the ValidationAttribute class. Then, I have created a public property "Extensions" and set the default value with image file type extensions, which means that my custom attribute will accept only image file type to be uploaded. So, in order to allow the required file type extensions, this property will be updated at the time of my custom attribute utilization accordingly. Finally, I have overridden the "IsValid(....)" method which will receive my uploaded file as "HttpPostedFileBase" data type and from this, I will extract the file type extension of the uploaded file and then validate whether it is according to either default file type extension restriction or according to my provided file type extensions.

Step 5
Now, create a new "Models\ImgViewModel.cs" file and replace the following code in it i.e.
//----------------------------------------------------------------------- 
// <copyright file="ImgViewModel.cs" company="None"> 
//     Copyright (c) Allow to distribute this code and utilize this code for personal or commercial purpose. 
// </copyright> 
// <author>Asma Khalid</author> 
//----------------------------------------------------------------------- 
 
namespace ImgExtLimit.Models 

    using System.Collections.Generic; 
    using System.ComponentModel.DataAnnotations; 
    using System.Web; 
    using Helper_Code.Common; 
 
    /// <summary> 
    /// Image view model class. 
    /// </summary> 
    public class ImgViewModel 
    { 
        #region Properties 
 
        /// <summary> 
        /// Gets or sets Image file property. 
        /// </summary> 
        [Required] 
        [Display(Name = "Supported Files .png | .jpg")] 
        [AllowExtensions(Extensions = "png,jpg", ErrorMessage = "Please select only Supported Files .png | .jpg")] 
        public HttpPostedFileBase FileAttach { get; set; } 
 
        /// <summary> 
        /// Gets or sets message property. 
        /// </summary> 
        public string Message { get; set; } 
 
        /// <summary> 
        /// Gets or sets is valid propertty. 
        /// </summary> 
        public bool isValid { get; set; } 
 
        #endregion 
    } 
}

In the above code, I have created my view model which I will attach with my view. Here, I have created HttpPostedFileBase type file attachment property which will capture uploaded image/file data from the end-user, then I have also applied my custom "AllowExtensions" attribute to the FileAttach property and provide the list of file type extensions separated by a comma (,) that I have allowed my system to accept. Then, I have created two more properties; i.e., Message of data type string and isValid of data type Boolean for processing purpose.

Step 6

Create a new "Controllers\ImgController.cs" file and add the following code to it.
//----------------------------------------------------------------------- 
// <copyright file="ImgController.cs" company="None"> 
//     Copyright (c) Allow to distribute this code and utilize this code for personal or commercial purpose. 
// </copyright> 
// <author>Asma Khalid</author> 
//----------------------------------------------------------------------- 
 
namespace ImgExtLimit.Controllers 

    using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Web; 
    using System.Web.Mvc; 
    using Models; 
 
    /// <summary> 
    /// Image controller class. 
    /// </summary> 
    public class ImgController : Controller 
    { 
        #region Index view method. 
 
        #region Get: /Img/Index method. 
 
        /// <summary> 
        /// Get: /Img/Index method. 
        /// </summary>         
        /// <returns>Return index view</returns> 
        public ActionResult Index() 
        { 
            // Initialization/ 
            ImgViewModel model = new ImgViewModel() { FileAttach = null, Message = string.Empty, isValid = false }; 
 
            try 
            { 
            } 
            catch (Exception ex) 
            { 
                // Info 
                Console.Write(ex); 
            } 
 
            // Info. 
            return this.View(model); 
        } 
 
        #endregion 
 
        #region POST: /Img/Index 
 
        /// <summary> 
        /// POST: /Img/Index 
        /// </summary> 
        /// <param name="model">Model parameter</param> 
        /// <returns>Return - Response information</returns> 
        [HttpPost] 
        [AllowAnonymous] 
        [ValidateAntiForgeryToken] 
        public ActionResult Index(ImgViewModel model) 
        { 
            try 
            { 
                // Verification 
                if (ModelState.IsValid) 
                { 
                    // Settings. 
                    model.Message = "'" + model.FileAttach.FileName + "' file has been successfuly!! uploaded"; 
                    model.isValid = true; 
                } 
                else 
                { 
                    // Settings. 
                    model.Message = "'" + model.FileAttach.FileName + "' file is not supported. "; 
                    model.isValid = false; 
                } 
            } 
            catch (Exception ex) 
            { 
                // Info 
                Console.Write(ex); 
            } 
 
            // Info 
            return this.View(model); 
        } 
 
        #endregion 
 
        #endregion 
    } 
}

In the above code, I have created a GET "Index(...)" method which will initialize the view model with default values and send it to the view page. Finally, I have created a POST "Index(...)" method which will receive an input image file from the end-user, then validate the view model for allowed file type extensions and then send the response message accordingly.

Step 7
Now, create a view "Views\Img\Index.cshtml" file and add the following code to it.
@using ImgExtLimit.Models 
 
@model ImgExtLimit.Models.ImgViewModel 
 
@{ 
    ViewBag.Title = "ASP.NET MVC5: Limit Upload File Extension"; 

 
 
<div class="row"> 
    <div class="panel-heading"> 
        <div class="col-md-8"> 
            <h3> 
                <i class="fa fa-file-text-o"></i> 
                <span>ASP.NET MVC5: Limit Upload File Extension</span> 
            </h3> 
        </div> 
    </div> 
</div> 
 
<br /> 
 
<div class="row"> 
    <div class="col-md-6 col-md-push-2"> 
        <section> 
            @using (Html.BeginForm("Index", "Img", FormMethod.Post, new { enctype = "multipart/form-data", @class = "form-horizontal", role = "form" })) 
            { 
                @Html.AntiForgeryToken() 
 
                <div class="well bs-component"> 
                    <br /> 
 
                    <div class="row"> 
                        <div class="col-md-12"> 
                            <div class="col-md-8 col-md-push-2"> 
                                <div class="input-group"> 
                                    <span class="input-group-btn"> 
                                        <span class="btn btn-default btn-file"> 
                                            Browse… 
                                            @Html.TextBoxFor(m => m.FileAttach, new { type = "file", placeholder = Html.DisplayNameFor(m => m.FileAttach), @class = "form-control" }) 
                                        </span> 
                                    </span> 
                                    <input type="text" class="form-control" readonly> 
                                </div> 
                                @if (Model.isValid && !string.IsNullOrEmpty(Model.Message)) 
                                { 
                                    <span class="text-success">@Model.Message</span> 
                                } 
                                else 
                                { 
                                    <span class="text-danger">@Model.Message</span>@Html.ValidationMessageFor(m => m.FileAttach, "", new { @class = "text-danger" }) 
                                } 
                            </div> 
                        </div> 
                    </div> 
 
                    <div class="form-group"> 
                        <div class="col-md-12"> 
                        </div> 
                    </div> 
 
                    <div class="form-group"> 
                        <div class="col-md-offset-5 col-md-10"> 
                            <input type="submit" class="btn btn-danger" value="Upload" /> 
                        </div> 
                    </div> 
                </div> 
            } 
        </section> 
    </div> 
</div> 
 
@section Scripts 

    @*Scripts*@ 
    @Scripts.Render("~/bundles/bootstrap-file") 
 
    @*Styles*@ 
    @Styles.Render("~/Content/Bootstrap-file/css") 
}


In the above code, I have created a simple view for uploading the image file to the server which will validate the allowed file type extensions at the server side.

Step 8
Now, execute the project



ASP.NET MVC 6 Hosting - HostForLIFE.eu :: How to Fix Bundles Are Not Working After Hosting To MVC Application?

clock December 18, 2018 10:38 by author Peter

If your bundles are not getting configured properly in your server, I have fixed this issue, and here I am going to share with you how you can also fix this error. I hope you will like this.

Background

Recently, I hosted one of my MVC applications to Microsoft Azure cloud. And we usually publish our application in release mode, right? So here comes the problem. You can replicate the same issue in your local machine itself. Just make the debug attribute to false in your Web.config as follows.

  1. <compilation debug="false" targetFramework="4.5" />  

And when you run, you will get a prompt as follows.

Run without debugging

Just select Run without debugging option. Now once after your application is run, you can see some script errors in your browser console saying that the references are not loaded correctly.

Release more error in console

And finally I found the solution. Here we will see that.

"Bundles Are Not Working After Hosting To MVC Application"

As I said, the problem is with your bundle config settings. There are few things you must check before going to the last fix.

  • Please make sure that you have used StyleBundle for creating the style bundle.
  • Please make sure that you have used ScriptBundle for creating the style bundle.
  • Make sure that you are loading the styles using @Styles.Render.
  • Make sure that you are loading the scripts using @Scripts.Render.
  • Make sure that the folder structure is same as you have in local system.
    If none of the above solution works, you can try the last one.
  • Make sure that virtual path of bundles doesn’t contains the folder names you have in your solution.

I will explain it. In my case my bundles were as follows.

@Styles.Render("~/Scripts/JQWidgets/CSS")  
@Scripts.Render("~/Scripts/JQWidgets")  

And I have the folders JQWidgets in my root script folder. This was making the issue.


Folder structure

Now what I did is, I just changed my bundle config settings in BundleConfig.cs as follows(Renaming the folder),

bundles.Add(new ScriptBundle("~/Scripts/Grid")  
bundles.Add(new StyleBundle("~/Scripts/Grid/Styles")  

And I referenced the same bundles as follows in my views.

@Styles.Render("~/Scripts/Grid/Styles")  
@Scripts.Render("~/Scripts/Grid")  

Please try these steps and build your application. Once that is done you can publish your application to cloud. I hope this will solve your issue. Have a happy coding.

Conclusion

Did I miss anything that you may think is needed? Did you find this post useful? I hope you liked this article. Please share with me your valuable suggestions and feedback.

Your turn. What do you think?

A blog isn’t a blog without comments, but do try to stay on topic. If you have a question unrelated to this post, you’re better off posting it on C# Corner, Code Project, Stack Overflow, ASP.NET Forum instead of commenting here. Tweet or email me a link to your question there and I’ll definitely try to help if I can.

HostForLIFE.eu ASP.NET MVC 6 Hosting
HostForLIFE.eu is European Windows Hosting Provider which focuses on Windows Platform only. We deliver on-demand hosting solutions including Shared hosting, Reseller Hosting, Cloud Hosting, Dedicated Servers, and IT as a Service for companies of all sizes. We have customers from around the globe, spread across every continent. We serve the hosting needs of the business and professional, government and nonprofit, entertainment and personal use market segments.



ASP.NET MVC 6 Hosting - HostForLIFE.eu :: Stepwise Display Multiple Partial View Using JSON in MVC 5

clock November 9, 2018 10:58 by author Peter

Here are the steps:
Step 1: Create the basic structure of your project, View, multiple partial views View Model,

Step 2: Create your base Controller as in the following,
    public class BaseController: Controller 
    { 
        protected internal virtual CustomJsonResult CustomJson(object json = null, bool allowGet = true) 
        { 
            return new CustomJsonResult(json) 
            { 
                JsonRequestBehavior = allowGet ? JsonRequestBehavior.AllowGet : JsonRequestBehavior.DenyGet 
            }; 
        } 
    } 


It is just small modifications if JSON is not provided handle it. And use this Controller as base controller.

Step 3: Add Class Controller helper which helps you to convert partial view into the string format as in the following,
    public static class ControllerHelper 
    { 
        public static string RenderPartialViewToString(ControllerContext context, string viewName, object model) 
        { 
            var controller = context.Controller; 
            var partialView = ViewEngines.Engines.FindPartialView(controller.ControllerContext, viewName); 
            var stringBuilder = new StringBuilder(); 
            using(var stringWriter = new StringWriter(stringBuilder)) 
            { 
                using(var htmlWriter = new HtmlTextWriter(stringWriter)) 
                { 
                    controller.ViewData.Model = model; 
                    partialView.View.Render(new ViewContext(controller.ControllerContext, partialView.View, controller.ViewData, new TempDataDictionary(), htmlWriter), htmlWriter); 
                } 
            } 
            return stringBuilder.ToString(); 
        } 
    } 

Step 4: Your action code is below. I have added the 2 partial views. Basically we are converting the partial view with objects into the string format.
    public JsonResult CreatePartialView() 
    { 
        MyMultipleUpdateViewModel obj = new MyMultipleUpdateViewModel(); 
        obj.myTest1ViewModel = new MyTest1ViewModel(); 
        obj.myTest1ViewModel.MyTestUpdate = "Test1" + DateTime.Now.ToString(); 
        obj.myTest2ViewModel = new MyTest2ViewModel(); 
        obj.myTest2ViewModel.MyTestUpdate = "Test2" + DateTime.Now.ToString(); 
        var json = new 
        { 
            Header = "Header", Footer = "Footer" 
        }; 
        return CustomJson(json).AddPartialView("_MyTest1PartialView", obj).AddPartialView("_MyTest2PartialView", obj); 
    } 

Step 5: In View display this JSON data ajax in below way . In below code PartialViewDiv1 and PartialViewDiv2 are two divs in which two partial views will be displayed. I have two partial views you may load more partial views.
    <h2>Index</h2> 
    <script type="text/javascript" src="@Url.Content(" ~/Scripts/jquery-1.10.2.js ")"></script> 
    <script type="text/javascript" src="@Url.Content(" ~/Scripts/jquery.unobtrusive-ajax.min.js ")"></script> 
    <script> 
    function GetData(url, onSuccess) 
    { 
        $.ajax( 
        { 
            type: "GET", 
            cache: false, 
            url: url, 
            dataType: "json", 
            success: function(data, textStatus, jqxhr) 
            { 
                onSuccess(data.Json, data.Html); 
            }, 
            error: function(data, text, error) 
            { 
                alert("Error: " + error); 
            } 
        }); 
        return false; 
    } 
     
    function UpdateDiv(json, html) 
    { 
        $("#PartialViewDiv1").html(html[0]); 
        $("#PartialViewDiv2").html(html[1]); 
    } 
    </script> 
    <input type="button" onclick="GetData('/DisplayMutiplePartialView/CreatePartialView', UpdateDiv);" value="Display Multiple Partial View" /> 
    <br> 
       <br> 
          <div id="PartialViewDiv1"></div> 
       <br> 
       <br> 
          <div id="PartialViewDiv2"></div> 
       <br> 
    <br> 


Step 6: Run application and use URL,
It will appear as below

HostForLIFE.eu ASP.NET MVC 6 Hosting
HostForLIFE.eu is European Windows Hosting Provider which focuses on Windows Platform only. We deliver on-demand hosting solutions including Shared hosting, Reseller Hosting, Cloud Hosting, Dedicated Servers, and IT as a Service for companies of all sizes. We have customers from around the globe, spread across every continent. We serve the hosting needs of the business and professional, government and nonprofit, entertainment and personal use market segments.

 



ASP.NET MVC 6 Hosting - HostForLIFE.eu :: How to Add Robots.txt to your ASP.NET MVC ?

clock October 16, 2018 12:17 by author Peter

One of the items I continuously forgot to add to my web applications is the Robots.txt file that Search Engines use to see what they should index.  This file and site maps help make your site easier to navigate by the bots and allow them to know what's legal and what you would rather not have the published in their engines.  I usually add any administrative pages or account pages despite the fact that they're protected by security, no need for the login page to be index if they sniff the link.

 

So how do you add Robots.txt to your MVC three application?  Glad you asked, here may be a very little code to get you started.

Code

1. Choose the controller you'd wish to use for the robots.txt output.  I selected the HomeController in my application as i use  it for many “top level” generic links like about us, contact us, index, etc.

2. Create a method called Robots to handle the request.
#region -- Robots() Method –
public ActionResult Robots()
{
    Response.ContentType = "text/plain";
    return View();

}
#endregion

Add the Robots.cshtml view to your Controller’s View directory.  Here is the code I have in my view, yours will vary.
@{
    Layout = null;
}
# robots.txt for @this.Request.Url.Host 
User-agent: *
Disallow: /Administration/
Disallow: /Account/

Load up the class you are using to control your routes, if you are in an Area, this could your AreaRegistration class.  If you are at the top like I am and using the standard MVC template, this is probably the Global.asax.cs file.  Add your route to this file, mine looks like this.

routes.MapRoute("Robots.txt",               
"robots.txt",

new { controller = "Home", action = "Robots" });

Now, Compile and test.

If you have an internet facing site, the chances are you will have a bot find you're request this page. you might as well offer them the advantage of the doubt and allow them to know where you want them to travel. additionally you may save yourself some error log once this page is requested and no controller is found.

Just like something in ASP.NET, there are some ways to solve this riddle, if you employ a special approach, please feel free to share it within the comments.

HostForLIFE.eu ASP.NET MVC 6 Hosting
HostForLIFE.eu is European Windows Hosting Provider which focuses on Windows Platform only. We deliver on-demand hosting solutions including Shared hosting, Reseller Hosting, Cloud Hosting, Dedicated Servers, and IT as a Service for companies of all sizes. We have customers from around the globe, spread across every continent. We serve the hosting needs of the business and professional, government and nonprofit, entertainment and personal use market segments.



European ASP.NET MVC 6 Hosting :: ASP.NET MVC 6 Web API Routes and ApiController

clock October 5, 2018 09:47 by author Peter

ASP.NET MVC 6 Web API Project

ASP.NET MVC 6 introduces several new project types after you initially pick that you want to develop an ASP.NET MVC 6 Web Application. One of those application types is the new Web API Project.


If you choose the Web API Project, a new Web API Controller Class is created for you to provide an example of responding to Get, Post, Put, and Delete requests for your API.


public class ValuesController : ApiController {

   // GET /api/values
    public IEnumerable<string> Get() {
        return new string[] { "value1", "value2" };
    }

    // GET /api/values/5
    public string Get(int id) {
        return "value";
    }

    // POST /api/values
    public void Post(string value) {}


    // PUT /api/values/5
    public void Put(int id, string value) {}

    // DELETE /api/values/5
    public void Delete(int id) {}
}


With the Web API Project you will also notice a new API specific route added to the RouteTable in Global.asax.cs.

routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional }
);


Running the project and navigating to ~/api/values will display a list of the values in XML Format. I removed the XML namespacing to keep things simple.

<ArrayOfString>
    <string>value1</string>
    <string>value2</string>
</ArrayOfString>

If you change the Accept Header so that you will only accept JSON, the same controller action will send the values via JSON instead.

["value1","value2"]

Web API Controller Class - ApiController in ASP.NET MVC 4

Creating a new Web API Controller Class is as simple as using the Add Controller Recipe in ASP.NET MVC 4 and choosing the Empty API controller Tempate.



Or, you could just create one via Add Item which has a new Web API Controller Class as an option.


I created a simple ProductsController that handles all the CRUD options for products in a mythical e-commerce website.


public class ProductsController : ApiController {
    private readonly IRepository<Product> _repository;

    public ProductsController(IRepository<Product> repository) {
        _repository = repository;
    }

    public IEnumerable<Product> Get() {
        return _repository.Queryable();
    }

    public Product Get(int id) {
        var product = _repository.Get(id);

        if (product == null)
            throw new HttpResponseException(HttpStatusCode.NotFound);

        return product;
    }

    public HttpResponseMessage<Product> Post(Product product) {
        _repository.Add(product);

        var response = new HttpResponseMessage<Product>
            (product, HttpStatusCode.Created);
        response.Headers.Location = new Uri(Request.RequestUri,
            Url.Route(null, new {id = product.Id}));

        return response;
    }

    public Product Put(int id, Product product) {
        var existingProduct = _repository.Get(id);

        if (existingProduct == null)
            throw new HttpResponseException(HttpStatusCode.NotFound);

        _repository.Save(product);

        return product;
    }

    public HttpResponseMessage Delete(int id) {
        _repository.Delete(id);

        return new HttpResponseMessage(HttpStatusCode.NoContent);
    }
}

You can see that in some instances I am just returning a Product and in other instances I am returning a more informational HttpResponseMessage. For example, in the case of the Post of a new Product, I need to tell the REST Client the new location of the newly added product in the header. In other actions I am also throwing a HttpResponseException if the resource requested is not found. Validation, Logging, and other concerns are being done in various ActionFilters just like in your normal ASP.NET MVC Projects. Try to pull those cross-cutting concerns out of the main logic as much as possible.


ASP.NET Web API OData Syntax for Paging and Querying

If you want to enable various paging and querying of products you can make a slight change to the Get ApiController Action and return an IQueryable<Product> as opposed to IEnumerable<Product>.

public IQueryable<Product> Get() {
    return _repository.Queryable();
}

Now from your browser you can add paging, filtering, sorting, and other options to shape the data. Here is an example call that does paging and sorting.

api/products?$skip=2&$top=2&$orderby=Title

The XML Response by the browser is:

<ArrayOfProduct>
    <Product>
        <Id>3</Id>
        <Title>RipStik</Title>
        <Price>69.00</Price>
    </Product>
    <Product>
        <Id>4</Id>
        <Title>Shred Sled</Title>
        <Price>49.00</Price>
    </Product>
</ArrayOfProduct>


Or the JSON Response:

[{"Id":3,"Price":69.00,"Title":"RipStik"},
{"Id":4,"Price":49.00,"Title":"Shred Sled"}]


Conclusion

ASP.NET Web API integration with ASP.NET MVC 4 is really slick. Now you can easily create an API for your website using the new ApiController Base Class to respond to REST Clients.

 



About HostForLIFE.eu

HostForLIFE.eu is European Windows Hosting Provider which focuses on Windows Platform only. We deliver on-demand hosting solutions including Shared hosting, Reseller Hosting, Cloud Hosting, Dedicated Servers, and IT as a Service for companies of all sizes.

We have offered the latest Windows 2016 Hosting, ASP.NET Core 2.2.1 Hosting, ASP.NET MVC 6 Hosting and SQL 2017 Hosting.


Tag cloud

Sign in