2013年10月27日 星期日

ASP.NET MVC 4 中將資料寫入 Windows Azure Table Storage

繼前一篇 ASP.NET MVC 4 WebApi 中使用 ActionFilter 紀錄 Log 提到如何擷取出使用者使用 Action 的狀況,接下來就是將這些狀況紀錄到 Windows Azure Table Storage (儲存體) 內。

1.

首先,先將 Table Storage 的連接字串 (Connection String) 記下來,可以先到 Windows Azure 內找到這個資訊,請照下圖方式找到:

將這組組好的連接字串,放到 ASP.NET MVC 4 專案中的 Windows Azure Web Role 的組態檔內,多設置一組連結字串,照以下圖片設置:

2.

此時你就可以開始寫程式了,可以先將建立 Table Storage 連接:
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
    CloudConfigurationManager.GetSetting("StorageConnectionString"));

// 建立連接
CloudTableClient tableClient = storageAccount.CreateCloudTableClient();

在 Azure Table 內,每筆資料需要兩個主要的 Key,PartitionKey 和 RowKey,這兩個 Key 值可以組成唯一值。其實要看這兩筆 Key 很簡單,把 PartitionKey 看成是資料表名稱、 RowKey 就看成是主鍵,因為這兩組 Key 如果在 SQL Server 當然很好分辨,但是資料全部轉為 Table 格式,就只能這樣子去看待。

所以要先設定 PartitionKey 名稱,並且建立此表。
private const string LogTableName = "Logs";

...

// 假設表不存在則建立。
tableClient.CreateTableIfNotExist(LogTableName);

// 取得 Table 
TableServiceContext serviceContext = tableClient.GetDataServiceContext();

3.

接著設置一組類別,當作是 Table 的所有欄位,要繼承 TableServiceEntity,必須引用參考 Microsoft.WindowsAzure.StorageClient:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Runtime.Serialization;

using Microsoft.WindowsAzure.StorageClient;

namespace EnterprisePortal.Models
{
    [NotMapped]
    public class Log : TableServiceEntity
    {
        public Log(string partitionKey, string rowKey)
            : base(partitionKey, rowKey)
        {

        }

        public Log() : this("Logs", Guid.NewGuid().ToString())
        {
        }

        public string Location { get; set; }

        public string ServerIP { get; set; }

        public string PublicIP { get; set; }

        public string ErrorMessage { get; set; }

        public Guid Creater { get; set; }

    }
}

4.

可以開始使用這個類別對 Azure Table 做 CRUD 的動作了。
Log _log = new Log();

if (context.Exception == null)
{
    _log.Creater = Guid.NewGuid();
    _log.ErrorMessage = string.Empty;
    _log.Location = context.ActionContext.Request.RequestUri + " | " + context.ActionContext.Request.Method;
    _log.PublicIP = GetPublicIP();
    _log.ServerIP = GetServerIP();
}
else
{
    _log.Creater = Guid.NewGuid();
    _log.ErrorMessage = context.Exception.Message;
    _log.Location = context.Exception.TargetSite.DeclaringType.ToString() + " | " + context.Exception.TargetSite.Name;
    _log.PublicIP = GetPublicIP();
    _log.ServerIP = GetServerIP();
}

/* 刪除 */
List<Log> lstLogs =
(from e in serviceContext.CreateQuery<Log>(LogTableName)
 where e.PartitionKey == "Logs"
 select e).ToList();

foreach (var t_Log in lstLogs)
    serviceContext.DeleteObject(t_Log);

serviceContext.SaveChangesWithRetries();

/* 新增 */

serviceContext.AddObject(LogTableName, _log);

serviceContext.SaveChangesWithRetries();

/* 查詢 */
CloudTableQuery<Log> partitionQuery =
(from e in serviceContext.CreateQuery<Log>(LogTableName)
 where e.PartitionKey == "Logs"
 select e).AsTableServiceQuery<Log>();

 
foreach (Log entity in partitionQuery)
{
    Console.WriteLine("{0}, {1}\t{2}\t{3}", entity.PartitionKey, entity.RowKey,
        entity.PublicIP, entity.ErrorMessage);
}







沒有留言 :

張貼留言

Related Posts Plugin for WordPress, Blogger...