Monday, July 1, 2013

CREATE CUSTOM HTTP HANDLER in Mvc Application based on Xml Rules

CREATE CUSTOM HTTP HANDLER in Mvc Application based on Xml File Rules

Creating Handler for Mvc Application, Deserialize Rules Xml and Invoke Relevant Contoller / Action




public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
            var virtualPath = HttpContext.Current.Request.CurrentExecutionFilePath.TrimStart('/');

            var routeInfo = RoutesBus.GetIdByRoute(virtualPath);

            if (routeInfo == null)
            {
                return new MvcHandler(requestContext);
            }

            var latestRouteInfo = RoutesBus.GetRouteById(routeInfo.Route_RelatedID, routeInfo.Route_RelatedType);

            if (latestRouteInfo == null)
            {
                return new MvcHandler(requestContext);
            }

            if (routeInfo.RouteURL != latestRouteInfo.RouteURL)
            {
                HttpContext.Current.Response.Status = "301 Moved Permanently";
                HttpContext.Current.Response.StatusCode = 301;
                HttpContext.Current.Response.RedirectLocation = '/' + latestRouteInfo.Route_EntireURL;
                HttpContext.Current.Response.End();
            }

            var showPageTypeControllerRules = Utilities.SerializationHelper.Desirialization<rules>
                                                                                                                                (ShowPageTypeControllerRulesXml);
            Utilities.RouteFactoryByPageType.GetRouteDataAccordingToShowPageRules(requestContext, 
                                                                                                                           showPageTypeControllerRules, routeInfo);

            return new MvcHandler(requestContext);
}

... Desirialization (trivial, but anyway)

public class SerializationHelper
    {
        public static T Desirialization<T>(string filePath)
        {
            var serializer = new XmlSerializer(typeof(T));
            var reader = new StreamReader(filePath);
            var result = (T)serializer.Deserialize(reader);
            reader.Close();
            return result;
        }

    }

AND GetRouteDataAccordingToShowPageRules And Invoke Relevant Controller

public static void GetRouteDataAccordingToShowPageRules
(RequestContext requestContext, rules showPageTypeControllerRules, RouteInfoObject routeInfo)
{
            var relevantRule = (from r in showPageTypeControllerRules.Items where r.name == routeInfo.Route_RelatedType  
                                              select r).FirstOrDefault();

            if (relevantRule == null) return;

            requestContext.RouteData.Values["controller"] = relevantRule.controller;
            requestContext.RouteData.Values["action"] = relevantRule.action;
            requestContext.RouteData.Values["eventId"] = routeInfo.Route_RelatedID;

 }

Wednesday, March 13, 2013

Web Data Grid with filtering on all fields and full paging functionality

Web Data Grid with filtering on all fields and full paging functionality
(JQuery, Link.js)

I worked on it very hard whole day, hope you will enjoy and save your day :-)

VIEW (razor):

@model IEnumerable<Enigma.Models.Product>
 
@{
    ViewBag.Title = "CreateNewOrder";
    Layout = "~/Views/Shared/_LayoutCustomer.cshtml";
}
 
@Styles.Render("~/Content/Customer/CreateNewOrder.css")
 
 
<div id="searchArea"> 
    <input class='searchFields' id='searchX1' type='text'>
    <input class='searchFields' id='searchName' type='text'>
    <input class='searchFields' id='searchSize' type='text'>
    <input class='searchFields' id='searchPriceFrom' type='text'>
    <input class='searchFields' id='searchPriceTo' type='text'>
    <input class='searchFields' id='searchQuantityInPackage' type='text'>
    <input class='searchFields' id='searchSupplierName' type='text'>
</div>
 
<div id="mainDiv"></div>
<a id="PrevPage" href="#">Prev</a>
<a id="NextPage" href="#">Next</a>
<input type="submit" value="Create" />
@Html.ActionLink("Cancel Order""CustomerIndex""CustomerIndex")

JAVA SCRIPT OF GRID:
 
