Monday, November 3, 2014

ASP.NET: Force client to update javascript files after each new build


Problem

How to force a client to update cached javascript files after each new build

Solution

Add build number property to your page class

Protected ReadOnly Property CurrentVersion() As Integer
        Get
            Return System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.Build
        End Get
End Property

And update script source to utilize the build number property


<script src="Script/Functions.js?v=<%= CurrentVersion%>" type="text/javascript"></script>


After each new build script source url is changed so browser will update javascript-file to the cache


Wednesday, December 5, 2012

EF 4: How to execute stored procedure with Entity Framework Code First?


Problem

How to execute stored procedure with Entity Framework Code First?

Solution

This would execute a stored procedure which returns a single integer value as result
using (var db = new MyEntities())
{
 var param1 = new System.Data.SqlClient.SqlParameter("@param1", 1000);
 var param2 = new System.Data.SqlClient.SqlParameter("@param2", 2000);
 int? result = db.Database.SqlQuery("MySproc @param1, @param2", param1, param2).FirstOrDefault();
}

This would execute a stored procedure which returns a table data as result
using (var db = new MyEntities())
{
 var cmd = db.Database.Connection.CreateCommand();
 cmd.CommandText = "MyStoredProc @param1, @param2, @param3";
 cmd.Parameters.Add(new System.Data.SqlClient.SqlParameter("@param1", 1300));
 cmd.Parameters.Add(new System.Data.SqlClient.SqlParameter("@param2", 60));
 cmd.Parameters.Add(new System.Data.SqlClient.SqlParameter("@param3", false));

 db.Database.Connection.Open();
 var reader = cmd.ExecuteReader();
 while (reader.Read())
 {
  var resultvalue1 = reader.GetValue(0);
  var resultvalue2 = reader.GetValue(1);
 }
 db.Database.Connection.Close();
}

Friday, June 8, 2012

ASP.NET MVC: How to get model values from separate javascript file


Problem
How to get ASP.NET MVC model values from separate javascript file?

Solution
There are many ways to get model values from separate javascript file. Here are a couple of way to do it:

1. If you are using HTML5 you can use custom data attributes
 <div id="baseTargetUrl" data-basetargeturl="<%= Url.Content("~/") %>" />  
and get custom attribute value from javascript file
 var rootUrl = location.protocol + '//' + location.host +  
 $('#baseTargetUrl').data('basetargeturl');  
2. Set javascript variable from view
 <script type="text/javascript">  
 var baseTargetUrl= <%= Url.Content("~/") %>;  
 </script>  
and use this variable from separate javascript file

3. Extend jQuery to allow own namespace to store values. Here is a great example how to do it

Wednesday, March 28, 2012

WinForms and C#: How to sort a ListView by column

Problem

How to sort a "WinForms.ListView" content when one of the columns are clicked

Solution

I don't remember where I found this great Sorter-class but just copy-paste it to your project as a new ListViewSorter class
public class ListViewSorter : System.Collections.IComparer
{
        public int Compare(object x, object y)
        {
            int result = 0;

            if (!(x is ListViewItem))
            {
                return result;
            }
            if (!(y is ListViewItem))
            {
                return result;
            }

            // Determine whether the type being compared is a date type.
            try
            {
                System.DateTime firstDate = DateTime.Parse(((ListViewItem)x).SubItems[ByColumn].Text);
                System.DateTime secondDate = DateTime.Parse(((ListViewItem)y).SubItems[ByColumn].Text);
                result = DateTime.Compare(firstDate, secondDate);
            }
            catch
            {        
                // Compare the two items as a string. 
                result = String.Compare(((ListViewItem)x).SubItems[ByColumn].Text, ((ListViewItem)y).SubItems[ByColumn].Text);
            }

            // Determine whether the sort order is descending. 
            if (((ListViewItem)x).ListView.Sorting == SortOrder.Descending)
            {
                // Invert the value returned by compare. 
                result *= -1;
            }

            LastSort = ByColumn;
            return result;
        }

        public int ByColumn
        {
            get { return Column; }
            set { Column = value; }
        }
        int Column = 0;

        public int LastSort
        {
            get { return LastColumn; }
            set { LastColumn = value; }
        }
        int LastColumn = 0;
}

After your class is ready you must declare a sorter object in the form:
private ListViewSorter listSorter = new ListViewSorter();

and create a new event for ListView ColumnClick to handle sorting
private void listMyList_ColumnClick(object sender, ColumnClickEventArgs e)
{
        listMyList.ListViewItemSorter = listSorter;
        if (listSorter.LastSort == e.Column)
        {
            // Change sort order for current column
            if (listMyList.Sorting == SortOrder.Ascending)
            {
                listMyList.Sorting = SortOrder.Descending;
            }
            else
            {
                listMyList.Sorting = SortOrder.Ascending;
            }
        }
        else
        {
            listMyList.Sorting = SortOrder.Descending;
        }
        listSorter.ByColumn = e.Column;
        listMyList.Sort();
}

