عملیات CURD در ASP.NET Core 1.0

چهارشنبه 3 آذر 1395

در این مقاله می خواهیم درمورد چگونگی Export کردن داده ها در فرمت CSV بحث و گفتگو کنیم و یک Response Formatter سفارشی را با استفاده از CsvOutputFormatter ایجاد کنیم و یک CsvWriter برای تبدیل کردن لیست از شی ها به فرمت CSV پیاده سازی می کنیم.

عملیات CURD در ASP.NET Core 1.0

افزودن CsvWriter  در WebApplicationCore.NetCore

ویژوال استودیو را اجرا می کنیم .

حال یک پوشه به نام Common ایجاد می کنیم.

یک کلاس به نام CsvWriter.cs در پوشه Common  ایجاد می کنیم .

پیاده سازی CsvWriter برای فراهم کردن لیستی از شی ها که با فرمت CSV ضروری است . CsvWriter یک کلاس helper است و لیستی از شی ها را برای تولید CSV فراهم می کند.

1.	public class CsvWriter {  
2.	    privateconst string DELIMITER = ",";  
3.	  
4.	    public string Write(IList list, bool includeHeader = true) {  
5.	        StringBuildersb = new StringBuilder();  
6.	  
7.	        Type type = list.GetType().GetGenericArguments()[0];  
8.	  
9.	        //Get property collection and set selected property list  
10.	        PropertyInfo[] properties = type.GetProperties();  
11.	  
12.	        //Add Header Names to Csv   
13.	        if (includeHeader) {  
14.	            sb.AppendLine(this.CreateCsvHeaderLine(properties));  
15.	        }  
16.	  
17.	        //Iterate through data list collection  
18.	        foreach(var item in list) {  
19.	            sb.AppendLine(this.CreateCsvLine(item, properties));  
20.	        }  
21.	  
22.	        returnsb.ToString();  
23.	    }  
24.	  
25.	    private string CreateCsvHeaderLine(PropertyInfo[] properties) {  
26.	        List < string > propertyValues = new List < string > ();  
27.	  
28.	        foreach(var prop in properties) {  
29.	            stringstringformatString = string.Empty;  
30.	            string value = prop.Name;  
31.	  
32.	            var attribute = prop.GetCustomAttribute(typeof(DisplayAttribute));  
33.	            if (attribute != null) {  
34.	                value = (attribute as DisplayAttribute).Name;  
35.	            }  
36.	  
37.	            this.CreateCsvStringItem(propertyValues, value);  
38.	        }  
39.	  
40.	        returnthis.CreateCsvLine(propertyValues);  
41.	    }  
42.	  
43.	    private string CreateCsvLine(object item, PropertyInfo[] properties) {  
44.	        List < string > propertyValues = new List < string > ();  
45.	  
46.	        foreach(var prop in properties) {  
47.	            stringstringformatString = string.Empty;  
48.	            object value = prop.GetValue(item, null);  
49.	  
50.	            if (prop.PropertyType == typeof(string)) {  
51.	                this.CreateCsvStringItem(propertyValues, value);  
52.	            } else if (prop.PropertyType == typeof(string[])) {  
53.	                this.CreateCsvStringArrayItem(propertyValues, value);  
54.	            } else if (prop.PropertyType == typeof(List < string > )) {  
55.	                this.CreateCsvStringListItem(propertyValues, value);  
56.	            } else {  
57.	                this.CreateCsvItem(propertyValues, value);  
58.	            }  
59.	        }  
60.	  
61.	        returnthis.CreateCsvLine(propertyValues);  
62.	    }  
63.	  
64.	    private string CreateCsvLine(IList < string > list) {  
65.	        returnstring.Join(CsvWriter.DELIMITER, list);  
66.	    }  
67.	  
68.	    private void CreateCsvItem(List < string > propertyValues, object value) {  
69.	        if (value != null) {  
70.	            propertyValues.Add(value.ToString());  
71.	        } else {  
72.	            propertyValues.Add(string.Empty);  
73.	        }  
74.	    }  
75.	  
76.	    private void CreateCsvStringListItem(List < string > propertyValues, object value) {  
77.	        string formatString = "\"{0}\"";  
78.	        if (value != null) {  
79.	            value = this.CreateCsvLine((List < string > ) value);  
80.	            propertyValues.Add(string.Format(formatString, this.ProcessStringEscapeSequence(value)));  
81.	        } else {  
82.	            propertyValues.Add(string.Empty);  
83.	        }  
84.	    }  
85.	  
86.	    private void CreateCsvStringArrayItem(List < string > propertyValues, object value) {  
87.	        string formatString = "\"{0}\"";  
88.	        if (value != null) {  
89.	            value = this.CreateCsvLine(((string[]) value).ToList());  
90.	            propertyValues.Add(string.Format(formatString, this.ProcessStringEscapeSequence(value)));  
91.	        } else {  
92.	            propertyValues.Add(string.Empty);  
93.	        }  
94.	    }  

1.	private void CreateCsvStringItem(List < string > propertyValues, object value) {  
2.	    string formatString = "\"{0}\"";  
3.	    if (value != null) {  
4.	        propertyValues.Add(string.Format(formatString, this.ProcessStringEscapeSequence(value)));  
5.	    } else {  
6.	        propertyValues.Add(string.Empty);  
7.	    }  
8.	}  
9.	  
10.	private string ProcessStringEscapeSequence(object value) {  
11.	    returnvalue.ToString().Replace("\"", "\"\"");  
12.	}  
13.	}  

