CSS3 – Đã đến lúc sử dụng hàm calc()

Nếu như bạn thường xuyên phải gặp khó khăn trong việc canh chỉnh kích thước của các thành phần HTML, thì nay vấn đề này có thể được giải quyết một cách đơn giản trong CSS3 nhờ vào hàm calc().
Nếu như bạn thường xuyên phải gặp khó khăn trong việc canh chỉnh kích thước của các thành phần HTML, thì nay vấn đề này có thể được giải quyết một cách đơn giản trong CSS3 nhờ vào hàm calc().
Trước đây, calc() chỉ mới được hỗ trợ trên IE9 và FF4 trở đi, nhưng hiện tại với sự hỗ trợ từ Chrome 19, tính năng này sẽ bắt đầu thực sự được phổ biến trong các ứng dụng web về sau.
Hàm calc() ra đời nhằm cung cấp khả năng tính toán cho CSS, khiến nó linh động và đơn giản hóa công việc cho các designer. Không chỉ đơn thuần áp dụng cho việc tính toán kích thước, việc nhiều tính năng mới của CSS3 đòi hỏi sự phức tạp và chính xác của các con số.
Bạn có thể sử dụng các phép tính đơn giản (+, -, *, /) và có thể trộn lẫn các đơn vị khác nhau như %, rem, em, px,... Ví dụ:

#div1 {  
   width: calc(100% 300px);
   width: -webkit-calc(100% 300px);
   width: -moz-calc(100% 300px);
}
 
Tất nhiên bạn cũng có thể sử dụng hàm này cho bất kì thuộc tính nào sử dụng giá trị là các con số, ví dụ như các thuộc tính khác để xác định vị trí (left, top, margin,…)
Để dự phòng, bạn có thể sử dụng thêm -o-calc() để đợi sẵn tính năng này trên Opera.
Tham khảo thêm tại http://www.caniuse.com/calc và calc() specification.

Export to pdf file sử dụng Itextsharp với asp.net

Trong bài này mình sẽ hướng dẫn các bạn, cách làm thế nào để export nội dung ra file *.pdf sử dụng itextsharp.

Ở đây mình sẽ cài đặt Itextsharp bằng Nuget, các bạn cũng có thể làm với cách khác nếu như các bạn download manual, đầu tiên mình sẽ tạo 1 blank website và add itextsharp bằng Nuget.


Mình sẽ sử dụng thư viện Hugo Bonacci cung cấp HtmlToPdfBuilder.cs.
Từ trang default.aspx mình sẽ thêm nội dụng cho thẻ Div và set thuộc tính runat=”server”, và đây là nội dung Default.aspx:


<div id="content" runat="server">
       <p>
            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam eleifend nunc ut
            nibh commodo tristique in et purus. Nunc viverra, tellus quis venenatis tempus,
            dui massa viverra risus, cursus luctus quam mi nec est. Nulla facilisi. Morbi felis
            erat, mollis et consectetur tincidunt, congue vitae nunc. Vivamus nunc est, molestie
            eu laoreet quis, tempor eu dolor. Vivamus tortor nibh, malesuada vel hendrerit sed,
            ultrices vitae eros. In sit amet lacus tempor elit commodo posuere vitae sit amet
            ante. Aliquam at libero magna. Mauris faucibus dapibus ultrices. Donec rutrum, mauris
            nec tempor luctus, felis turpis dignissim sapien, eu feugiat metus erat at ante.
            Praesent iaculis metus at diam tincidunt vulputate dapibus ante volutpat. Suspendisse
            vulputate mauris non augue ullamcorper tempus. Maecenas sed ipsum nec nisi tincidunt
            condimentum euismod a urna. Maecenas orci leo, malesuada quis facilisis at, lacinia
            non est. Praesent mi mauris, laoreet vitae egestas vitae, luctus non nunc. Vestibulum
            viverra condimentum lectus, pretium tempus nulla sodales non. Sed lectus odio, ullamcorper
            ac viverra vel, facilisis laoreet sapien. Phasellus tristique vulputate posuere.
            Duis adipiscing blandit est, a lobortis velit auctor non. Cum sociis natoque penatibus
            et magnis dis parturient montes, nascetur ridiculus mus.
        </p>
        <p>
            Morbi quis massa ac nunc accumsan sagittis ac et tortor. In non mi orci. Cras mattis
            lacus et lectus porttitor facilisis. Nullam tempor lacus a magna scelerisque interdum.
            In pellentesque ultrices nibh, eu cursus lectus viverra a. Cum sociis natoque penatibus
            et magnis dis parturient montes, nascetur ridiculus mus. Vestibulum et quam et sapien
            facilisis sollicitudin. Praesent sodales ultricies commodo. Morbi suscipit leo leo.
            Nullam suscipit cursus diam vitae suscipit. Donec nec ante vitae augue consectetur
            ullamcorper malesuada vitae urna. Maecenas sed tincidunt urna. Suspendisse eget
            felis dui. Donec sit amet nibh ac risus dignissim fermentum et in nulla. Pellentesque
            varius augue vitae sem semper et molestie nunc eleifend. Nam ut molestie mauris.
        </p>
        <p>
            Vivamus at metus ante. Duis vitae suscipit nibh. Etiam metus arcu, pulvinar nec
            bibendum laoreet, rhoncus eu quam. Suspendisse pellentesque hendrerit nunc id scelerisque.
            Aenean sagittis arcu sit amet neque commodo blandit. Nullam bibendum, est in rutrum
            imperdiet, sem urna lobortis leo, at hendrerit tellus mauris in orci. Ut quis turpis
            neque, ac euismod augue. Sed ornare nisl in eros eleifend volutpat at non nulla.
            Etiam mi massa, congue facilisis tempus ac, ullamcorper a lorem. Phasellus eleifend
            odio a eros viverra fringilla. Lorem ipsum dolor sit amet, consectetur adipiscing
            elit. Proin vitae orci ac felis blandit gravida. Etiam luctus velit elit, eget cursus
            est. Duis fringilla erat non justo blandit hendrerit. Nulla sit amet ornare mi.
        </p>
    </div>
    <asp:Button ID="btnExportPdf" runat="server" OnClick="btnExportPdf_Click" Text="Export To Pdf" />