Thursday, March 22, 2012

ASP.NET: How to pass value back from user control to the page with events

Problem
This is simple tutorial how to pass a value back from user control to the page with event. In this example textbox value is passed back to the label on default page

Solution
After creating a new web site with default page create a simple user control called InputBox. Inputbox should have one TextBox and two buttons

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="InputBox.ascx.cs" Inherits="Testi.InputBox" %>
<table>
    <tr>
        <td colspan="2">
            <asp:Label ID="lblUserInput" runat="server" Text="User input:"></asp:Label>
        </td>
    </tr>
    <tr>
        <td colspan="2">
            <asp:TextBox ID="txtUserInput" runat="server"></asp:TextBox>
        </td>
    </tr>
    <tr>
        <td>
            <asp:Button ID="btnOk" runat="server" Text="OK" onclick="btnOk_Click" />
        </td>
        <td>
            <asp:Button ID="btnCancel" runat="server" Text="Cancel" 
                onclick="btnCancel_Click" />
        </td>
    </tr>
</table>

Open user control code-behind and create a new EventArgs class

public class InputEventArgs : EventArgs
{
    public string UserInput{ get; set; }
}
Then add two events to the user control which uses InputEventArgs

    public event EventHandler<InputEventArgs> OKClicked;
    public event EventHandler<InputEventArgs> CancelClicked;

Add following code to the OK and Cancel -button event handlers to fill InputEventArgs:

        protected void btnOk_Click(object sender, EventArgs e)
        {
            // Create a new event argument when OK is clicked
            if (OKClicked != null)
            {
                EventHandler<InputEventArgs> tmp = OKClicked;
                if (tmp != null)
                {
                    // Take value from textbox 
                    tmp(this, new InputEventArgs() { UserInput = txtUserInput.Text });
                }
            }
        }

        protected void btnCancel_Click(object sender, EventArgs e)
        {
            // Create a new event argument when Cancel is clicked
            if (CancelClicked != null)
            {
                EventHandler<InputEventArgs> tmp = CancelClicked;
                if (tmp != null)
                {
                    tmp(this, new InputEventArgs() { UserInput = null });
                }
            }
        }
Now you can open your default.aspx page and register user control

<%@ Register TagPrefix="Test" TagName="InputBox" Src="InputBox.ascx" %>

Add the user control and result label inside form

        <table>
            <tr>
                <td>
                    <b>For example you can place this user control inside modal confirmation...</b>
                </td>
            </tr>
            <tr>
                <td>
                    <Test:InputBox ID="inputBox" runat="server" OnOKClicked="InputBox_OKClicked" 

OnCancelClicked="InputBox_CancelClicked" />
                </td>
            </tr>
            <tr>
                <td>
                    <b>Display input value from user control:</b>
                </td>
            </tr>
            <tr>
                <td>
                    <asp:Label ID="lblInputBoxResult" runat="server" Text=""></asp:Label>
                </td>
            </tr>
        </table>


Then open default page code-behind and create two event handlers to handle clicks from user control

        protected void InputBox_OKClicked(object sender, InputEventArgs e)
        {
            lblInputBoxResult.Text = e.UserInput;
        }

        protected void InputBox_CancelClicked(object sender, InputEventArgs e)
        {
            lblInputBoxResult.Text = "User clicked cancel";
        }


Now you can run and test if value from user control is passed to the event handler at default page...

Friday, September 16, 2011

.NET Framework 4: Unable to cast object of type 'system.string' to type

Problem

For example you are binding pricelist-objects to a combobox in WinForms application like this

cmbPricelist.DataSource = BL.GetPricelists();
cmbPricelist.ValueMember = "PricelistCode";
cmbPricelist.DisplayMember = "PricelistName";

and later you trying to get selected item from combobox like this

Pricelist p = (Pricelist)cmbPricelist.SelectedValue;

you might get an error "Unable to cast object of type 'system.string' to type..."

Solution

If you are using .NET Framework 4 Client profile ComboBox.SelectedValue method returns object (in this example Pricelist).

But if you are using .NET Framework 4 Full profile ComboBox.SelectedValue method returns ValueMember as String

Monday, July 4, 2011

ASP.NET: Prevent button double-click

Problem

How to prevent button double-click on ASP.NET page

Solution

Add following code to Page_load. This code prevents button double-click on client-side but still executes code at server-side:

VB.Net

btnSave.Attributes.Add("onclick", " this.disabled = true; " + ClientScript.GetPostBackEventReference(btnSave, Nothing) + ";")

C#

btnSave.Attributes.Add("onclick", " this.disabled = true; " + ClientScript.GetPostBackEventReference(btnSave, null) + ";");