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 { getset; }
            public stringTask { getset; }

            publicDateTimeBuildDate { getset; }

            public stringLiveId { getset; }
        }
    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即可。

本文转自 流牛木马 博客园博客,原文链接:http://www.cnblogs.com/azure/archive/2009/07/07/Azure_Calendar_Tutorial.html,如需转载请自行联系原作者
相关文章
|
8天前
|
数据采集 人工智能 安全
|
17天前
|
云安全 监控 安全
|
3天前
|
机器学习/深度学习 人工智能 前端开发
构建AI智能体:七十、小树成林,聚沙成塔:随机森林与大模型的协同进化
随机森林是一种基于决策树的集成学习算法,通过构建多棵决策树并结合它们的预测结果来提高准确性和稳定性。其核心思想包括两个随机性:Bootstrap采样(每棵树使用不同的训练子集)和特征随机选择(每棵树分裂时只考虑部分特征)。这种方法能有效处理大规模高维数据,避免过拟合,并评估特征重要性。随机森林的超参数如树的数量、最大深度等可通过网格搜索优化。该算法兼具强大预测能力和工程化优势,是机器学习中的常用基础模型。
292 164
|
2天前
|
机器学习/深度学习 自然语言处理 机器人
阿里云百炼大模型赋能|打造企业级电话智能体与智能呼叫中心完整方案
畅信达基于阿里云百炼大模型推出MVB2000V5智能呼叫中心方案,融合LLM与MRCP+WebSocket技术,实现语音识别率超95%、低延迟交互。通过电话智能体与座席助手协同,自动化处理80%咨询,降本增效显著,适配金融、电商、医疗等多行业场景。
303 155
|
4天前
|
机器学习/深度学习 人工智能 前端开发
构建AI智能体:六十九、Bootstrap采样在大模型评估中的应用:从置信区间到模型稳定性
Bootstrap采样是一种通过有放回重抽样来评估模型性能的统计方法。它通过从原始数据集中随机抽取样本形成多个Bootstrap数据集,计算统计量(如均值、标准差)的分布,适用于小样本和非参数场景。该方法能估计标准误、构建置信区间,并量化模型不确定性,但对计算资源要求较高。Bootstrap特别适合评估大模型的泛化能力和稳定性,在集成学习、假设检验等领域也有广泛应用。与传统方法相比,Bootstrap不依赖分布假设,在非正态数据中表现更稳健。
233 113
|
11天前
|
SQL 自然语言处理 调度
Agent Skills 的一次工程实践
**本文采用 Agent Skills 实现整体智能体**,开发框架采用 AgentScope,模型使用 **qwen3-max**。Agent Skills 是 Anthropic 新推出的一种有别于mcp server的一种开发方式,用于为 AI **引入可共享的专业技能**。经验封装到**可发现、可复用的能力单元**中,每个技能以文件夹形式存在,包含特定任务的指导性说明(SKILL.md 文件)、脚本代码和资源等 。大模型可以根据需要动态加载这些技能,从而扩展自身的功能。目前不少国内外的一些框架也开始支持此种的开发方式,详细介绍如下。
809 6