Ở trong Code Behind mình sẽ lưu nội dụng ra file và tiến hành download nó:


protected void btnExportPdf_Click(object sender, EventArgs e)
    {
        string path = Server.MapPath("~/PDF/");
        string filename = DateTime.Now.Ticks.ToString() + ".pdf";
        HtmlToPdfBuilder builder = new HtmlToPdfBuilder(PageSize.LETTER);
        HtmlPdfPage first = builder.AddPage();
        first.AppendHtml(content.InnerText);
        byte[] file = builder.RenderPdf();
        filename = DateTime.Now.Ticks.ToString() + ".pdf";
        File.WriteAllBytes(path + filename + ".pdf", file);
        //
        HttpContext.Current.Response.Buffer = true;
        HttpContext.Current.Response.ClearContent();
        HttpContext.Current.Response.ClearHeaders();
        HttpContext.Current.Response.ContentType = "application//pdf";
        HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment;filename=" + filename);
        HttpContext.Current.Response.BinaryWrite(file);
        HttpContext.Current.Response.End();
    }
Chúc các bạn thành công

ASP.NET – Serialize đối tượng .NET thành JSON và ngược lại

Các dữ liệu JSON được sử dụng rất thường xuyên trong ứng dụng web, đặc biệt khi cần truyền dữ liệu thông qua ajax. Trong ASP.NET, bạn có thể sử dụng classJavaScriptSerializer để chuyển đối một đối tượng .NET (hay CLR) bất kì thành một chuỗi JSON và ngược lại. Đồng thời, bạn có thể tạo ra các JavaScriptConverter để quy định cách thức chuyển đổi của JavaScriptSerializer.

Cơ bản

Trong bài viết này, tôi sử dụng một ứng dụng kiểu Console vì vậy cần phải thêm tham chiếu đến assembly System.Web.Script.Serialization. Class  JavaScriptSerializer chứa hai phương thức là  Serialize() và  Deserialize() dùng để chuyển đối tượng thành chuỗi JSON và ngược lại. Với một collection, phương thức Serialize() sẽ trả về một chuỗi JSON dạng mảng.

class Foo
{
    public int Id { get; set; }
    public string Name { get; set; }
    public DateTime Birthday { get; set; }
}
class Program
{
    static void Main(string[] args)
    {
        var js = new JavaScriptSerializer();
        var foo=new Foo(){
            Id = 1,
            Name = "Bar",
            Birthday = DateTime.Today
        };
        var json = js.Serialize(foo);
        Console.WriteLine("+ Serialize:\n"+json+"\n");
        var obj = (Foo) js.Deserialize(json, typeof(Foo));
        Console.WriteLine("+ Deserialize:\nId = {0} \nName = {1} \nBirthday = {2}",obj.Id,obj.Name,obj.Birthday);
        Console.Read();
    }
}
Ouput:

+ Serialize:
{"Id":1,"Name":"Bar","Birthday":"\/Date(1329670800000)\/"}
+ Deserialize:
Id = 1
Name = Bar
Birthday = 2/19/2012 5:00:00 PM

Sử dụng JavaScriptConverter