<script>
 
    var pagingIndexStep = 10;
    var origPagingIndexStep = 10;
    var globalPagingIndexMin = -origPagingIndexStep;
    var globalPagingIndexMax = 0;
    var model = @Html.Raw(Json.Encode(Model));    
    var modelSize = model.length;
    var origModel = model;
    var newModel = model;
    var reachedMaximum;
    var reachedMinimum;
    var pageNumber = 0;
    ShowNextPage(model);    
 
    function CutModelAccordingToIndex(model, startWith, endWith) {
        newModel = {};
        for (var i = startWith; i < endWith; i++) {
            newModel[i] = model[i];
        }
        
        return newModel;
    }
        
    function DrawGridByModel(newModel) {
        if (newModel.length == 0) return;
        var localModel = newModel;
        var html = "";       
        html += "<table class='productTable'>";
        html += "<thead class='tableThead'>";
        html += "<tr>";
        html += "<th>X1</th>";
        html += "<th>Name</th>";
        html += "<th>Size</th>";
        html += "<th>Price</th>";
        html += "<th>Quantity In Package</th>";
        html += "<th>Supplier Name</th>";
        html += "<th>Start Date</th>";
        html += "<th>End Date</th>";
        html += "<th>Add to Order</th>";
        html += "</tr>";
        html += "</thead>";
        html += "<tbody class='tableBody'>";
        html += "<tr>";        
        html += "<td></td>";
        html += "<td></td>";
        html += "<td></td>";
        html += "</tr>";
        $.each(localModel, function(key, value) {
            html += "<tr>";
            html += "<td class='x1_row'>" + value.x1 + "</td>";
            html += "<td class='name_row'>" + value.name + "</td>";
            html += "<td class='size_row'>" + value.size + "</td>";
            html += "<td class='price_row'>" + value.price + "</td>";
            html += "<td class='quantity_in_package_row'>" + value.quantity_in_package + "</td>";
            html += "<td class='supplier_name_row'>" + value.supplier_name + "</td>";
            html += "<td class='start_date_row'>" + value.period_start_date + "</td>";
            html += "<td class='end_date_row'>" + value.period_end_date + "</td>";
            html += "<td class='check_row'><input id='addToOrderButton' type='checkbox'></td>";
            html += "</tr>";
        });
        if (model.length > 0) {
            html += "<tr>";
            html += "<td class='total_pages'>Page: " + pageNumber +
                                           " From: " + Math.ceil(model.length / pagingIndexStep) + 
                                           " Total Results:" + model.length + "</td>";
            html += "</tr>";
        }
        html += "</tbody>";
        html += "</table>";
        $("#mainDiv").html(html);
        UpEvents();
    }
  
    $('#NextPage').click(ShowNextPage);
    $('#PrevPage').click(ShowPrevPage);        
    
    function ShowNextPage() {        
        var nextButton = $('#NextPage');
        var prevButton = $('#PrevPage');
        if (reachedMaximum || model.length == 0) return; 
        pageNumber++;
        globalPagingIndexMin += pagingIndexStep;
        globalPagingIndexMax += pagingIndexStep;
        if (globalPagingIndexMax >= modelSize) {
            newModel = CutModelAccordingToIndex(model, globalPagingIndexMin, modelSize);
            DrawGridByModel(newModel);
            nextButton.addClass("prevNextButtonsDisabled");           
            reachedMaximum = true;
        } else {
            newModel = CutModelAccordingToIndex(model, globalPagingIndexMin, globalPagingIndexMax);
            DrawGridByModel(newModel);           
            reachedMaximum = false;
        }                
        prevButton.addClass("prevNextButtonsEnabled");
        reachedMinimum = false;
       
    }
    
    function ShowPrevPage() {
        var nextButton = $('#NextPage');
        var prevButton = $('#PrevPage');
        if (reachedMinimum || (globalPagingIndexMin - pagingIndexStep) < 0 || model.length == 0) return;
        pageNumber--;
        globalPagingIndexMin -= pagingIndexStep;
        globalPagingIndexMax -= pagingIndexStep;
        if (globalPagingIndexMin < 1) {
            newModel = CutModelAccordingToIndex(model, globalPagingIndexMin, globalPagingIndexMax);
            DrawGridByModel(newModel);
            prevButton.addClass("prevNextButtonsDisabled");          
            reachedMinimum = true;
        } else {
            newModel = CutModelAccordingToIndex(model, globalPagingIndexMin, globalPagingIndexMax);
            DrawGridByModel(newModel);              
        } 
        reachedMaximum = false;
        nextButton.addClass("prevNextButtonsEnabled");
        
    }      
    
    function CreateNewModelAccordingToCrteria()
    {
        var queryResult;
        var searchByX1Val = $('#searchX1').val();
        var searchName = $('#searchName').val();
        var searchSize = $('#searchSize').val();        
     
        queryResult = origModel;
        if (searchByX1Val && searchByX1Val.length > 0) {          
            queryResult = Enumerable.From(queryResult)
                   .Where(" x => x['x1']== " + searchByX1Val).ToArray(); 
        }        
        if (searchName && searchName.length > 0) {                       
            queryResult = Enumerable.From(queryResult)
                   .Where("x => x['name']== '" + searchName + "'").ToArray(); 
        }               
        if (searchSize && searchSize.length > 0) {                       
            queryResult = Enumerable.From(queryResult)
                   .Where("x => x['size']== '" + searchSize + "'").ToArray(); 
        }  
        
        model = queryResult;  
        pagingIndexStep = model.length > origPagingIndexStep ? origPagingIndexStep : model.length;
       
        globalPagingIndexMin = -pagingIndexStep;
        globalPagingIndexMax = 0;
        pageNumber = 0;
        modelSize = model.length;
        reachedMaximum = false;
        reachedMinimum = false;        
        ShowNextPage();
    }       
 
    function AddProductToOrder() {
        if($(this).attr('checked')) {
            
            alert($(this).parent().parent()[0].cells[0].innerText);
        } else {
            alert('REMOVED');
        }
    }
 
    function UpEvents(){
        $(".check_row input[type=checkbox]").click(AddProductToOrder);
    }
   
    $('#searchX1').keyup(CreateNewModelAccordingToCrteria);
    $('#searchName').keyup(CreateNewModelAccordingToCrteria);  
    $('#searchSize').keyup(CreateNewModelAccordingToCrteria);  
    
