zoukankan      html  css  js  c++  java
  • Azure完整实例:在线日程表

    在本文中,流牛木马为大家演示一个完整的Azure程序开发实例:在线日程表。跟上一个实例Stick Love 的仅能新增、读取实体相比,本次的数据实体稍微复杂,对数据的操作包括完整的增、删、改、查(CRUD),并增加了与Windows Live Id集成验证身份的功能。

    本项目的前身是给老婆的一个办公系统里的小巧私用日程表,现将其提取出来,集合LiveId使之通用。老婆大人功不可没。

    (如果你以前从未了解过Azure,请查看这里。)

    在线演示:http://live.cloudapp.net/

    界面截图:

    6

    重点步骤:

    一、集成Live Services

        在以前的文章中我们提到过,Live Services是Azure Services Platform的组成部分。Live Services包括了很多内容,今天我们要使用的是Windows Live Tools 里的集成LiveId身份验证功能。

        其实在Azure发布前,Live就开放了其LiveId的API接口。不过那时比较麻烦,今天的Windows Live Tools跟Azure配合的天衣无缝,为开发人员省力不少。

    1.    首先,打开VS2008,新建一个空白Cloud应用程序。
    2. 在Roles上单击右键,选择“New Web Role Project”,并选择Windows Live Web Role,如下两图所示。12
    3. 此时,设计视图的工具栏(Toolbar)中将出现Windows Live的控件组。包含各种很酷的服务。最好玩当然是MessagerChat了,是网页MSN聊天的控件!当然今天不介绍它。今天我们使用能够快捷集成LiveId身份验证的IDLoginStatus控件。如下图:将IDLoginStatus控件拖放到右侧的页面中。3
    4. 拖完控件后,只需要做简单的配置就可以使用了。方法是点击IDLoginStatus控件右侧的小箭头,选择“Configure Application ID”,将这个控件与你Azure平台上的应用程序ID进行绑定。
      5
    5. 搞定了!在之后的开发中,就不用维护登录状态了。为了使没有放置IDLoginStatus控件的页面能够使用LiveId,我们需要在用户登录时,把用户的信息写入Session中。我的方法如下:
      protected void IDLoginStatus1_ServerSignIn(object sender, Microsoft.Live.ServerControls.AuthEventArgs e)
            {
                Session["LiveId"] = IDLoginStatus1.ApplicationUserID;
            }
      这样,在未放置IDLoginStatus控件的页面,我们可以通过判断Session["LiveId"]的值来取得用户的身份信息。

    二、创建实体和数据服务

               和Stick Love类似,我们需要创建实体和数据服务。(详细的步骤请参考基础章节)

      1. 数据实体Schedule.cs
        public class Schedule: Microsoft.Samples.ServiceHosting.StorageClient.TableStorageEntity
         
        {
              publicSchedule()
              {
                  PartitionKey = "000000";
                  RowKey = (DateTime.MaxValue.Ticks - DateTime.Now.Ticks).ToString();
              }

              public stringId { get; set; }
              public stringTask { get; set; }

              publicDateTimeBuildDate { get; set; }

              public stringLiveId { get; set; }
          }
      2. 创建数据服务ScheduleDataServiceContext.cs(增删改查功能)
        public class ScheduleDataServiceContext: TableStorageDataServiceContext
           {
               public ScheduleDataServiceContext(StorageAccountInfo accountInfo)
                   : base(accountInfo)
               {
               }
        
               //定义公共属性Schedules
               public IQueryable<Schedule> Schedules
               {
                   get
                   {
                       return this.CreateQuery<Schedule>("Schedules");
                   }
               }
        
               //添加一个Schedule
               public void AddSchedule(Schedule c)
               {
                   this.AddObject("Schedules", c);
                   this.SaveChanges();
               }
        
               //删除一个Schedule
               public void DelSchedule(Schedule c)
               {
                    this.AttachTo("Schedules", c, "*");
                   this.DeleteObject(c);
                   this.SaveChanges();
               }
        
               //修改一个Schedule
               public void UpdateSchedule(Schedule c)
               {
                   this.AttachTo("Schedules", c, "*");
                   this.UpdateObject(c);
                   this.SaveChanges();
               }
           }
        大家注意到,删除操作和修改操作的时候,需要先使用this.AttachTo("Schedules", c, "*")指明实体的位置。

            

    三、AJAX前台调用

           前台采用jquery实现简单的AJAX,包括“增删改查”数据的前台调用。修改、删除、增加数据都大同小异,以更新数据为例,前台js函数为:

    //更新任务信息
    function updateTask() {
        var taskId = $("#taskId").val();                //任务编号
        var taskInfo = $("#editTaskInfo").val();        //任务内容
        //检查任务信息是否为空
        if ($.trim(taskInfo)=="") {
            alert("Please input task information.");
        } else {
        $.post("Calendar.aspx",                    //服务器页面地址
                {
                    action: "updateTask",               //action参数
                    taskId: taskId,                     //年月参数
                    taskInfo: taskInfo                  //任务信息参数
                },
                function() {                            //回调函数
                    $("#task" + taskId).html(taskInfo); //更新页面任务内容
                    closeEditBox();                     //关闭编辑box
                }
            );
        }
    其中Calendar.aspx页面是AJAX调用的页面,即后台主功能页面。
    此外,前台还需要做的工作是通过AJAX读取JSON格式的数据并填充。
    /从服务器获取任务信息
    function getTasks() {
        $.getJSON("Calendar.aspx",               //服务器页面地址
            {
                action: "getTasks",             //action参数
                month: year + "-" + (month + 1) //年月参数
            },
            function(json) {                    //回调函数
                //遍历JSON数组,建立任务信息
                $(json).each(function(i){
                    buildTask(json[i].builddate, json[i].id, json[i].task);
                });
            }
        );
    }
    
    //根据日期、任务编号、任务内容在页面上创建任务节点
    function buildTask(buildDate, taskId, taskInfo) {
    
        $("#" + buildDate).parent().append("<div id='task" + taskId + "' class='task' onclick='editTask(this)'>" + taskInfo + "</div>");
    }

    四、AJAX后台处理

            AJAX后台处理页面的左右就是根据前台通过js函数post的参数进行处理,再输出返回结果。AJAX后台处理页的制作方式很多,比如使用WebServices,ashx(HttpHandler)等等,我们这里使用最普通的aspx页面。

    1. 新建一个aspx页面Calendar.aspx.将页面代码全部删除。仅保留
      <%@PageLanguage="C#"AutoEventWireup="true"CodeBehind="Calendar.aspx.cs"Inherits="AzureCalendar.Calendar"%>
    2. 在后台的Page_Load函数中处理post参数,并选择合适的函数进一步处理数据并输出。
      protected void Page_Load(objectsender, EventArgse)
             {
                 if(Session["LiveId"] == null)
                 {
                     Response.Redirect("Default.aspx");
                 }
                //设置页面无缓存      
                 Response.Cache.SetCacheability(HttpCacheability.NoCache);
                Request.ContentEncoding = Encoding.UTF8;
                string action = Request.Params["action"];
                //根据action不同执行不同的操作
                 if ("addTask".Equals(action))
                 {                             //新建任务
                     String taskInfo = Request.Params["taskInfo"];
                     String buildDate = Request.Params["buildDate"];
                     Response.Write(addTask(taskInfo, buildDate));
                 }
                 else if ("getTasks".Equals(action))
                 {                     //获取整月任务信息
                     String month = Request.Params["month"];
                     String result = getTasks(month);
                     Response.Write(result);
                 }
                 else if ("delTask".Equals(action))
                 {                      //删除任务
                     String taskId = Request.Params["taskId"];
                     delTask(taskId);
                 }
                 else if ("updateTask".Equals(action))
                 {                   //更新任务信息
                     String taskId = Request.Params["taskId"];
                     String taskInfo = Request.Params["taskInfo"];
                     updateTask(taskId, taskInfo);
                 }
             }
    3. 写入protected string getTasks(string month)。
      这步很关键,我们采用JSON返回数据,前台通过AJAX调用得到JSON对象并填充前台页面外观。
      protected string getTasks(string month) { StorageAccountInfo accountInfo = StorageAccountInfo.GetAccountInfoFromConfiguration("TableStorageEndpoint"); TableStorage.CreateTablesFromModel(typeof(ScheduleDataServiceContext), accountInfo); ScheduleDataServiceContext context = new ScheduleDataServiceContext(accountInfo); List<Schedule> list= context.Schedules.Where(p=>p.LiveId==Session["LiveId"].ToString()).ToList(); string json="[\n"; //开始封装JSON格式 foreach (Schedule s in list) { if (s.BuildDate.ToString("yyyy-MM-dd").Replace("-0","-").Contains(month)) { string strSchedule = "{\"id\":\"" + s.Id + "\",\"builddate\":\"" + s.BuildDate.ToString("yyyy-MM-dd") + "\",\"task\":\"" + s.Task + "\"}"; json = json + strSchedule + ",\n"; } } json = json.Substring(0, json.Length - 2); json += "\n]"; if (json.Length < 10) return "[\n{\"id\":\"0\",\"builddate\":\"0\",\"task\":\"0\"}\n]";//如果没有数据,则返回一个废数据保证格式正确 return json.Replace("-0", "-"); }
      为了配合前台,我们把形如"2009-07-01”的字符串替换成"2009-7-1”。实现方法比较丑,相信大家有更优雅的方法。
    4. 其他的增加、修改、删除数据都大同小异。以删除数据为例:
      //删除任务 
            protected void delTask(string taskId)
            {
                StorageAccountInfo accountInfo = StorageAccountInfo.GetAccountInfoFromConfiguration("TableStorageEndpoint");
                TableStorage.CreateTablesFromModel(typeof(ScheduleDataServiceContext), accountInfo);
                ScheduleDataServiceContext context = new ScheduleDataServiceContext(accountInfo);
                Schedule s = new Schedule();
                s.RowKey = taskId;
                context.DelSchedule(s);
            }
      这里有两个问题需要说明:在修改和删除数据时,需要指明对象的主键。
      在Azure Storage中,对象的主键是RowKey和PatitionKey。由于本例里PatitionKey相同,我们只需要指明RowKey即可。

      好了,大功告成!再慢慢增加一些细节吧!
      PS:全部源代码稍后将放到CodePlex上,谢谢大家的支持!
      更多的Azure技术文章在这里
      (转载请保留作者博客链接,http://azure.cnblogs.com/


       
       
       
       
       
       

         

  • 相关阅读:
    shell 自动map和unmap 应用实例url域名【升级版】
    shell 自动map和unmap 应用实例url域名【初级版】
    cloudfoundry容器实例内部测试redis连通性
    Tsunami 跨机房大数据迁移【ubuntu】
    BOS项目05——Action层抽取重复代码(接受page,rows参数,封装到pageUtils对象中;对象转Json),批量添加数据的流程,批量删除流程(主要看前端部分),easyUI选项框(发送ajax请求从region中获取数据),JsonLib转码的原理(get方法),分页查询重复调用问题
    idea与Pycharm破解(Maven+Ubuntu:http://www.cnblogs.com/LexMoon/p/JavaMavenUbuntu.html)
    BOS项目
    前端——EasyUI基本使用
    Mavent——学Java不会Maven,怎么行archetypeCatalog=internal
    SpringMVC——高级参数绑定(数组、集合),@RequestMapper 的使用,Controller方法的三种返回值类型,异常处理器,上传图片,JSON数据交互,配置拦截器
  • 原文地址:https://www.cnblogs.com/azure/p/Azure_Calendar_Tutorial.html
Copyright © 2011-2022 走看看