Trong ví dụ trên, kiểu dữ liệu DateTime được serialize thành một chuỗi rất khó để đọc và định dạng khi cần thiết. Vì thế tôi sẽ tạo một tạo một converter sau đó đăng kí cho đối tượng  JavaScriptSerializer. Converter tôi cần tạo phải được thừa kế từ JavaScriptConverter. Class này có 3 thành viên cần được override trong subclass:
-        SupportedTypes: property này sẽ trả về một danh sách các kiểu dữ liệu được hỗ trợ bởi converter này.
-        Serialize: Phương thức này sẽ tạo một đối tượng Dictionary chứa các cặp name/value dùng để chuyển đổi một đối tượng thành JSON.
-        Deserialize: Phương thức này nhận các dữ liệu cần thiết từ một Dictionary để tạo ra đối tượng .NET.
Như vậy Dictionary chính là đối tượng trung gian của quá trình chuyển đổi giữa đối tượng .NET và JSON. Mọi công việc mà bạn cần thực hiện chỉ đơn giản là thao tác trên dữ liệu của đối tượng Dictionary.
Tôi sẽ viết một class  MyFooConverter và sau đó đăng kí một instance của nó vào  JavaScriptSerializer bằng phương thức  RegisterConverters():

public class MyFooConverter : JavaScriptConverter
{
    public override IEnumerable SupportedTypes
    {
        get { return new List() { typeof(Foo) }; }
    }
    public override IDictionary Serialize(object obj, JavaScriptSerializer serializer)
    {
        var result = new Dictionary();
        var foo = obj as Foo;
        if (foo == null)
            return result;
        result["Id"] = foo.Id;
        result["Name"] = foo.Name;
        result["Birthday"] = foo.Birthday.ToShortDateString();
        return result;
    }
    public override object Deserialize(IDictionary dictionary, Type type, JavaScriptSerializer serializer)
    {
        if (dictionary == null)
            throw new ArgumentNullException("dictionary");
        return new Foo()
        {
            Id = (int) dictionary["Id"],
            Name = (string) dictionary["Name"],
            Birthday = DateTime.Parse(dictionary["Birthday"].ToString())
        };
    }
}
// Main method:
// …
 var js = new JavaScriptSerializer();
        js.RegisterConverters(new []{ new MyFooConverter() });
// ...
Output:


{"Id":1,"Name":"Bar","Birthday":"2/20/2012"}

Một Converter linh hoạt hơn

Sẽ rất bất tiện nếu như đối tượng bạn cần chuyển đối có quá nhiều property, việc override hai phương thức Serialize() và Deserialize() sẽ chiếm một số lượng code kha khá. Vì vậy, để giải quyết vấn đề này, tôi sẽ sử dụng reflection để tự động xây dựng một Dictionary từ đối tượng:

public class MyFooConverter : JavaScriptConverter
{
    public override IEnumerable SupportedTypes
    {
        get { return new List() { typeof(Foo) }; }
    }
    public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
    {
        if (obj == null)
            return new Dictionary<string, object>();
        var result = obj.GetType()
             .GetProperties()
             .ToDictionary(p => p.Name, p => p.GetValue(obj, null));
        result["Birthday"] = ((DateTime)result["Birthday"]).ToShortDateString();
        return result;
    }
    public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
    {
        if (dictionary == null)
            throw new ArgumentNullException("dictionary");
        return new Foo()
        {
            Id = (int) dictionary["Id"],
            Name = (string) dictionary["Name"],
            Birthday = DateTime.Parse(dictionary["Birthday"].ToString())
        };
    }
}

Đoạn mã trên chỉ là một ví dụ đơn giản về cách làm và nó cần phải cải tiến để có thể được cho mọi class. Bạn có thể gọi đây là một JsDateTimeConverter, nhưng dĩ nhiên bạn có thể thay đổi nó để chuyển đối cả các kiểu dữ liệu khác về định dạng JSON cần thiết. Đây mới thực sự là đoạn mã tôi muốn giới thiệu:

Một Generic Javascript Converter

Kết hợp generic, LINQ và reflection để giải quyết, tôi được đoạn mã sau:

public class MyJsConverter : JavaScriptConverter
{
    public override IEnumerable SupportedTypes
    {
        get { return new List() { typeof(T) }; }
    }
    public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
    {
        if (obj == null)
            return new Dictionary<string, object>();
        var result = obj.GetType()
             .GetProperties()
             .ToDictionary(p => p.Name,
                p => {
                 var value = p.GetValue(obj, null);
                 if (value.GetType() == typeof(DateTime))
                     value = ((DateTime)value).ToShortDateString();
                 return value;
                });
        return result;
    }
    public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
    {
        if (dictionary == null)
            throw new ArgumentNullException("dictionary");
        var foo = Activator.CreateInstance();
        foreach (var property in type.GetProperties())
        {
            var value = dictionary[property.Name];
            if (property.PropertyType == typeof(DateTime))
                value = DateTime.Parse(value.ToString());
            property.SetValue(foo,value,null);
        }
        return foo;
    }
}
Khi đăng kí, bạn cần xác định rõ kiểu dữ liệu cần chuyển đổi, hoặc bạn cũng có thể tạo một class converter sử dụng kiểu object:

