Archive for the ‘ASP.Net’ Category

Posted by OmegaMan at January 15, 2009

Category: Ajax, ASP.Net

Tags: , , , ,

Waiting

This article demonstrates in a step by step fashion how to use the Ajax Control Toolkit’s AutoCompleteExtender control with an animated gif ajax-loader progress indicator while the target dropdown of the AutoCompleteExtender is waiting to be loaded.

This article relies on the fact that you, the developer, already have the toolkit loaded and that a medium level of knowledge of Asp.net, C# and Visual Studio operations are understood. This targets VS2008 SP1, .Net/Asp.net 3.5 SP1,  Ajax Control Toolkit 3.0.20820.

Steps

  1. Create the  animated GIF which will be used. Go to the site AjaxLoad.Infowhere one can create animated loading gifs and download them for free. Use firefox to view the site because one can see the types of icons in the dropdown, on the site, where IE does not. Once done save your the icon to your project.
  2. The Ajax extender will need to call a webservice to get the data. Create a webservice (.asmx oldstyle type), in this example named AjaxServices.asmx. Within that service add, or uncomment out,  the following attribute declaration to allow the service to have communication from the page to the service in a scriptable manner.
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
    [System.Web.Script.Services.ScriptService]
    public class AjaxServices : System.Web.Services.WebService
    {
  3. Create a web method, the actual method name can be anything, but it must have the exactinput parameters and return value as shown below. Note we introduce a delay for this demonstration effect (highlighted line) you will not need to do that. Right. 🙂
    [WebMethod]
    public string[] GetUsers( string prefixText, int count )
    {
        List<string> names
       = new List<string>()
        { "Alpha", "Beta", "Gamma", "Delta", "Omega" };
    
        // Fake delay to see the update gif
        System.Threading.Thread.Sleep( 5000 );
    
        return names.ToArray();
    }
  4. On the web page where the controls will be, add the asp:ScriptManager control. Within the manager we need to let it know our web service we have created and it will be using.
    <asp:ScriptManager ID="ScriptManager1"
        runat="server"
        EnablePartialRendering="true">
    
     <Services>
       <asp:ServiceReference Path="~/AjaxServices.asmx" />
     </Services>
    
    </asp:ScriptManager>
  5. Add three more controls, an asp.net textbox  the autoCompleteExtender and the image gif. Here are the controls all added. Note how the extender references the webservice and webmethod, the textbox and calls a javascript function which we will show in step 6. Change the MinimumPrefixLength to two or three if the data list is quite huge. in your system.
    <table>
    <tr>
        <td>User:&nbsp;&nbsp;</td>
        <td><asp:TextBox ID="tbUser" runat="server"></asp:TextBox></td>
        <td>&nbsp;</td>
        <td><img id="processing" style="visibility:hidden" src="ajax-loader.gif" /></td>
        <td>&nbsp;</td>
        <td><cc1:AutoCompleteExtender
       ID="AutoCompleteExtender1"
       runat="server"
       TargetControlID="tbUser"
       ServicePath="AjaxServices.asmx"
       ServiceMethod="GetUsers"
       MinimumPrefixLength="1"
       EnableCaching="true"
       CompletionSetCount="25"
       onclientpopulating="ShowIcon"
       onclientpopulated="ShowIcon"/>
        </td>
    </tr>
    </table>
  6. The image starts off hidden. We will write a javascript method, to swap its state.  Place the code on the page after the <Head> section. The code has to know the name of the img tag. The code should look like this:
<script language ="javascript">

function ShowIcon() {

    var e = document.getElementById("processing");

    e.style.visibility =  (e.style.visibility == 'visible') ? 'hidden' : 'visible';

}

</script>

That is it! When done and the extender calls the webservice the gif gets displayed and the user knows something is happening. When the processing is done the same javascript method is called to turn it off.

Note: If no data is found, the final hook call to onclientpopulated is not done and the icon will still be displayed. Possibly you can send back text like “No data found”, but that will be populated in the textbox and has its drawbacks. That is the monkey’s paw wish caveat of using this methodology.

Share

Posted by OmegaMan at October 2, 2008

Category: ASP.Net

Tags: , , ,

(Update 03.28.2012 Cleaned up article and verified it  works with Asp.net versions 3.5 and 4.0)

The following ASP.Net article details how to create a ListView, bind it to a Linq query and create a dynamic list of hyperlinks to show on an Asp.net web page in C#. To recreate this, use Visual Studio (VS2008/VS2010/VS 11) and create a default Asp.Net Web Application project all working in the default page setup.

On the screen there will be a button which will cause a refresh to the page when pressed. On that refresh the ListView will be cleared of all data and the button disabled to show that the control has not been rebound to actual data.

Here is what it will look like on its first run with a button and dynamically created html links in a list.

Example showing button and dynamic links

HTML: which has the button and the ListView. We will hand create the LayoutTemplate and the ItemTemplate. Our goal is to have a list of links and dynamically create them. The ItemTemplate is expecting to be bound to Url field and UrlText which Linq will nicely create for us in the code behind.

<asp:Button ID="btnClear" runat="server" Text="Clear" /> 

<br /> 
<asp:ListView ID="lvPanelGroup1" runat="server">     
    <LayoutTemplate>         
        <div>             
            <ul>                 
                <asp:PlaceHolder runat="server" ID="itemPlaceholder" />             
            </ul>         
        </div>     
    </LayoutTemplate>     
    <ItemTemplate>         
        <li>             
            <asp:HyperLink ID="HyperLink1"                            
                           NavigateUrl='<%# Eval("Url") %>'                            
                           runat="server">
                <%# Eval("UrlText") %>
            </asp:HyperLink>         
        </li>     
    </ItemTemplate> 
</asp:ListView>

C#:The following is the code in the PageLoad. Its job is to either bind the data in the ListView using Linq or clear the ListView of all items and disable the control. Notice the Linq code where we create our object to have a Url field and UrlTextField which the ListView will use.

protected void Page_Load(object sender, EventArgs e) 
{ 
    if (IsPostBack == false) 
    {     
        List<string> Titles = new List<string>()        
            { "Title 1", "Title 2", "Title 3", "Fini"};     

        int index = 0;     

        var links = from item in Titles                 
                    select new                 
                            {                     
                                Url = "~Default.aspx?articleid=" + (++index).ToString(),                     
                                UrlText = item                 
                            };     
        lvPanelGroup1.DataSource = links;     
        lvPanelGroup1.DataBind();     
        btnClear.Enabled = true; 
    } 
    else // Clear the ListView 
    {     
        lvPanelGroup1.Items.Clear();     
        lvPanelGroup1.DataSource = null;     
        lvPanelGroup1.DataBind(); 

        // The rebinding will clear the ListView.     
        btnClear.Enabled = false; 
    } 
}

Here is what happens after a button press:

What happens after Clear is pressed.

Hope this helps those learning about the ListView and Linq.

Share

Posted by OmegaMan at July 30, 2008

Category: ASP.Net, MVC

Tags: ,

This application is built on the using the ASP.NET MVC Preview 3 using VC2008. The goal is to show the basics of MVC by creating a basic web site in a step by step manner. This article shows the creation of a basic web site, with login screen, work screen, validation error page and finally a results screen. It shows how to have the pages (views) rendered and data (model) passed between those pages as a state, with a validation of work and upon success the final page.

I like to build MVC ASP.Net web pages because it bespeaks to me of tier architecture. That is one programming paradigm which makes sense because of the separation of the differing layers and being able to work and test the layers outside of their intended box. When one has the ability to modularize actions, it leads to easier understandings of written code but more important easier maintenance. MVC, the Model (data objects), View (GUI look and feel) and Controller (your code which sits in between the user actions and page generation) allow for such modularity of code.

Hint: Most MVC tutorials tell you to get the MVC Toolkit along with the preview. Don’t bother, as of version 3 it is rolled in!

When the opportunity to use a new methodology in creating thin clients came along, I felt it was time to put my GUI architecture knowledge on a diet. As with corporate America, my current contract saw one of the bigwig(s) require that the team make an estimate for the costs of creating a thin client. Of course currently there is no thin client but an established click once winform application. Well when you work for a company that can cut a billion dollars from its budget and ask at the same time to rewrite a solid application, heck why not dream. It is going to happen right. 😉

In that scenario its best to look at the latest and greatest and fortunately this technology bespeaks to the thick client developer. So this is post is some of things I learned in researching it for my company.

Tribal Knowledge: there are three concepts to get to know about this MVC thin application.

Controller

Processing interactions between the user pages and MVC/page generation go here. This is an ISAPI type approach where the controller code, your .net code, intercepts the operations and interacts with it by working with the model data and determining a view.

Model

Contains the application object. Create class objects which represent data and state between the pages.

View

What the user works with/sees the forms.

Code Download

Here is the zipped code to download. Statement.zip

Preparation

Get the latest MVC preview and install it with Visual Studio 2008.

Goals

We will create a statement page, where a typical CSR will enter in search values and be directed to either a failure validation page or the data page. By that we will create a Controller, Model and Views.

Solution Setup

File->New Project->Visual C#->Web->ASP MVC Web Application and name the project Statement. Accept the default Visual Studio Test Project. Once done you will have a solution with two projects.

Statement SolutionThe things to be aware of are the folders found in the project named Controllers, Models and Views. We will be interacting with those folders primarily.  The following sections will detail how to add the models, views and controllers for the individual objects.

The project wizard has created a basic web site with one View (Home) that has two pages, the home/index page and also the about page. All of the pages are based on the Site.Master template. Later when we create pages we will also base our pages off of that site master which gives the pages a foundation which we will not have to mimic on each page. Each page inherits so to speak from that page and only presents the unique information/tags for that page.

There is only one controller out of the box which is the HomeController which intercepts the page requests which will route to the Home views of About and Index. Which brings us to our next topic of routing.

Routing

There have been quite a few articles on routing and I am not going to get into it here. But our goal is to keep with the routing currently setup by the default web site. We will have the user click on a Statement tab and be directed to the Statement views via the a new statement controller.

Note if you haven’t done this, build play around with the default website to get the feel of it.

Model Creation

Solution Explorer: Select the Models folder. Right Click->Add->Class We are going to create a model first. This class will handle the interactions between the pages and is just a basic class with properties. On the Models folder right click and add a class named StatementState which will just be three strings which our pages will be interested in. The class looks like this:

 1:
 2: namespace Statement.Models
 3: {
 4:     public class StatementState
 5:     {
 6:         public string PortfolioID  { get; set; }
 7:         public string CustomerID   { get; set; }
 8:         public string ErrorMessage { get; set; }
 9:     }
 10: }

Site.Master

The file Site.Master, as found in the Views / Shared folder acts as our base template page. It simply acts as a foundation for all future pages to apply their specific business logic on without worrying about the general architecture of the web site. On that page we need to add a link, an Action.Link to our future Statement page for the CSR to enter in the values to search for.  To accomplish that, open the file and add the code with our statement redirection as shown below:

<div id="header">
    <p id="logo">
        <a href="">My Sample MVC Application</a>
    </p>
    <ul id="menu">
        <li>
            <%= Html.ActionLink("Home", "Index", "Home")%>
        </li>
        <!-- Here is our code to add to create and route for our new tab -->
        <li>
           <%= Html.ActionLink("Statement", "Statement", "Statement") %>
       </li>
        <li>
            <%= Html.ActionLink("About Us", "About", "Home")%>
        </li>
    </ul>
</div>

We provide the special server tags with the Html.ActionLink to link/redirect to the Statement view. Go ahead and build the site. The new link tab will be between the home and about.

New Statement Tab

Views

New Statement Folder under Views

We will now add the views, or web pages which our statement operations pages will be joined to the site.master. In this section we will be adding three pages to compliment our view being Statement, ErrorAction and ViewStatement. To prepare for the pages create a Statement folder under the Views folder such as:

The video below demonstrates how to add View Content pages. The below visually shows how to create the Statement page.

Solution Explorer: Select Statement Folder: Right Click->Add->New Item->Visual C#->Web->MVC->MVC View Content Page which will need input and we will specify Statement as the page to create then select Add. The next dialog box Select a Master Page comes up and we can specify that this content page be associated with a particular master template page. Our template page is the site.master page and we will select Statement->Views->Shared->Site.Master and select OK.

We will need to add two more View Content pages just like above but their names will be ErrorAction and ViewStatement.

FinalViewContentPages

Statement View Contents Pages

In the statement page we are going to add two edit boxes to allow for user input specifics about the statement which are a portfolio and customer number. Those two items will be submitted by the form to our controller which we will write later. Here is the code to place in the Statement.aspx page:

<form action="/Statement/StatementSubmit">
   <table>
    <tr>
        <td>Portfolio ID:</td>
        <td><input type="text" name="portfolioID" /></td>
    </tr>
    <tr>
        <td>Customer ID:</td>
        <td><input type="text" name="customerID" /></td>
    </tr>
    </table>
  <input type="submit" value="Submit" />
</form>

We have two other web pages to contend with…the ErrorAction.aspx page will behave similar to the above statement page, but it is a validation target when validation fails and the user needs to be informed of as to the why and prepopulate the fields from the previous screen:

<!-- ErrorAction page to reset variables and inform user of the problem on the originating page -->
<form action="/Statement/StatementSubmit">
<% if (ViewData.Model.ErrorMessage != null) { %>
  <% } %>
   <table>
   <tr><td colspan="2"><fieldset><legend>Validation Failure</legend>
    The following error occurred while inserting the customer data:
    <br />
    <%= ViewData.Model.ErrorMessage%>
    <br />
    </fieldset></td></tr>
    <tr>
        <td>Portfolio ID:</td>
        <td><%= Html.TextBox("portfolioID", ViewData.Model.PortfolioID)%></td>
    </tr>
    <tr>
        <td>Customer ID:</td>
        <td><input type="text" name="customerID" value="<%= ViewData.Model.CustomerID %>"/></td>
    </tr>
    </table>
  <input type="submit" value="Submit" />
</form>

Finally we have the final page where we will take the user’s request and show the actual generated statement:

<!-- ViewStatement ... just regurgitate what the user typed in. -->
<%= Html.Encode(ViewData.Model.PortfolioID)%>
<br />
<%= Html.Encode(ViewData.Model.CustomerID)%>

Note all this code goes in the asp:Content tags!

Linking up with the Model

The final step with the views is to link up with our data model StatmentState. We do that by changing the class definition of both pages which will be using it which are ErrorAction and ViewStatement. We do that by changing how its inheritance.

Solution Explorer: Select Views\Statement\ErrorAction.aspx (then ViewStatment.aspx next) right click->View Code change the class inheritance to this and and the appropriate using:

 1:
 2: public partial class ErrorAction : ViewPage<StatementState>
 3:

This is important otherwise for the when the page is rendered it will access the StatementState class properly. Otherwise rendering will fail with object does not contain XXXX in class. Do the same for ViewStatment.aspx.

Controller

Ok the final frontier to get this to work is the controller. We need to create a StatementController. We will once again use the wizard to create the controller.

Solution Explorer: Select Controllers folder: Right Click->Add->New Item->Visual C#->Web->MVC->MVC Controller Class and name it StatmentController. Once done the wizard will create a class for us with the appropriate signature and plumbing to handle the calls. We just need to add the specifics of that plumbing such as:

 1: using Statement.Models;
 2:
 3: public class StatementController : Controller
 4: {
 5:     public ActionResult Statement()
 6:     {
 7:         ViewData["Title"] = "Statement Page";
 8:         return View();
 9:     }
 10:
 11:     public ActionResult StatementSubmit(string portfolioID, string customerID)
 12:     {
 13:         // TODO: Validate Choices.
 14:
 15:         StatementState state = new StatementState();
 16:
 17:         state.CustomerID = customerID;
 18:         state.PortfolioID = portfolioID;
 19:
 20:         if ( string.IsNullOrEmpty(state.PortfolioID) )
 21:         {
 22:             state.ErrorMessage = "Portfolio ID Required";
 23:             return View("ErrorAction", state);
 24:         }
 25:
 26:         return View("ViewStatement", state);
 27:     }
 28: }
  • Line 01: We need to pull in our data type StatementState which will be passed between the pages.
  • Line 05: This is needed when the user is directed to the Statement page. We handle the initial setup here.
  • Line 07: We will use the existing system to have the page sub title shown.
  • Line 08: The we simply say view it to display!
  • Line 15: Here is what we will pass to either the ErrorAction page or the final ViewStatement page.
  • Line 17: Assign the current value of the post to our state object for customer ID.
  • Line 18: Assign the current value of the post to our state object for the portfolio ID.
  • Line 20: We only have one validation rule…that is no empty portfolio number.
  • Line 22: Inform the user that they need to fill in the portfolio ID.
  • Line 23: Launch the ErrorAction page and pass in our specific model data. Its a nice way to redirect….
  • Line 26: Everything is fine…pass the info onto the view state to show.

That is it. Run the application, see how the validation will catch an empty portfolio ID and how it works in general.

We have a basic website built upon the foundation which Microsoft has given us. As MVC matures, this technology will only get better. I like were it is heading. Hope this little intro has helped you.

Share