Category: tips and tricks

5 Minutes .NET–Memory Cache

 

At https://youtu.be/BL5yo_p7x-E you can find the new video about caching in .NET with Memory Cache.

The code is:

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Caching;
using System.Text;
using System.Threading.Tasks;

namespace MemoryCacheNet
{
    public static class GlobalData
    {
        static object lockMe = new object();

        public static List<string> CountryList()
        {
            string key = "countries";
            var data = MemoryCache.Default.Get(key) as List<string>;
            if(data == null)
            {
                lock (lockMe)
                {
                    data = MemoryCache.Default.Get(key) as List<string>;
                    if(data != null)
                    {
                        return data ;
                    }
                    data = CountryListFromDatabase();
                    var duration = DateTimeOffset.UtcNow.AddSeconds(5);
                    MemoryCache.Default.AddOrGetExisting(key,data,duration);
                   

                }
            }
            return data;
        }
        static List<string> CountryListFromDatabase()
        {
            Console.WriteLine("obtaining data from database");
            return new List<string>()
            {
                "Romania",
                "India",
                "USA"
                // add your country 😉
            };
        }
    }
}

and using from Console:

using MemoryCacheNet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace MemoryCacheDOS
{
    class Program
    {
        static void Main(string[] args)
        {
            var data = GlobalData.CountryList();
            Console.WriteLine(data.Count);

            Console.WriteLine("waiting 1 sec");
            Thread.Sleep(1000);
            data = GlobalData.CountryList();
            Console.WriteLine(data.Count);

            Console.WriteLine("waiting 5 sec");
            Thread.Sleep(5000);
            data = GlobalData.CountryList();
            Console.WriteLine(data.Count);

        }
    }
}

 

Other tutorials are:

5MinThrowVsThrowEx
5Min Usefull Attributes
5MinIValidatableObject
5MinAsyncException
5MinAsync
5Min iMacrosAHK
5min Zip
5MinPSR
5MinParseWebPage
5MinFileHelpers
5Min Logging
5min Send emails and SMTP4Dev
5Min Memory Profiler ( User Object and/or memory leaks)
5min SFHB
5min – .TT files in Visual Studio

The full list is at https://www.youtube.com/playlist?list=PL4aSKgR4yk4OnmJW6PlBuDOXdYk6zTGps  .

Javascript MVVM and ASP.NET MVC

TL;DR;

The purpose of this article is to show is how to transmit data to edit( create, update, delete) from a MVVM array to an ASP.NET MVC action in order for the action to bind to an IEnumerable/Array/List of objects. We will make also a javascript function that can be re-use across multiple MVVM frameworks to transmit data for multiple objects at once.

As always, you can find source code at https://github.com/ignatandrei/JavaScriptAndMVVMandMVC/ and you can view online at http://mvvmjavascriptmvc.apphb.com/

 

If you know already that, the last item on this rather long post is a homework. Download code and do it Winking smile

 

 

Prerequisites:

  1. If you want to know about ajax, please see the same example of how to save employee one by one http://msprogrammer.serviciipeweb.ro/2011/12/05/jquery-ajax-request-and-mvcdetailed/.
  2. The reference of sending an array of objects to MVC is http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx/ . Please read it first since we will compose the Http request in ASP.NET MVC manner.
  3. If you do not know about MVVM and data binding in javascript, please follow most comprehensive tutorial that I know, http://learn.knockoutjs.com/

Objects

We start with the Employee ( Id, Name and IdDepartment) and Department(Id, Name). We will make an interface to display and edit multiple employees. The user can choose to change the Name and pick a Department from a list of Departments (presented as a select / dropdown / combox) .Also, he can create new Employee or delete an existing Employee. Then the user can submit all changes at once. We will use for this MVVM from Knockout, but you can use any other MVVM framework.

We will have 2 modes: edit and display. For edit, we have as actions add, delete ,modify and send all modifications(along with validation) . I would list what it is mandatory for every mode and action.

For fast learners:
Display
Edit Mode –Modify existing data
Edit Mode –add new employee
Edit Mode –delete existing employee
Edit Mode –send modifications and client validation
Summary
Homework


Display:

clip_image002

As you see we need to display the Employee list with name and the Department name.

If I do not want to create a NameDepartment property on Employee, but just use DepartmentId then the Model of the View should return the list of names of Departments.

public class ListEmployeesViewModel