var js = new JavaScriptSerializer();
js.RegisterConverters(new []{new MyJsConverter()});

Chọn và upload nhiều file giống như Gmail sử dụng Jquery và ASP.NET

Có 1 vài người hỏi làm thế nào upload nhiều file kiểu AJAX với progress bar tương tự như Google Gmail.Câu trả lời đó là Uploadify , 1 plugin cho Jquery có thể làm điều đó trong vài phút.Bài này tôi sẽ nói về vấn đề này.
Bước 1

Download Uploadify JQuery plugin và JQuery Library dùng link bên dưới.
Download JQuery

Download Uploadify


Bạn sẽ cần 4 file như bên dưới :


1. jquery-1.3.2.min.js
2. jquery.uploadify.js
3. uploader.fla
4. uploader.swf
trong thư mục scripts trong thư mục gốc của ứng dụng ASP.NET của bạn.
Bước 2
Mở Visual Studio và hoàn thành như bên dưới

Chèn các file CSS và JS trong thẻ head của trang aspx hoặc trang master

<link rel="Stylesheet" type="text/css" href="CSS/uploadify.css" />
<script type="text/javascript" src="scripts/jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="scripts/jquery.uploadify.js"></script>
Add 1 control FileUpload ASP.Net

<form id="form1" runat="server">
    <div style = "padding:40px">
        <asp:FileUpload ID="FileUpload1" runat="server" />
    </div>
</form>
Đặt đoạn script sau trong thẻ head hoặc trong ContentPlaceHolder trong trường hợp bạn sử dụng Master Pages

<script type = "text/javascript">
$(window).load(
    function() {
    $("#<%=FileUpload1.ClientID %>").fileUpload({
        'uploader': 'scripts/uploader.swf',
        'cancelImg': 'images/cancel.png',
        'buttonText': 'Browse Files',
        'script': 'Upload.ashx',
        'folder': 'uploads',
        'fileDesc': 'Image Files',
        'fileExt': '*.jpg;*.jpeg;*.gif;*.png',
        'multi': true,
        'auto': true
    });
   }
);
</script>

Như các bạn thấy chúng ta cần 1 số cài đặt cho FileUpload control. Điểm quan trọng nhất trong đó là 'script': 'Upload.ashx'  cái này sẽ handle FileUpload và lưu file uploaded vào đĩa.
Bên dưới là code của file Upload.ashx


<%@ WebHandler Language="C#" Class="Upload" %>
  
using System;
using System.Web;
using System.IO;
  
public class Upload : IHttpHandler {
    
    public void ProcessRequest (HttpContext context) {
        context.Response.ContentType = "text/plain";
        context.Response.Expires = -1;
        try
        {
            HttpPostedFile postedFile = context.Request.Files["Filedata"];
            
            string savepath = "";
            string tempPath = "";
            tempPath = System.Configuration.ConfigurationManager.AppSettings["FolderPath"];
            savepath = context.Server.MapPath(tempPath);
            string filename = postedFile.FileName;
            if (!Directory.Exists(savepath))
                Directory.CreateDirectory(savepath);
  
            postedFile.SaveAs(savepath + @"\" + filename);
            context.Response.Write(tempPath + "/" + filename);
            context.Response.StatusCode = 200;
        }
        catch (Exception ex)
        {
            context.Response.Write("Error: " + ex.Message);
        }
    }
  
    public bool IsReusable {
        get {
            return false;
        }
    }
}
Như bạn thấy handle này đơn giản chỉ chấp nhận posted files và lưu file vào thư mục là uploads trong thư mục root của website , đường dẫn này đặt trong AppSettings của Web.Config
?
1
2
3
<appSettings>
    <add key ="FolderPath" value ="uploads"/>
</appSettings >

Đó là tất cả những gì chúng ta cần và sau cùng là chạy website chúng ta





 Chọn File để Upload

Bắt đầu upload file

Thật là dễ phải không nào. Chúc các bạn thành công

Cách tạo crystal report thật đơn giản

Nhiều bạn có mail cho mình hỏi cách làm crystal report. hôm nay, mình làm một tut hướng dẫn các bạn cách làm với bộ thư viện mình mới viết. Hi vọng sẽ giúp ích cho các bạn.

Video Download: http://www.mediafire.com/?yug89zd2heqbd48
Library download:http://www.mediafire.com/?w63ta25yycpd6mc

Chúc các bạn thành công!