</script>

Thursday, January 17, 2013

Using MVP Pattern in ASP.NET WebForm Application

MVP - Model / View / Presenter pattern.

There are a lot of various explanations about this pattern on internet spaces and I would like to skip explain about one more time, but I would like to show 2 simple examples of MVP pattern:

1. View referred to Presenter (getting all necessary data and run presenter methods according to events)
     (See Pic 1)

2. Presenter has reference to View and initiated all view's objects and View refer back to Presenter with events fired that Presenter registered on. (See Pic 2)




Lets see which components we need to prepare for scenario Pic 1:

Lets start with Presenter Interface:

namespace Contracts
{
    public interface IMyView<T>
    {
        List<T> Model { getset; }
    }
}



... And its Concrete, our Presenter:

public class MyPresenter
{
    private IMyView<ViewModel> View { getset; }
 
    public MyPresenter(IMyView<Model> view)
    {
        View = view;
    }
 
    public void InitViewList(string categoryId = null)
    {
        var List = ServiceAgend or DALAgend or .....
  
        View.Model = (from c in List select new ViewModel
                          {
                              Name= c.Name,
                              Surname = c.SurName
                          }).ToList();
    }
}

ViewModel:

namespace ViewModels
{
    public class ViewModel
    {
        public string Name{ getset; }
        public string SurName { getset; }
    }
}


...and View code behind:

 
namespace International
{
    public partial class MyView: IMyView<ViewModel>
    {
        public static readonly string Title = "Most Popular Discounts";
        public static readonly string Footer = "See all Discounts";
        public List<ViewModel> Model { getset; }
 
        protected void Page_Load(object sender, EventArgs e)
        {
            var presenter = new MyPresenter(this);
            presenter.InitViewList(CategoryId);
        }
    }
}



...and Sample of View.ascx


<% foreach (var item in Model)
       {%>    
         <li class="dots">
            <a href="#"><%=item.Name%></a>
            <span class="discount"><%=item.SurName%></span>
            <div class="clr"></div>
        </li>
    <% } %>




Unit Testing tip:

How to simulate HttpContextBase:


public HttpContextBase MockContext(bool isAuthenticated = falsestring username = "")
{
    //Creating the HttpContext object
    var httpContext = MockRepository.GenerateMock<HttpContextBase>();            
    //Creating the Identity object 
    var identity = MockRepository.GenerateMock<IIdentity>();
    identity.Stub(u => u.Name).Return(username);
    identity.Stub(i => i.IsAuthenticated).Return(isAuthenticated);
    //Creating the User Object 
    var user = MockRepository.GenerateMock<IPrincipal>();
    user.Stub(u => u.Identity).Return(identity);
    httpContext.Stub(ctx => ctx.User).Return(user);
    return httpContext;
}