{

public employeeList AllEmployees { get; set; }

public departmentList DepartmentList{ get; private set; }

This will be serialized as javascript array in the Home view:

@{

var jss = new JavaScriptSerializer();

var arrDepartments = jss.Serialize(Model.DepartmentList);

var arrEmployees = jss.Serialize(Model.AllEmployees);

}
//This is in the script tag in javascript:
//existing departments

var arrDeps = @Html.Raw(arrDepartments) ;

//existing employees

var arrEmps = @Html.Raw(arrEmployees) ;


So we have in arrDeps the departments and in arrEmps the existing employees.

To display the list of employees we create a MVVM javascript model( we have here knockout style, but is similar with other javascript MVVM framework)

First we create an employee in javascript ( explanations will follow) :

//this is in javascript
var emp = function(empId,name,deptId,active){

var self = this;

self.nr = i++; 

self.IdEmployee = ko.observable(empId);

self.NameEmployee = ko.observable(name);

self.Active = ko.observable(active);

self.iddepartament = ko.observable(deptId);

self.editMode = ko.observable(false);

self.displayMode= ko.observable(true);

self.deptName= function(){

var id=self.iddepartament();

var name ="";

$.each(arrDeps,function(index,value){

if(value.IdDepartment == id){

name=value.NameDepartment;

return false;

}

});

return name;

}

}

Explanation 1: the nr is the number of the employee . The user does not like ID, but wants to know how much employees are displayed.

Explanation 2: I have add an editMode and displayMode to the employee – to know the mode in which the employee is. I can have one property instead of 2(because of complementarity) , but was easier for me.

Explanation 3: In order to display DepartmentName it is enough to create a function on the employee to return the department name , iterating through the arrDeps – the code is

self.deptName= function(){

var id=self.iddepartament();

var name ="";

$.each(arrDeps,function(index,value){

if(value.IdDepartment == id){

name=value.NameDepartment;

return false;

}

});

return name;

}

Now we create the javascript model that holds all employees on the view:

var jsModel = function() {

var self = this;

self.employees = ko.observableArray([]);

And we make a function to add the existing employees to the array of employees:

self.addEmp = function(empId,name,deptId,active) { 

self.employees.push(new emp(empId,name,deptId,active)) 

};

And we add to the javascript MVVM model the existing employees

var model= new jsModel();

$.each(arrEmps,function(index,value){

model.addEmp(value.IdEmployee ,value.NameEmployee, value.iddepartament,value.Active);

});

And display it on the template by just binding :

ko.applyBindings(model);

that will repeat in

<tbody data-bind=’foreach: employees’>

<tr>

<td>

<span data-bind=’text: nr’ > </span>

</td>

<td>

<span data-bind=’text: NameEmployee,visible:displayMode’> </span>

<!—code removed for clarity–>

</td>

<td>

<span data-bind=’text: deptName(),visible:displayMode’> </span>

<!—code removed for clarity–>

</td>

<td>

<span data-bind=’text: Active,visible:displayMode’> </span>

<!—code removed for clarity–>

</td>

<td><!—code removed for clarity–>

</td>

</tr>

So this was the display mode. Pretty simple, huh ?

Edit Mode –Modify existing data

The Edit button calls the javascript model edit(true):

self.edit = function(val){

var arr =self.employees();

$.each(arr ,function(index,value){

value.editMode(val);

value.displayMode(!val);

});

So I put editMode to true and displayMode to false

Now, back to the template:

<td>

<span data-bind=’text: NameEmployee,visible:displayMode’> </span>

<input data-bind=’value: NameEmployee,visible:editMode’ />

</td>

You can see here visible attribute binded on displayModel and editMode –and how the span or the input are visible either way.

clip_image004

Same for the checkbox and the select. Because of the MVVM (in this case, knockout) any changes on the data ( name, active, changing department) will be binded back to the array of employees in the javascript MVVM model

Edit Mode –add new employee

When you press add a new employee is generated – the number 3:

clip_image006

It is easy – the Add button calls the same function addEmp that we use to push existing employees:

function BeginAdd(){

model.addEmp(0,'',0,true);

model.edit(true);

}

So a new employee is added to the array of employees – and the employees table is displaying the added employee . Do you like MVVM now ? 😉

Edit Mode –delete existing employee

The delete button have this code:

<td><button data-bind="click: $root.removeEmp,visible:editMode">Delete</button></td>

It is clear visible just when editMode is true. And the removeEmp removes the current employee from array, but having the id ( if not 0 – means new) put into a string that contains the ids of deletedEmployeesa:

 self.removeEmp = function(emp) { 

var id=emp.IdEmployee(); 

if(id != 0)

self.deletedItemsId += id;

self.employees.remove(emp); 

};

And the employees table is removing the row for the employee . Do you like MVVM now ? 😉

Edit Mode –send modifications and client validation

On the server side, the parameters of the action that receives the data is simple:

[HttpPost]

[HttpPost]

public JsonResult SaveEmployees(ListEmployeesViewModel e,string deletedItems)

I will explain the 2 arguments. For the first, remember ListEmployeesViewModel from the beginning ? It contains the list of employees and we will post that:

public class ListEmployeesViewModel

{

public employeeList AllEmployees { get; set; }

The second argument is the string that contains the id’s of deletedEmployees.

Now to transmit those from javascript array of employees.

Being a programmer, I like code-reuse. So why not create a function that iterates through an array( of employees), get all properties ( eliminating non-relevant, such as nr, editMode, displayModel and others) and compose the data in the MVC style(http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx/ )

First, we need reflection in javascript:


//this is generic and can be put in a different .js file

var refProps= function (obj, exclude , recognizeFunction) {

var properties = [];

for (var prop in obj) {

//you can define an exclude function to exclude added properties

if(exclude){

if(exclude(prop))

continue;

}

var excludeProp = true;

var t = (typeof obj[prop]).toLowerCase();

if (t == 'number' || t == 'string' || t == 'boolean') {

excludeProp=false;

}

if(excludeProp){

//special case :maybe it is a observable function 

if(recognizeFunction){

if(t == 'function' ){

if(recognizeFunction(t))

excludeProp=false;

}

};

}

if(!excludeProp)

properties.push(prop);

};

return properties;

}

Fast explanation of parameters:

  1. obj is the object in javascript that I need all properties that are number, string, or boolean.
  2. I need to remove some properties(nr,editMode, displayMode) that are relevant in javascript – but not on the server side – so I have put an exclude function( you can put null)
    function exclude(prop){
    
    switch(prop){
    
    case "nr":
    
    return true;
    
    case "deptName":
    
    return true;
    
    case "editMode":
    
    return true;
    
    case "displayMode":
    
    return true;
    
    default:
    
    return false;
    
    }
    
    
  3. Also, knockout make a special ko.observable function
    self.NameEmployee = ko.observable(name);
    

    – so I need to recognize those functions – and the function is(surprise!) ko.observable

Now saving the array is again re-usable:

function saveArray(itemsArray,/*you can not pass those*/prefix, excludeProp,recognizeFunction,validateProp){

var l = itemsArray.length ;

if(l == 0){

return "";

}

var propNames = refProps(itemsArray[0],excludeProp,recognizeFunction); // you can pass null on exclude to add all properties

var nr = 0 ;

var strData="";

for (var i = 0; i < l; i++) {

var objToSave= itemsArray[i]; 

//you can pass here another function to recognize which object can be saved

//if(!canBeSaved(objSave) continue;

for (var j = 0; j < propNames.length; j++) {

var nameProp = propNames[j];

var val =objToSave[nameProp] ;

var t = (typeof val).toLowerCase();

if(t == 'function'){

val = objToSave[nameProp]();

}

if (validateProp) {

if (!validateProp(nameProp,val, objToSave, i)) {

return "";

}

}

strData += "&"+ prefix+"[" + nr + "]." + nameProp;

strData += "=" + val;

}

nr++;

}

return strData;

}


The itemsArray parameter is the items array that you want to save ( in my case, the employees).

The new function is validateProp – you can pass null – but this is an implementation that take into consideration that the employee should not have the name empty and the user must select something from the department list:


function validateProperty(propName, value, item, number){

switch(propName){

case "NameEmployee":

if(value == ""){

window.alert("please enter employee name for row number " + (number+1) );

return false;

}

return true;

case "iddepartament":

if(value === undefined || value == 0){

window.alert("please select a department for row number " + (number+1) );

return false;

}

return true;

default:

return true;

}

}



After those 2 re-usable functions( saveArray and refProps ) the code for save is pretty simple:

We obtain the values for employees using saveArray

self.save = function() { 

var itemsArray = self.employees();

var strData = saveArray(itemsArray,"AllEmployees",exclude, ko.observable,validateProperty);

if(strData == "")

{

//window.alert("no save");

return;

}

strData="deletedItems=" +self.deletedItemsId + strData;

window.alert("saving:" + strData);

and post to the server.


$.ajax({

type:"POST",

url:'@Url.Content("~/Home/SaveEmployees")' ,

data: strData ,

datatype:"JSON",

//Just we must be attentive: if success , then the id of the new employees( those with id’s 0) must be replaced by the id’s of the id’s generated on server.
//How I identify if multiple new employees? Well, it is easier to delete all employees with id’s 0 and add the id’s that are not already in the array:

var dels=[];

//delete the new items and add the new ones

var idExisting=';';

$.each(self.employees(), function(index,emp) {

if(emp.IdEmployee() == 0 )

dels.push(emp);

else

idExisting += emp.IdEmployee()+";";

});

$.each(dels,function(index,emp) {

self.removeEmp(emp);

});

//add new one

window.alert('add new ones');

$.each(returndata.emps,function(index,emp) {

var id=emp.IdEmployee;

if(idExisting.indexOf(";" + id+";") == -1){// not found - means it is a new one

self.addEmp(emp.IdEmployee ,emp.NameEmployee, emp.iddepartament,emp.Active);

}

});


Also, for Antiforgery token I have used this code

 //added antiforgery token
                var aft= $('input[name="__RequestVerificationToken"]');
                if(aft.length){
                    strData +="&__RequestVerificationToken=" + aft.val();
                }

Well, that was it !

Summary:


We have had an javascript array of employees to edit and send data at once . We have make the POST as for ASP.NET MVC rules. You can re-use the refProps javascript function( that gives you the name of the properties of an object – in our case, employee) and saveArray javascript function – that serialize an javascript array to a recognizable ASP.NET MVC idiom

As always, you can find source code at https://github.com/ignatandrei/JavaScriptAndMVVMandMVC/ and you can view online at http://mvvmjavascriptmvc.apphb.com/

 

Homework for you:

( fork on github  and send me the solution via github)


1. Modify the nr ( the employee order number) such as , when deleting or adding a new employee, the numbers are in good order – not 1 and 3 like in the picture

clip_image008

2. Add a hiredate to the employee . Ensure you transmit the date(Hint: Modify the refProps )

LaterEdit:
Hintea Dan Alexandru made a simple application to show me that a simple json.stringify it is enough for MVC to do this magic.
More , it shows directly in the MVVM model a toDTO that is simplier to use( however, the validation part remains to do)
Source code at https://github.com/hinteadan/MvcAjaxSample/#!

MVC , JsonResult , DateTime and TimeZone

The jsonresult of date time is serializing to the string /Date and some integer value starting with 1970 . The problem is that the browser interprets this value accordingly to the LOCAL TimeZone – and thus the same date is going to be interpreted with a difference.

I was thinking that I can adjust from UTC time offset of the server( obtained with .NET from TimeZoneInfo.Local.BaseUtcOffset.TotalMinutes) and the UTC time offset of the client( obtained with (new Date()).getTimezoneOffset() + UTCServerMinutes; ). Unfortunately, the code does not work for SAMOA ( 13 hours difference).

Pay attention that the server is sending SAME data – just the browser is interpreting from the local user time zone.

So the solution is to convert the  date to a string ( I have chosed yyyy-MM-ddTHH:mm:ss) and interpret in javascript( see date2 below).

The server code – I have put my birthdate 16 april 1970

DateTime res = new DateTime(1970, 04, 16, 22, 0, 0);
[HttpPost]
        public JsonResult GetDateBirth()
        {

            var str = res.ToString("s");
            return Json(new { date =res, datestring=str, ok = true });

        }

The Javascript code:

function GetJsonDate() {
        $.ajax({
            type: "POST",
            url: '@Url.Action("GetDateBirth")',
            datatype: "JSON",
            contentType: "application/json; charset=utf-8",
            success: function (returndata) {
                if (returndata.ok) {
                    window.alert('The server is sending:' + returndata.date + " -- " + returndata.datestring);
                    var d = parseInt(returndata.date.substr(6));
                    var date1 = new Date(d);
                    var date2 = dateFromSortable(returndata.datestring);
                    var date3= getDateString(returndata.date);
                    window.alert('original: ' + date1  + '\r\n'  + ' iso correct:'+ date2 + '\r\n'+ ' utc difference not good:' + date3);

                }
                else {
                    //this is an error from the server
                    window.alert(' error : ' + returndata.message);
                }

            }
        }
        );
    }
    function dateFromSortable(dateStr) {
        var parts = dateStr.match(/\d+/g);
        return new Date(parts[0], parts[1] - 1, parts[2], parts[3], parts[4], parts[5]);
    }
    
    function getDateString(jsonDate) {
        //does not work correctly for SAMOA - it have some hours difference
        var UTCServerMinutes = @serverMinutes;
        if (jsonDate == undefined) {
            return "";
        }
        var utcTime = parseInt(jsonDate.substr(6));

        var dateUtc = new Date(utcTime);

        var minutesOffset = (new Date()).getTimezoneOffset() + UTCServerMinutes;

        var milliseconds = minutesOffset * 60000;
        var d = new Date(dateUtc.getTime() + milliseconds)
        return d;
    }

How to test it:

Run the project. Click “Get Json Date” – and you will see the three dates equal.

image

Now change the time zone to Samoa ( or other, if you live in Samoa Winking smile)

image

Click again on “Get Json Date”  – the date will  same 16 april 1970 just for the date2  – obtained from dateFromSortable javascript function.

image

Please note that the local time zone is NOT affecting the values transmitted via ViewBag/ViewData/Model, but just the ones transmitted via Json.

The project can be downloaded from here

MVC and auto persisting values

When you have a textbox in HTML (let’s say

<input name=”FirstName” type=”text” />

)
And it binds to “FirstName” Property of a Model, and in HttpPost Action you do modify the value and return the same view, the value shown in the textbox is the posted one, not the modified one. ( The first thought is that HttpPost is not executing – but it is a false impression!)
The solution is:
ModelState.Remove(“FirstName”)

or, better

http://lennybacon.com/2010/09/07/RemovingPropertiesFromTheModelStateTheTypedWay

(and it’s not a bug, it’s a feature: classical example: numeric textbox/ numeric property and user enters “aaa” – the validation error appears and the textbox must have aaa, not 0 or default value for the property )

Redirect and Ajax Redirect in MVC

In the sample example I will have various methods to perform redirects from main page to “About” page of a simple MVC site. In my opinion, there are only 3 cases – 2 goods and one bad – to perform redirection with or without Ajax.

 

First case:  A sample redirect and a sample link:

The action is

 public ActionResult RedirectToAboutNoAjax()
        {
            return RedirectToAction("About");
        }

and in the View I call in a simple <a href, generated by :

@Html.ActionLink("Redirect no ajax to about", "RedirectToAboutNoAjax", "Home")

When you click the link, the following happens : a 302 Found answer is send to the browser with the new Location. The browser goes to the page requested.
image
  

Second case( not good ajax): Call same action from ajax – in hope that ajax will do the redirect alone, without coding further.Modified only the code that calls the action, transforming to ajax.

<a href="javascript:AjaxNotGoodForRedirect('@Url.Action("RedirectToAboutNoAjax", "Home")')">Redirect not good with ajax - returns the page</a>

 What it happens is the same: the ajax code calls the RedirectToAboutNoAjax , that redirects to about – and the result is the page. It is no redirect performed to the page itself – rather, on the ajax itself!And , to proof it, I will show the message of html returned in an message:image

Third case( good with ajax): Call a action that returns the new url as a json data parameter and make javascript know that.The action:

 [HttpPost]
        public ActionResult RedirectToAboutWithAjax()
        {
            try
            {
                
                //in a real world, here will be multiple database calls - or others
                return Json(new { ok = true, newurl = Url.Action("About") });
            }
            catch (Exception ex)
            {
                //TODO: log
                return Json(new { ok = false, message = ex.Message });
            }
        }

The javascript:

function AjaxGoodRedirect(urlAction) {
        $.ajax({
            type: "POST", // see http://haacked.com/archive/2009/06/24/json-hijacking.aspx
            url: urlAction,
            data: {}, //to send data see more at http://bit.ly/mvc_ajax_jquery
            datatype: "JSON",
            contentType: "application/json; charset=utf-8",
            success: function (returndata) {
                if (returndata.ok)
                    window.location = returndata.newurl;
                else
                    window.alert(returndata.message);

            }
        }
        );
    }

Note: You can combine the returning the RedirectToAction with Json by checking Request.IsAjaxRequest value and returning either FirstCase, either ThirdCase.

You can find the example for download here
If you want more details, please comment – and I will provide any further explanations.

Optimizing EF4 and EDMGen2

Just reading (from Adrian Florea links ) how the EF4 could be optimized : http://www.codeproject.com/KB/database/PerfEntityFramework.aspx

First modification is to “Pre-generated Your View”. For this you must have .ssdl, .csdl, and .msl files – so you change the “Metadata Artifact Processing property to: Copy to Output Directory.”. Then you process the .ssdl, .csdl, and .msl with edmgen in order to can have the  views.

Until here , all ok.

But, in the next advice, is to keep “Metadata Artifact Processing property to: Embed in Output Assembly.”

One solution is to put “Metadata Artifact Processing property to: Copy to Output Directory.” , compile, put again “Metadata Artifact Processing property to: Embed in Output Assembly.” and compile again. But , if you change the edmx (add fields or tables ) you must redo the operation  – so you will have more things to do(if you remember)

A solution is to build them on the pre-build step .But how to generate the .ssdl, .csdl, and .msl files  ?

Edmgen2 , http://code.msdn.microsoft.com/EdmGen2 , to the rescue. Download, put into a lib folder under your solution folder and put a pre-build like this :

$(SolutionDir)lib\edmgen2\edmgen2 /FromEdmx $(ProjectDir)prod.edmx”

“%windir%\Microsoft.NET\Framework\v4.0.30319\EdmGen.exe” /mode:ViewGeneration /language:CSharp /nologo “/inssdl:prod.ssdl” “/incsdl:prod.csdl”   “/inmsl:prod.msl” “/outviews:$(ProjectDir)prod.Views.cs”

What you must change on your project?

1. IF you are on 64 bit, change Framework to Framework64

2. change the prod with your edmx name.

What is the performance?

Tested by loading a table with 301 rows by doing the steps :

1. open connection, load all table in objects(POCO), closing connection

2. open connection , find object with PK = 1, closing connection

3. open connection ,  loading 1 tables with 2 related (include ) , closing connection

The results are in milliseconds:

Without pre-compiled views

LoadTable LoadID LoadMultiple Total Time
579 800 172 1551
563 755 171 1489
559 754 169 1482
568 762 240 1570

With pre-compiled views:

LoadTable LoadID LoadMultiple Total Time
606 807 183 1596
509 706 177 1392
852 137 192 1181
530 733 221 1484
523 722 183 1428

The average / min / max results:

average max min
without 1523 1570 1482
with 1413.25 1596 1181

In the next picture the smaller the duration(milliseconds), is the better :

image

Conclusions:

1.  For the average and min the difference is 7%, respectively 20%. Please remember we are using only 3 queries.

For the max, it is vey curious : the with is more than without. The penalty is 1%, I think that is a measuring error ? – or maybe not. However , the penalty is small comparing with others.

2. Very curious, find after ID, with a table with 301 rows, took longer than loading the whole table.However, did not take into accound finding in the list the object( it is in memory also)

3. It may worth to add the pre-build step shown before to pre-compile views.

Links :

http://www.codeproject.com/KB/database/PerfEntityFramework.aspx

http://msdn.microsoft.com/en-us/library/bb896240.aspx

Five common mistakes for ASP.NET (MVC) accesing resources : css, js, images, ajax

To have once for all the link to show to people, because too much makes the same error again and again.

(From here – you can use ResolveUrl or Url.Content – it’s the same for me. I use ResolveUrl because I used first …)

Case 1 The image does not display

Please check you have the following :

<img src='<%= ResolveUrl("~/Content/images/YOURIMAGE.jpg" )%>'  alt="image" style="border:0" />

Case 2 The css does not show

Please check you have the following :

<%= string.Format("<link href='{0}' type='text/css' rel='stylesheet' />", ResolveUrl("~/Content/your.css")) %>

or

<style type="text/css">
@import '<%= ResolveUrl("~/Content/your.css") %>';

</style>

Case 3 The js does not execute (undefined error)

Please check you have the following :

<script type="text/javascript" src='<%= ResolveUrl("~/Scripts/yourjs.js")%>'></script>

Case 4 The js does execute in aspx page, but did not execute under js file

Please check you DO NOT have the following

<%

in the js file. The js file is not interpreted by the same engine as aspx, so can not interpret asp.net tags. Instead , add a parameter to your function : the path.

Simple example : Let’s say in aspx you have :

<script type=”text/javascript”>

function Generate(){

window.open(‘<% Url.Action(“About”)%>’);
}

</script>

and you call Generate();

When you put in .js file, please put this :

function Generate(url){

window.open(url);
}

and call like this :

Generate('<% Url.Action(“About”)%>');

Case 5 The ajax request gives you a 404 error.

Please ensure that you have

<%= ResolveUrl("~/path”)%>

and not

/path

Bonus 1: T4MVC , http://mvccontrib.codeplex.com/releases

Bonus 2: Edit the project file and put <MvcBuildViews>true</MvcBuildViews>

( short url: http://bit.ly/asp5Mistakes)

Generating history trigger with EF , edmx and TT files

I have wrote in an older post ( http://msprogrammer.serviciipeweb.ro/2010/06/28/ef-automatic-history-of-table-and-t4-files-tt-files/ ) how to generate history code for tables . The easy solution was to create a tt file that track for the ObjectContext the SaveChanges for each table that has a “history” in name. the limitation is that , when you raise an sql command such as “update table ” you must load from database a lot of rows for this….

Now I want to show the same thing, but generating triggers in database for that ! I start also from edmx file and with a template stealed from http://forums.asp.net/p/1599616/4083198.aspx ( to have type of fields in the database ) and another stealed and modified from StackOverflow(to generate trigger for after insert , update, delete) I manage to have a solution to generate sql tables and trigger code.

When is that good ?At the beginning stages of a project when the table structure changes by adding a new parameter.

Sample code generated for table Notes(ID, TextNote, PersonID)

print 'Create table Notes_History ';
Create Table Notes_History(
		ID_Notes_History BIGINT IDENTITY NOT NULL
		,History_Action varchar(50)
		,History_From varchar(100) default HOST_NAME()
		,History_User varchar(50) default SYSTEM_USER
		,History_Date varchar(50) default  getdate()
	   ,Id  int   NOT NULL
	   ,Textnote  nvarchar (255)  NULL
	   ,PersonId  int   NULL
	)
print 'end Create table Notes_History ';
GO
print 'create trigger for Notes'
GO
CREATE TRIGGER dbo.TR_IUP_Notes
   ON  Notes
   AFTER INSERT, UPDATE, DELETE
AS
BEGIN
    SET NOCOUNT ON;
	DECLARE @Ins int

DECLARE @Del int

SELECT @Ins = Count(*) FROM inserted

SELECT @Del = Count(*) FROM deleted
if(@Ins  + @Del = 0)
	return;

declare @operation varchar(50)
	set @operation ='update';
	if(@ins < @del)
		set @operation ='delete';
	if(@ins > @del)
		set @operation ='insert';

	if(@ins <= @del)
	begin
		INSERT INTO Notes_History(History_Action ,Id,Textnote,PersonId)
			select @operation ,Id,Textnote,PersonId from deleted
	end
    else
	begin
    INSERT INTO Notes_History(History_Action ,Id,Textnote,PersonId)
			select @operation ,Id,Textnote,PersonId from inserted
	end
END

The drawback of the code : the user that executes is not always the logged sql server user…
Anyway, what you have to do to use this automatically generated history/audit for tables ?

download historysql and modify

string inputFile = @”Model1.edmx”;

from historysql.tt to your edmx name. Then take the generated code and execute in sql server.

First Install of tools for programmer

My primary tools are Visual Studio ( and the Express suite) , Sql Server ( and SQL Server Management Studio )( and the Express suite) and Office (Excel, Word)

Those are the modification that I do every time … I wish there were enabled by default :

For VS2010

Go to=> Tools, Options , Html, Formatting ,Check “ Insert attribute value quotes when typing”

image

This saves me a lot of time , when I put : input type=”text” , the “  are inserted automatically.

For SSMS

Go to=> Tools, Options , Designers , uncheck “Prevent saving changes that require table re-creation”

image

As a developer, I do modify tables … and this wont let me the first time …

For Excel, Word

Alt+F11 (Visual Basic Editor), Tools, Options, Editor Tab, uncheck “Auto syntax check”, check “require variable declaration”

image

“require variable declaration”  :This saves you a lot of time debugging or writing “Option Explicit” .

“Auto syntax check “ : I do not want a message box each time I do an error. The error is seen in red … no need for a Msgbox.

How about you, dear reader ? Do you have programs that require after installation modifying of options ?

ASP.NET MVC Extensions Methods

These are my extensions.

  1. Not display dropdownlist if the Select list is null
    public static MvcHtmlString DropDownListNull(this HtmlHelper html, string Name, SelectList select, object htmlAttributes)
    {
    
    if (select == null)
    return MvcHtmlString.Empty;
    else
     return html.DropDownList(Name, select, htmlAttributes);
    
    }
    
    
  2. Transform Enum to SelectList
    #region enum to list
            private static List<KeyValuePair<long, string>> FromEnum(this Type e)
            {
                List<KeyValuePair<long, string>> kvp = new List<KeyValuePair<long, string>>();
                foreach (var s in Enum.GetValues(e))
                {
                    kvp.Add(new KeyValuePair<long, string>((int)s, s.ToString()));
                }
                return kvp;
            }
            public static SelectList ToSelectList(this Type enumObj)
            {
    
                return new SelectList(enumObj.FromEnum(), "Key", "Value");
    
            }
            #endregion
    
  3. Transform Generic list into a SelectList
                  #region Generic List to SelectItem
            public static SelectList SelectFromList<TItem>(this List<TItem> values,
                Expression<Func<TItem, string>> key, Expression<Func<TItem, string>> value)
            {
                var Key = key.Compile();
                var Value = value.Compile();
                List<KeyValuePair<string, string>> kvp = new List<KeyValuePair<string, string>>(values.Count);
                values.ForEach(item =>
                    kvp.Add(new KeyValuePair<string, string>(Key.Invoke(item), Value.Invoke(item))));
    
                return new SelectList(kvp, "Key", "Value");
    
            }
            #endregion
    
    
  4. Display pager control
    #region paged list control
            //after http://geekswithblogs.net/nuri/archive/2009/08/05/mvc-paged-list.aspx
            /// <summary>
            /// Shows a pager control - Creates a list of links that jump to each page
            /// </summary>
            /// <param name="page">The ViewPage instance this method executes on.</param>
            /// <param name="pagedList">A PagedList instance containing the data for the paged control</param>
            /// <param name="controllerName">Name of the controller.</param>
            /// <param name="actionName">Name of the action on the controller.</param>
            public static void ShowPagerControl(this ViewPage page, BasePagedListImplementation pagedList, string formatUrl)
            {
                HtmlTextWriter writer = new HtmlTextWriter(page.Response.Output);
                if (writer != null)
                {
                    for (int pageNum = 1; pageNum <= pagedList.PageCount; pageNum++)
                    {
                        bool samepage=(pageNum == pagedList.PageNumber);
                        if (!samepage)
                        {
                            writer.AddAttribute(HtmlTextWriterAttribute.Href,string.Format(formatUrl, pageNum));
                            writer.AddAttribute(HtmlTextWriterAttribute.Alt, "Page " + pageNum);
                            writer.RenderBeginTag(HtmlTextWriterTag.A);
                        }
    
                        writer.AddAttribute(HtmlTextWriterAttribute.Class,
                                            pageNum == pagedList.PageNumber ?
                                                                "pageLinkCurrent" :
                                                                "pageLink");
    
                        writer.RenderBeginTag(HtmlTextWriterTag.Span);
                        writer.Write(pageNum);
                        writer.RenderEndTag();
    
                        if (!samepage)
                        {
                            writer.RenderEndTag();
                        }
                        writer.Write("&nbsp;");
                    }
    
                    writer.Write("(");
                    writer.Write(pagedList.TotalItemCount);
                    writer.Write(" items in all)");
                }
            }
    
            #endregion
    
    

Other extensions available that are good :

  1. http://blog.wekeroad.com/blog/asp-net-mvc-list-helper-extension-method/
  2. http://www.hanselman.com/blog/ASPNETMVCSessionAtMix08TDDAndMvcMockHelpers.aspx
  3. http://helios.ca/2009/09/21/asp-net-mvc-extension-methods-of-urlhelper/
  4. http://blog.donnfelker.com/2010/02/25/asp-net-mvc-tempdata-extension-methods/
  5. http://inq.me/post/ASPNet-MVC-Extension-method-to-create-a-Security-Aware-HtmlActionLink.aspx

If you know more, please tell me

Andrei Ignat weekly software news(mostly .NET)

* indicates required

Please select all the ways you would like to hear from me:

You can unsubscribe at any time by clicking the link in the footer of our emails. For information about our privacy practices, please visit our website.

We use Mailchimp as our marketing platform. By clicking below to subscribe, you acknowledge that your information will be transferred to Mailchimp for processing. Learn more about Mailchimp's privacy practices here.