The AppLife Update Blog

  • Available Updates .aspx Page

    As you publish updates using AppLife Update, the information about the available updates is available to your deployed applications. Using the Update Controller, your deployed applications can easily check for updates over http, ftp, unc, or file path. Using the Update Controller, you can investigate the available updates programmatically through the Update Controller API. But what about presenting a list of available updates to a human user via a web page? Shouldn’t that be just as easy? Turns out, it is, but it doesn’t appear so at first glance.

    Let’s instantiate an Update Controller in an aspx page code behind and see what happens.

       1:  protected void Page_Load(object sender, EventArgs e) {
       2:    using(UpdateController controller = new UpdateController()) {
       3:      //all we need to just check for updates is an update location and application id
       4:        controller.UpdateLocation = "http://localhost/updates/myapp";
       5:        controller.ApplicationId = new Guid("288b93ae-0795-47bf-959e-06dc96434d43");
       6:   
       7:        if(controller.CheckForUpdate()) { 
       8:          //display update information
       9:        }
      10:    }
      11:  }

    We get an ugly error about starting an asynchronous operation.

    image

    Download the attached aspx form and code-behind for a complete working example.

    image

    Even though the CheckForUpdate method is synchronous to the calling code, it uses an asynchronous method under the hood and the asp.net page doesn’t like that. To get around this, we’ll use a PageAsyncTask object to execute the update check between the page prerender and prerender complete processing steps. To accomplish this, we’ll move our update checking code to its own method, and then create and register a PageAsyncTask to execute it.

       1:  protected void Page_Load(object sender, EventArgs e) {
       2:    PageAsyncTask asyncTask = new PageAsyncTask(
       3:             new BeginEventHandler(BeginCheckForUpdate),
       4:             new EndEventHandler(EndCheckForUpdate),
       5:             new EndEventHandler(CheckForUpdateTimeout), null);
       6:              
       7:    RegisterAsyncTask(asyncTask);
       8:  }
       9:   
      10:  IAsyncResult BeginCheckForUpdate(object sender, EventArgs e, AsyncCallback cb, object state) {
      11:    return null;
      12:  }
      13:   
      14:  void EndCheckForUpdate(IAsyncResult ar) {
      15:               
      16:  }
      17:   
      18:  void CheckForUpdateTimeout(IAsyncResult ar) {
      19:               
      20:  }
      21:   
      22:  private void checkForUpdate() {
      23:    using(UpdateController controller = new UpdateController()) {
      24:      //all we need to just check for updates is an update location and application id
      25:      controller.UpdateLocation = "http://localhost/updates/myapp";
      26:      controller.ApplicationId = new Guid("288b93ae-0795-47bf-959e-06dc96434d43");
      27:   
      28:      if(controller.CheckForUpdate()) {
      29:        //display update information
      30:      }
      31:    }
      32:  }

    The code above gets us almost there. We have an asynchronous task plumbed in, but because the controller’s CheckForUpdate method isn’t really an asynchronous method, we don’t have an IAsyncResult interface readily available to plug into the async task. If we use a delegate method, we can slip our “synchronous call” into an asynchronous context.

       1:  public partial class AvailableUpdatesPage : System.Web.UI.Page {
       2:    private Action mCheckForUpdateWork; //Use a delegate for IAsyncResult context
       3:   
       4:    protected void Page_Load(object sender, EventArgs e) {
       5:      PageAsyncTask asyncTask = new PageAsyncTask(
       6:                        new BeginEventHandler(BeginCheckForUpdate),
       7:                        new EndEventHandler(EndCheckForUpdate),
       8:                        new EndEventHandler(CheckForUpdateTimeout), null);
       9:   
      10:      RegisterAsyncTask(asyncTask);
      11:    }
      12:   
      13:    IAsyncResult BeginCheckForUpdate(object sender, EventArgs e, AsyncCallback cb, object state) {
      14:      mCheckForUpdateWork = new Action(checkForUpdate);
      15:      return mCheckForUpdateWork.BeginInvoke(cb, state);
      16:    }
      17:   
      18:    void EndCheckForUpdate(IAsyncResult ar) {
      19:      mCheckForUpdateWork.EndInvoke(ar);    
      20:    }
      21:   
      22:    void CheckForUpdateTimeout(IAsyncResult ar) {
      23:      mCheckForUpdateWork.EndInvoke(ar);
      24:    }
      25:   
      26:    private void checkForUpdate() {
      27:      using(UpdateController controller = new UpdateController()) {
      28:        //all we need to just check for updates is an update location and application id
      29:        controller.UpdateLocation = "http://localhost/updates/myapp";
      30:        controller.ApplicationId = new Guid("288b93ae-0795-47bf-959e-06dc96434d43");
      31:         
      32:        if(controller.CheckForUpdate()) {
      33:          //display update information
      34:        }
      35:      }
      36:    }
      37:  }

    All that’s left to do is set the Async page directive to true and this page will successfully perform an update check, where we can then use the controller API to manipulate the display of the available information.

    <%Page Language="C#" AutoEventWireup="true" CodeBehind="..." Inherits="..."
     Async="true" AsyncTimeout="30"%>

    The example page creates an asp.net Repeater object to format and display each of the available updates on the web page. We can then simply DataBind the AvailableUpdates collection of the update controller to the repeater.

       1:  if(controller.CheckForUpdate()) {
       2:    //display update information
       3:    rptrUpdateList.DataSource = controller.AllUpdates;
       4:    rptrUpdateList.DataBind();
       5:  }

    Posted at 31 October, 2013 | By :Brian Haas | Categories : AppLife Update |