Quick sample: EPiServer Change access level of Page

Introduction

Bitwise operators give you the ability to store multiple settings in a single primitive data type (e.g. an integer). This is useful when a single item has potentially more than one setting of the same type.

EPiServer AccessLevel is enum, and if you want to set or remove a AccessLevel, we need to use bitwise operators:

Defining the Flags

To start of with, declare an enum to list all the possible flags. Two things are important when declaring the enum. The first thing you will probably notice is the [Flags] attribute. This is necessary in order to indicate that the enumeration should be treated as a set of flags. The second important thing is assigning a value to each of the items in the enum. The first value should be 1, then just double the value for each consecutive item. The integer type in .NET can store up to 32 flags.

EPiServer.Security
{
 // Summary:
 //     The access levels (bitmapped) that are used to control the various actions
 //     that a user is allowed to perform.
 //
 // Remarks:
 //     Primarily used to control access to page manipulation functions in EPiServer,
 //     but can be used for general-purpose access restriction functions.
 [Serializable]
 [Flags]
 public enum AccessLevel

Setting flags ON:

To set multiple flags, concatenate the desired flags using the bitwise OR symbol “|”:

pageACL.Access |= AccessLevel.Delete;

Setting flags OFF:

pageACL.Access &= ~AccessLevel.Delete;

Testing to see if a certain flag is set:

if ((pageACL.Access&AccessLevel.Delete)==AccessLevel.Delete)


Some sample code

  • Get a PageData by PageLink
  • get ACL list
  • Loop though ACL
  • Remove Delete access right, so no one can delete this page
PageData data = DataFactory.Instance.GetPage(e.PageLink);

 // this page also cannot delete, ignore processing
 if (data.QueryDistinctAccess(AccessLevel.Delete) == false)
 {
     return;
 }

 // modify this page accessright, do not allow to delete
 AccessControlList list = data.ACL.CreateWritableClone();
 foreach (KeyValuePair<string, AccessControlEntry> pair in data.ACL)
 {
 if ((pair.Value.Access & AccessLevel.FullAccess) == AccessLevel.FullAccess)
 {
 list.Remove(pair.Key);
 list.Add(new AccessControlEntry(pair.Value.Name, pair.Value.Access & ~AccessLevel.FullAccess, pair.Value.EntityType));
 }

 if ((pair.Value.Access & AccessLevel.Delete) == AccessLevel.Delete)
 {
 list.Remove(pair.Key);
 list.Add(new AccessControlEntry(pair.Value.Name, pair.Value.Access & ~AccessLevel.Delete, pair.Value.EntityType));
 }
 }
 list.Save(SecuritySaveType.Modify);

dùng Cache trong ASP.NET

Bài này đề cập tới DataCaching của ASP.NET. Các vấn đề outputCaching (cache cả trang aspx) và fragmentCaching (cache một ascx, một phần của trang Aspx) là khá dễ, chỉ cần setup vài thẻ trong mã aspx là xong nên không được đề cập trong bài.

Xem thêm tại http://aspnet.4guysfromrolla.com/articles/022802-1.aspx

Cache về bản chất giống như một HashTable, lưu key là một String, value là đối tượng .NET. Tuy nhiên Cache thì có tính năng đặc biệt là tự động gỡ bỏ các entry theo thời gian hoặc khi hết bộ nhớ để lưu.

Truy xuất Cache:

dùng đối tượng tĩnh HttpContext.Current.Cache
nếu trong Page aspx, dùng Server.Cache
nếu trong ashx, dùng context.Cache

tất cả đều truy xuất đến cùng một chỗ lưu cache của ASP.NET.

Có hai kiểu chính sách hết hiệu lực bạn có thể sử dụng khi lưu giữ dữ liệu trong cache.

  • Absolute expiration: hết hiệu lực vào một THỜI ĐIỂM xác định trong tương lai (VD: 10 phút nữa là huỷ đổi tượng).

Cache.Insert("cacheKey", ObjectToCache, null, DateTime.Now.AddMinutes(10), TimeSpan.Zero);

  • Sliding expiration: gỡ bỏ các đối tượng sau một khoảng thời gian không dùng đến. Mỗi khi đối tượng được truy xuất, thời gian sống của nó sẽ được reset. (VD: loại bỏ các đối tượng mà đã lâu (10 phút) không dùng tới)

Cache.Insert("cacheKey", ObjectToCache, null,DateTime.MaxValue, TimeSpan.FromMinutes(10));

Mẫu code chung để sử dụng Cache là:

T GetValue(){
string CACHE_KEY = "cacheKey";
object oValue = cache[CACHE_KEY];
if (oValue == null) {
oValue = GetValueFromSomeWhere();
// Lưu giữ đối tượng theo kiểu nào tuỳ bạn chọn
cache.Insert(CACHE_KEY, oValue, null, DateTime.MaxValue, TimeSpan.FromSeconds(60));
}
return oValue as T;
}

Hàm GetValueFromSomeWhere() là chỗ bạn lấy dữ liệu thực ở đâu đó (VD lấy từ Database, đọc từ file …)

.

Một  số bonus:
Hàm Cache.Insert() có đối số cuối cùng là CallBack. Tính năng này khá tiện, cho phép developer kiểm soát xem nên làm gì mỗi khi Cache entry bị gỡ bỏ (có thể kiểm tra, tạo lại mới luôn, hoặc thực hiện một số tác vụ …) .  Tips: Dùng cái này có thể tránh được việc pooling để kiểm tra xem Cache entry hết hạn chưa.

Callback này không được khởi chạy nếu cache entry bị gỡ bỏ có chủ ý (bằng cách gọi Remove(), hay gọi Insert() mới đè lên)

Hàm Cache.Insert() nếu cung cấp key trùng với key đã có rồi sẽ gỡ bỏ entry cũ, ấn entry mới vào với key tương ứng ấy

Silverlight – lập trình viên .NET cần đón đầu công nghệ

http://weblogs.asp.net/scottgu/archive/2008/10/14/silverlight-2-released.aspx

http://weblogs.asp.net/scottgu/archive/2007/05/07/silverlight.aspx

http://weblogs.asp.net/scottgu/archive/2008/11/16/update-on-silverlight-2-and-a-glimpse-of-silverlight-3.aspx

http://weblogs.asp.net/scottgu/archive/2008/02/22/first-look-at-silverlight-2.aspx

Webserver push tới browser (client), kỹ thuật và đánh giá, Reverse Ajax / Comet / Ajax Push

(đang nghiên cứu và đánh giá, thực hiện)

Giới thiệu công nghệ

Reverse Ajax refers to an Ajax design pattern that uses long-lived HTTP connections to enable low-latency communication between a web server and a browser. Basically it is a way of sending data from client to server and a mechanism for pushing server data back to the browser.[1][2]

This server–client communication takes one of two forms:

* Client polling, the client repetitively queries (polls) the server and waits for an answer.
* Server pushing, a connection between a server and client is kept open, the server sends data when available.

Reverse Ajax describes the implementation of any of these models, including a combination of both. The design pattern is also known as Ajax Push, Full Duplex Ajax and Streaming Ajax.

Từ khoá: Reverse Ajax / Comet / Ajax Push

Slow load

http://www.obviously.com/tech_tips/slow_load_technique

So sánh Push và Pull khi dùng Ajax

http://www.infoq.com/news/2007/07/pushvspull

Các lựa chọn để cài đặt

Comet – http://cometdproject.dojotoolkit.org/

Cometd Bayeux Ajax Push: Cometd is a scalable HTTP-based event routing bus that uses a Ajax Push technology pattern known as Comet. The term ‘Comet’ was coined by Alex Russell in his post Comet: Low Latency Data for the Browser.

MeteorServer – http://meteorserver.org/

jquery

dojo

APE  http://www.ape-project.org/

Tomcat / Pushlets

http://www.pushlets.com/

http://www.icesoft.com/corporate/press_release_07_06_EE_1.0.html

http://www.icefaces.org/main/ajax-java/ajaxpush.iface

Apache

http://jha.rajeev.googlepages.com/web2push

PHP server push (chỉ xài với non-IE)

http://web.they.org/software/php-push.php

Đọc thêm

http://www.wired.com/wired/archive/5.03/ff_push_pr.html

http://www.patentstorm.us/patents/6381645/claims.html

http://www.itaware.eu/2008/11/03/push-push-push-on-the-browser/

http://www.itaware.eu/2008/11/03/push-push-push-on-the-browser/

http://www.openajax.org/member/wiki/Main_Page

http://www.theserverside.com/news/thread.tss?thread_id=40650

http://ajaxpatterns.org/HTTP_Streaming

http://cometdaily.com/

http://www.pathf.com/blogs/2006/05/not_there_yet_c/

Jetty 6 Servlet Container has it. It is called Continuation and is based on NIO

Scalability is a fundamental feature for a Comet Server, since a large number of concurrent TCP connections has to handled.
Lightstreamer is based on a staged event driven architecture, built over Java NIO classes, that allows it to handle an arbitrary number of connections with a fixed pool of threads.
Just to give you an idea of performance, on a single Pentium 4 CPU – 2.4 GHz, Lightstreamer Server was able to sustain 10,000 concurrent streaming connections with an outbound frequency of 1 update/sec per client.

.NET

http://www.codeproject.com/KB/aspnet/CometGrid.aspx?fid=1538113&select=3001476#xx3001476xx

http://www.codeproject.com/KB/aspnet/CometMultiClient.aspx

Móc nối toán tử ?? của C# để lấy tham số nhẹ nhàng hơn

C# từ bản 2.0 có toán tử ?? rất tiện. Toán tử ?? tương tự như hàm isnull() trong T-SQL của SQL Server vậy. Nó hoạt động như sau:

Nếu value1 là null thì sẽ trả ra value2;

VD:
Nếu dùng toán tử ??

string result = value1 ?? value2;

Nếu viết bình thường
string value1 = null;
string value2 = "Test1";
string result = value1 != null ? value1 : value2;

Cả hai trường hợp trên, biến result sẽ nhận giá trị “Test1″.

Sử dụng toán tử ?? thì bạn sẽ dễ viết hơn, ngắn gọn, bỏ đi được cả đống if() kiểm tra null. Với VD dưới đây, bạn có thể móc nối toán tử ?? để viết chỉ trên 1 dòng mã (chaining):

string partner = Request.QueryString["GoogleId"] ??
Request.QueryString["PartnerId"] ??
Request.QueryString["UserKey"] ??
string.Empty;

Câu lệnh trên sẽ dừng khi nó tìm ra giá trị querystring đầu tiên không null. Nếu tất cả querystring đều null thì nó sẽ trả ra chuỗi rỗng “”.

Nếu bạn sử dụng if()else thì sẽ phải viết rất nhiều mã, nhàm chán, lại phải lồng các if() vào nhau, khó đọc.

.

Nguồn: http://www.west-wind.com/weblog/posts/236298.aspx

Dùng C# viết windows service

Các bài hướng dẫn bằng tiếng Anh có vẻ có nhiều, nhưng phần lớn các bạn post những bài tiếng Anh ấy lên các diễn đàn đều không giải thích cũng như dịch lại, mà thuần là copy paste, cho nên LockeVN mỗ cảm thấy nếu viết một bài hướng dẫn nhanh bằng tiếng Việt thì vẫn hữu ích.

Viết bằng VS2008 và C# rất tiện, rất nhanh, dễ hiểu, gọn, chỉ cần làm theo vài bước đơn giản là được.

OK, rào trước đón sau đủ rồi, giờ bắt đầu, ngắn gọn.

1. Mở Visual Studio ra (dùng bản VS2008 cho tiện),
Tạo một Project mới, chọn C#, chọn windows, chọn Windows Service, đặt tên project “MyService”, OK.
2. Chỉnh vài setting nho nhỏ
Chuột phải vào project, chọn Startup Object là MyService.Program nhé
Nhìn vào Solution Explorer, chuột phải vào Service1.cs, chọn Rename, cho nó một cái tên mỹ miều hơn nhé “FirstService”, nhấn Yes để nó tự thay đổi các file khác.
Nhìn vào Solution Explorer, Nhấn vào FirstService.cs, Nhấn Shift F7, mở ra màn hình Design, chuột phải vào màn hình Design (ở giữa ấy) chọn Properties, chỉnh các thông số của nó trong khung Properties nhé, quan trọng nhất là cái ServiceName, đặt tạm là “mysvc”

3. Nhớ là dùng System.Threading.Timer, đừng dùng các Timer khác (kẻo bạn sẽ hối hận và tốn thời gian vô cùng)

4. Thêm bộ Installer
Sửa các thuộc tính sau

5. Cài đặt
mở Visual Studio 2008 Command Prompt
Để cài đặt, Gõ installutil /i “MyService.exe”
Để gỡ bỏ, Gõ installutil /u “MyService.exe”

Đôi khi việc gỡ bỏ service không hề dễ dàng (nhất là khi code lỗi, code lỗi phần installer, chỉnh sửa project setup), không thể uninstall đc, mà không uninstall được thì bạn sẽ không cài lại được, không thử tiếp được :D . Cho nên ta vẫn phải cần tới cách gỡ bỏ windows service bằng tay.

  • Vào menu Start, Run, gõ regedit, enter
  • Chuyển đến nhánh key (bên trái) HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services
  • Xoá nhánh service nào bạn thấy bị lỗi.
  • Khởi động lại.

Chú ý: đừng làm việc gỡ bỏ bằng tay này nếu không hiểu rõ ràng bạn đang sửa cái gì, hoàn toàn tự chịu trách nhiệm đấy nhé.

Tham khảo

http://www.grinn.net/blog/dev/2008/01/windows-services-in-c-part-1.html

http://www.codeproject.com/KB/system/WindowsService.aspx

http://www.aspfree.com/c/a/C-Sharp/Timer-Objects-in-Windows-Services-with-C-sharp-dot-NET/

using memcache with multi ClientAPI multi platforms and languages

When your system is large, compose by several programs, in several languages. If every programs need to access memcacheD, you should use the correct ClientAPI to make them talk with each other.
Of course, if you set value by PHP, you get value by PHP, it works. If you set value by Java, then you get value by other Java program, it work too.

BUT, this time (this post time), if PHP says, maybe Java can’t hear, C# can’t here, and vice versa.

in PHP, $memcacheClient->set(“test”,”lockevn”);     // it will go to memcache server

in Java, Object oValue = oMemcacheClient.get(“test”) ;      // it will return null, supprise!!! @:@

I have some experience with Java, PHP. PHP website (using default pecl extension module) set value to memcache, if Java program need to get that value, you should use http://bleu.west.spy.net/~dustin/projects/memcached/ ClientAPI (at the time of this post). The other won’t work. Follow this link to get more info.

I do not test .NET client   http://www.codeplex.com/EnyimMemcached

You also need to store value as native format, only use 32bit integer, or string. If you put PHP object, Java program can not understand it, neither the C# program.

If your really need to store object, serialize it (to XML, JSON, … encode with UTF-8) BEFORE put it in memcache. The others must deserialize after get that value. Believe me, do that will save you a lot of time.

There is a similar alternative project on Windows: Velocity from MS

http://www.microsoft.com/downloads/details.aspx?FamilyId=B24C3708-EEFF-4055-A867-19B5851E7CD2&displaylang=en

And an alternate one

http://www.sharedcache.com/cms/

Summary

memcache is good, but it make only to store data, only data, it does not like “object” things, don’t push it too hard. If you want some program say and other “different language” program hear, check it carefully, ask the ClientAPI author if it does not work. You should use native data format for value (int and string only), do serialize by yourself if you want to store data object.