Archive

Archive for the ‘VB.NET’ Category

Sys.WebForms.PageRequestManagerServerErrorException

Followed by:Object reference not set to an instance of an object.
I was struggling in an old Asp.Net site, which is using Microsoft Ajax Toolkit, with this error.

In order to reduce the postbacks i used some jquery for partial page updates, and using a simple html select with a button for change the parameter to a REST call, i got this error.
The problem solution is very simple.. the HTML button tag by default causes a postback, and the error was caused from a null value in the Page_Load event of the behind code: the button type must be “button”, otherwise without specifying the type is considered as “submit”.

Then the HTML is:

<button id="cmdUpdateByFilter" onclick="updateSint ();" type="button" class="Botton">Update</button>

Categories: .NET, Ajax, HTML5, VB.NET

Regex grouping for automatic coding

Sometimes is requested to do ugly and repetitive tasks.
For example there were some .aspx pages where in a DataGrid was written the DataField for monthly columns, but not the HeaderText (i don’t know why..).
Copy & paste, ok only 13 columns: but a lot of .aspx pages.
So i thinked to an substitution using regular expressions.
Tipically we have a string delimited with a double quotation mark, that we can express as

DataField=(["'])(.*?)\1

Or

DataField=(["'])(.*?)(["'])

Both are explainable as: the string begin with a ‘ or an ” , there could be an variable amount of chars or numbers and then there is a final ‘ ( or “)
The trick is in the parenthesis () , that isolates an regex group.
I use an old but valid tool, the Rad Software Regular Expressions Designer (the website is no more available), the basilar syntax is
0regex
If we introduce an group
1regex
We have surrounded with () the [“‘] expression, and there is a group ‘1’ referred to the char “.
The \1 is a regex reference to the first group (if you delete the parenthesis around [“‘] there is an error while evaluating the regex).
By using
2regex
We isolate the text between the ” couple.
Using the regex expression $<number> we can refer to these groups, so in Notepad++ i used
notepad
And for every DataField with the Replace All is created the HeaderText with the same month name.

Categories: RegEx, VB.NET

maxJsonLength property

I was working on a asp:DataGrid table , where in every cell there is an asp:Textbox for immediate editing (think to a sort of Excel).
Then with an html button is called the javascript method save:

function save() {
    $get('ContentPlaceHolder1_UpdateProgress1').style.display = 'block';
    var strSql = "";
    var strPartSql = "";
    $("input.editqt").each(function () {
        var strHtmlId = this.id;
        var arrValues = strHtmlId.split("_");
        var strId = arrValues[1];
        var strValue = $("#" + strHtmlId).val();
        if (strValue.trim() === "")
            strValue = "0";
        strPartSql = "UPDATE TSG123_VoyageRes SET Qt = " + strValue + " WHERE ID_Voyage_Res = " + strId + "; ";
        strSql += strPartSql;
    });
    PageMethods.SaveMatrix(strSql, saveCallback, saveErrorCallback, "save");
}

function saveCallback(result, response, context) {
    $get('ContentPlaceHolder1_UpdateProgress1').style.display = 'none';
    window.alert("Save success.");
}

function saveErrorCallback(result, response, context) {
    $get('ContentPlaceHolder1_UpdateProgress1').style.display = 'none';
    if (result._timedOut)
        window.alert("Timeout saving");
    else {
        if (result !== null)
            window.alert(result.get_message());
        else
            window.alert("Error saving.");
    }
}

The javascript code calls an PageMethod (the web site uses ASP.NET 4, VB.NET , Microsoft Ajax Toolkit), defined as:

<System.Web.Script.Services.ScriptMethod(), System.Web.Services.WebMethod()> _
Public Shared Sub SaveMatrix(ByVal sql As String)
    UserFrameworkClass.AccessDB.Database.SetData(sql, Data.CommandType.Text)
End Sub

In practice from the javascript side is generated (not the best method..) a long SQL string, in the Page method is launched “as is” into SQL Server.
At a certain point the datagrid became bigger, and trying to save , crash: error from javascript:
“Error during serialization or deserialization using the JSON JavaScriptSerializer. The length of the string exceeds the value set on the maxJsonLength property.”
The solution was to add these lines in web.config:

<system.web.extensions>
  <scripting>
    <webServices>
      <jsonSerialization maxJsonLength="2147483647"/>
    </webServices>
  </scripting>
</system.web.extensions>

No more errors, until these pages will be rewritten in a more solid manner.

Categories: .NET, Ajax, VB.NET, Vs2013

Arbitrary values in asp:Datagrid

Working at a ships loading planner, i received this request: we can have more work turns, for every turn one or more squads (from 1 to 5).

But there should be an optional special squad , the “0” squad, that must be represented with the “SA” string; note also that only on the first row for every turn must be visible an Word export icon.

The work turn on the db is an Int.. how to write “SA”?

We are speaking of an .NET 4 solution, using VB.NET, the DataGrid is defined as

<asp:DataGrid ID="DG" runat="server" AutoGenerateColumns="False" ShowHeader="true"
    EnableViewState="true" CssClass="DGBorder" Width="99%" Height="1%" HorizontalAlign="left">
    <AlternatingItemStyle CssClass="DGRow2" />
    <SelectedItemStyle CssClass="DGSelect" />
    <ItemStyle CssClass="DGRow1" />
    <HeaderStyle />
    <Columns>
        <asp:BoundColumn DataField="Day" HeaderText="Date" DataFormatString="{0:dd/MM/yyyy}">
            <ItemStyle CssClass="DGBorder" Width="200px" HorizontalAlign="Left" />
            <HeaderStyle HorizontalAlign="Center" Width="200px" />
        </asp:BoundColumn>
        <asp:BoundColumn DataField="Turn" HeaderText="Turn">
            <ItemStyle CssClass="DGBorder" Width="100px" HorizontalAlign="Left" />
            <HeaderStyle HorizontalAlign="Center" Width="100px" />
        </asp:BoundColumn>
        <asp:BoundColumn DataField="Hours" HeaderText="Hours">
            <ItemStyle CssClass="DGBorder" Width="3em" HorizontalAlign="Center" />
            <HeaderStyle HorizontalAlign="Center" Width="3em" />
        </asp:BoundColumn>
        <asp:BoundColumn DataField="Squad" HeaderText="Squad">
            <ItemStyle CssClass="DGBorder" Width="100px" HorizontalAlign="Center" />
            <HeaderStyle HorizontalAlign="Center" Width="100px" />
        </asp:BoundColumn>
        <asp:ButtonColumn DataTextField="Squad" HeaderText="Fold" DataTextFormatString="<img src=Imgs\word.png border=0>" CommandName="PrintFold">
            <ItemStyle CssClass="DGBorder" Width="100px" HorizontalAlign="Center" />
            <HeaderStyle HorizontalAlign="Center" Width="100px" />
        </asp:ButtonColumn>
    </Columns>
</asp:DataGrid>

The solution is the SetRenderMethodDelegate method:

Protected Sub DG_ItemCreated(sender As Object, e As System.Web.UI.WebControls.DataGridItemEventArgs) Handles DG.ItemCreated
    If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingItem Or e.Item.ItemType = ListItemType.SelectedItem Then
        Dim drv As DataRowView = TryCast(e.Item.DataItem, DataRowView)
        If drv Is Nothing Then
            Exit Sub
        End If
        If strDataRif = String.Empty Then
            strDataRif = drv.Row("Day").ToString()
            strTurnoRif = drv.Row("Turn").ToString()
        End If
        strTempData = drv.Row("Day").ToString()
        strTempTurno = drv.Row("Turn").ToString()
        If strTempData <> strDataRif Or strTempTurno <> strTurnoRif Or boolForceFirst Then
            strDataRif = strTempData
            strTurnoRif = strTempTurno
            boolForceFirst = False
            ' 3 = position of column, starting from 0 , in DataGrid
            e.Item.Controls(3).SetRenderMethodDelegate(New RenderMethod(AddressOf RenderCustom))
        Else
            e.Item.Controls(4).Controls(0).Visible = False
        End If
    End If
End Sub

Protected Sub RenderCustom(ByVal writer As System.Web.UI.HtmlTextWriter, ByVal Container As System.Web.UI.Control)
    If DirectCast(Container, System.Web.UI.WebControls.TableCell).Text = "1" Then
        writer.Write("1")
    Else
        writer.Write("SA")
    End If
End Sub

If we asked to create the SA squad, we have 0 as number and then must be changed with “SA” , otherwise the squad numbering begins with 1 and must not be changed.
The result:

grid

Categories: .NET, VB.NET, Vs2013

Autocomplete extender with Id and Description

It was a very long time ago that i worked with the Ajax Toolkit, but sometimes you are requested to implement old projects..

And the language is VB.NET, that i was not using since 2003.

The request was to implement an Autocomplete extender from a customers list (from a Sql Server table), but in the database is requested to write the autoincrement ID, not the description.

In order to implement the ajax toolkit, in the .aspx markup must be added the header:

<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="cc1" %>

With the obvious adding of a reference , for the ASP.NET project, to AjaxControlToolkit.dll

A simple autoextender can be written as

<asp:TextBox ID="txtAgency" runat="server" ></asp:TextBox>
<cc1:AutoCompleteExtender ID="aceAgency" FirstRowSelected="false" MinimumPrefixLength="1" TargetControlID="txtAgency" ServiceMethod="GetListAgencies" runat="server">
</cc1:AutoCompleteExtender>

in the aspx page; in the code behind for this page we can implement a page method (the “ServiceMethod”) as

<System.Web.Script.Services.ScriptMethod(), _
System.Web.Services.WebMethod()> _
Public Shared Function GetListAgencies(ByVal prefixText As String, ByVal count As Integer) As List(Of String)
    Dim conn As SqlConnection = New SqlConnection
    '
    conn.ConnectionString = <string from web.config>
    Dim cmd As SqlCommand = New SqlCommand
    cmd.CommandText = "SELECT AnagId, AnagName FROM [dbo].[SomeTableOrView] WHERE AnagName LIKE @SearchText + '%'"
    cmd.Parameters.AddWithValue("@SearchText", prefixText)
    cmd.Connection = conn
    conn.Open()
    Dim lstAgencies As List(Of String) = New List(Of String)
    Dim sdr As SqlDataReader = cmd.ExecuteReader
    While sdr.Read
        lstAgencies.Add(sdr("AnagName").ToString))
    End While
    conn.Close()
    Return lstAgencies
End Function

This works, we type one letter (MinimumPrefixLength=”1″) on the keyboard and we are proposed with the list of names beginning with the typed letter.

But from the database in our sample we have only the AnagName value , the AnagId is not connected in some manner with the selected item: if we need to save that Id instead of the name this approach is not valid.

In order to save that id we need some javascript code and another approach in the web method.

First, this is the new aspx markup:

<asp:TextBox ID="txtAgency" runat="server"></asp:TextBox>
<cc1:AutoCompleteExtender ID="aceAgency" FirstRowSelected="false" TargetControlID="txtAgency" ServiceMethod="GetListAgencies" OnClientHidden="onClientHiddenAgency" MinimumPrefixLength="1"  EnableCaching="true" OnClientItemSelected="onClientItemSelectedAgency" OnClientPopulating="onClientPopulatingAgency" runat="server">
</cc1:AutoCompleteExtender>
<input type="hidden" id="hdnAgencyId" name="hdnAgencyId" runat="server" value="0" />

The OnClient… properties are the names of javascript functions; the EnableCaching is true because the underlying data are in this case very static.

Note that there is an hidden field where to save the requested Id and this is runat=server because we need to refer this field when we will save the record.

The javascript functions (ok, not the best javascript code…):

var boolChosenAgency = false;

function onClientItemSelectedAgency(source, e) {
    window.document.getElementById("<%=hdnAgencyId.ClientID%>").value = e.get_value();
    boolChosenAgency = true;
}

function onClientHiddenAgency(source, e) {
    if (!boolChosenAgency) {
        window.document.getElementById("<%=hdnAgencyId.ClientID%>").value = "0";
        window.document.getElementById("<%=txtAgency.ClientID%>").value = "";
    }
}

function onClientPopulatingAgency(source, e) {
    window.document.getElementById("<%=hdnAgencyId.ClientID%>").value = "0";
    boolChosenAgency = false;
}

What happens with this code is:

  • When the user begins to write, the Id value is changed to 0 and boolChosenAgency is set to false (“the user has not stille chosen an valid value”)
  • Only when an item is chosen the Id (coming from e.get_value()) is written in the hidden field
  • OnClientHiddenAgency is always executed, if the user has opened the list but has not clicked on a value then the id value is changed to 0

On the code behind so we must verify : if the hidden id is 0 and/or the textbox is empty the the id must be null on the db, otherwise we can write the int value.

The scope of the code is also: if the user write a not valid text, the Id is invalidated.

But how we can have the id in e.get_value() ?

This is done with this code for the web method:

<System.Web.Script.Services.ScriptMethod(), _
System.Web.Services.WebMethod()> _
Public Shared Function GetListAgencies(ByVal prefixText As String, ByVal count As Integer) As List(Of String)
    Dim conn As SqlConnection = New SqlConnection
    '
    conn.ConnectionString = <string from web.config>
    Dim cmd As SqlCommand = New SqlCommand
    cmd.CommandText = "SELECT AnagId, AnagName FROM [dbo].[SomeTableOrView] WHERE AnagName LIKE @SearchText + '%'"
    cmd.Parameters.AddWithValue("@SearchText", prefixText)
    cmd.Connection = conn
    conn.Open()
    Dim lstAgencies As List(Of String) = New List(Of String)
    Dim sdr As SqlDataReader = cmd.ExecuteReader
    While sdr.Read
        lstAgencies.Add(AjaxControlToolkit.AutoCompleteExtender.CreateAutoCompleteItem(sdr("AnagName").ToString, sdr("AnagID").ToString))
    End While
    conn.Close()
    Return lstAgencies
End Function

The trick is done using the CreateAutoCompleteItem method as in the above code.

In the javascript code we can use e.get_value for the ID and e.get_text() for the name (“AnagName” in the sample).

Categories: .NET, Ajax, Javascript, VB.NET, Vs2010