افزودن CsvOutputFormatter در WebApplicationCore.NetCore

حال کلاس CsvOutputFormatter.cs را به پوشه Common اضافه می کنیم.

برای این کار برروی پوشه کلیک راست کرده و برروی Add New Item کلیک کنید سپس  Class را انتخاب کنید تا ایجاد شود.

پیاده سازی Output formatter  سفارشی در کلاس CsvOutputFormatter برای تولید response در فرمت CSV با استفاده از CsvWriter . برای ایجاد Output Formatter سفارشی جدید میتوان از روش زیر استفاده کنید :

ارث بری از کلاس های پایه TextOutputFormatter ، OutputFormatter یا StreamOutputFormatter  برای اساس نیاز. برای مثال JsonOutputFormatter و XmlSerializerOutputFormatter از TextOutputFormatter ارث بری می کنند.اگر چه این روش امکانات زیادی را فراهم می کند اما فرمت سنگین تری ساخته می شود.

پیاده سازی اینترفیس IoutputFormatter و تنها دو متد CanWriteResult   و WriteAsync. جایی که از CanWriteResult استفاده شده است برسی می شود که اگر فرمت بود میتواند در فرآیند Response استفاده شود.درحالی که متد WriteAsync فرآیند Response را به صورت حقیقی انجام می دهد.

مقررات ASP.NET Core به گونه ای است که پیاده سازی Response Formatter و Request Formatter سفارشی به صورت جداگانه می باشد. در این حالت در صورت نیاز میتوان نوع Response و Request را مشخص کرده و استفاده کنیم.

همچنین برای این کار نیاز است CsvOutputFormatter را ثبت کنیم. برای این کار در کلاس Startup در متد ConfigureServices با استفاده از MVC Service آن را ثبت می کنیم.

1.	public class CsvOutputFormatter: IOutputFormatter {  
2.	    public bool CanWriteResult(OutputFormatterCanWriteContext context) {  
3.	        if (context == null) {  
4.	            throw new ArgumentNullException(nameof(context));  
5.	        }  
6.	  
7.	        if (context.ContentType == null || context.ContentType.ToString() == "text/csv") {  
8.	            return true;  
9.	        } else {  
10.	            return false;  
11.	        }  
12.	    }  
13.	  
14.	    publicasync Task WriteAsync(OutputFormatterWriteContext context) {  
15.	        if (context == null) {  
16.	            throw new ArgumentNullException(nameof(context));  
17.	        }  
18.	  
19.	        var response = context.HttpContext.Response;  
20.	        response.ContentType = "text/csv";  
21.	  
22.	        using(var writer = context.WriterFactory(response.Body, Encoding.UTF8)) {  
23.	            IListlst = context.Object as IList;  
24.	            CsvWritercsvWriter = new CsvWriter();  
25.	  
26.	            string csv = csvWriter.Write(lst, true);  
27.	  
28.	            writer.Write(csv);  
29.	  
30.	            awaitwriter.FlushAsync();  
31.	        }  
32.	    }  
33.	}  

1.	public void ConfigureServices(IServiceCollection services) {  
2.	    // Add framework services.  
3.	    services.AddMvc(options => options.OutputFormatters.Add(new CsvOutputFormatter()));  
4.	  
5.	    services.AddSingleton < IConfigurationRoot > (sp => {  
6.	        return this.Configuration;  
7.	    });  
8.	    services.AddScoped < IContactDataAccess, ContactDataAccess > ();  
9.	    services.AddScoped < IContactBusinessLogic, ContactBusinessLogic > ();  
10.	}  

متد GetCsv و Get CSV Link

حال یک اکشن متد به کنترلر Contact اضافه می کنیم که لیستی از جنس ContactListVM را بازمیگرداند و داری صفت  [Produces("text/csv")] می باشد که برای تعیین نوع محتوا استفاده می شود.

افزودن لینک CSV در Index.cshtml  برای اکشن متد GetCsv

<th>
    <a asp-controller="Contact" asp-action="GetCsv">دریافت فایل</a>
</th>

[Produces("text/csv")]
        public List<ContactListVM> GetCsv()
        {
            List<Contact> contacts = this.ContactBusinessLogic.GetContacts();
            List<ContactListVM> contactVMs = new List<ContactListVM>();
            ContactListVM contactVM;
 
            foreach (Contact contact in contacts)
            {
                contactVM = new ContactListVM
                {
                    ContactId = contact.ContactId,
                    ContactNumber = contact.ContactNumber,
                    Email = contact.Email,
                    Name = contact.Name,
                    WebSite = contact.WebSite
                };
                contactVMs.Add(contactVM);
            }
 
            return contactVMs;
        }

اجرای کردن برنامه در حالت Debug

با استفاده از F5 برنامه را اجرا کنید .

صفحه اصلی نمایش داده می شود.

در منوی بالایی بر روی لیست تماس ها کلیک کنید.

برروی لینک دریافت لینک کلیک کنید و فایل را ذخیره کنید.

حال میتوان فایل را با برنامه Excel یا Notepad باز کنید.

آموزش asp.net mvc

فایل های ضمیمه

برنامه نویسان

نویسنده 3355 مقاله در برنامه نویسان

کاربرانی که از نویسنده این مقاله تشکر کرده اند

در صورتی که در رابطه با این مقاله سوالی دارید، در تاپیک های انجمن مطرح کنید