Rails まとめる!

Railsとは

Railsとは、Rubyプログラミング言語で書かれたWebアプリケーションフレームワーク(MVC)です。 Railsは、あらゆる開発者がWebアプリケーションの開発を始めるうえで必要となる作業やリソースを事前に仮定して準備しておくことで、Webアプリケーションをより簡単にプログラミングできるように設計されています。

 

① Railsをインストール(MAC OS)

  1. Homebrewをインストールする

Homebrewとは「ユーザが自らパッケージをビルドして使用する」、これをインストールするためには、Command Line Tools for Xcodeを先にインストールする必要があります

ruby -e “$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)”

 

  1. Rubyをインストールする

デフォルトで入っているrubyより、最新のrubyをインストールして使用します。そのために、rbenvというツールをインストールします。

  1. rbenvをインストール

rbenvとは、rubyのバージョンを管理してくれるツールです

$ brew update
$ brew install rbenv ruby-build
$ echo ‘eval “$(rbenv init -)”‘ >> ~/.bash_profile
$ source ~/.bash_profile

  1. Rubyをインストール

$ rbenv install -l # 2.0.0-pXXXを探してください
$ rbenv install 2.0.0-pXXX # 上で探した2.0.0-pXXXを入力
$ rbenv global 2.0.0-pXXX # 上で指定した2.0.0-pXXXを入力
$ ruby -v # 2.0.0-pXXXが表示されることを確認

 

  1. MySQLをインストール

$ brew install mysql

  1. Railsアプリの作成準備

必要最低限なgemをインストールします。それ以外は、Bundlerで管理することになるはずです。

$ gem install bundler
$ gem install rails
$ rbenv rehash

ここまで来たらrails newコマンドでrailsアプリを作成していけます。

 

  1. Railsプロジェクトを作成

rails new myapp

rails new myapp -d mysql(MySqlを使います)

cd myapp

rake db:create (データベースを作ります)

rails s(Railsサーバーを起動します)

myappのウェブサイト: http://localhost:3000

 

② MVCに基づく設計

 

後述しますが、モデルやコントローラのひな形を自動生成してくれる便利なコマンドがあります。

基本的な処理はそのコマンドから初めて、必要な箇所だけあとから編集、というのがおおまかな処理の流れになると思います。

 

③ RailsのMVC

  1. Model

app/models に配置されます。

Modelは ActiveRecord::Base クラスを継承したものになります。

基本的な CRUD (Create, Read, Update, Delete) の仕組みはベースクラスで定義されているため、特殊な処理がないモデルの場合は以下のように定義するだけで基本的な機能を使うことができます。

コメントで指摘もらいましたが、あくまでその処理を行うことが定義されている、という意味です。

なので実際にアプリケーションとして実行可能な状態にするにはコントローラなどとの連携が必要になります。

Modelで使用される型

概要
string 文字列
text 長い文字列
integer 整数
float 浮動小数点数
decimal 精度の高い小数
datetime 日時
timestamp タイムスタンプ
time 時刻
date 日付
binary バイナリ
boolean 真理値
primary_key 主キー

 

  1. Controller

 

app/controllers に配置されます。

ユーザからの操作を受け付けて、アプリケーションの動作を決定するコントローラです。

  • ルーティングを設定する

プロジェクトディレクトリの下に config ディレクトリがあります。

その中の routes.rb ファイルにルートをに関する設定をしてあげると自動的にそのルーティングを行う処理を実行してくれます。

Rails.application.routes.draw do
   resources :projects

end

  • rootを設定する

サイトトップにアクセスしたときなどに、どこを表示して欲しいかをコントローラとアクションの単位で指定しておくことができます。

例:root ‘projects#index’

上記のようにすると、トップに来た場合に projects の index アクションが実行されます。

  • URLの階層を定義する

以下のようにすることで、あるモデル以下に紐付いた他モデルのデータ(has many的な)を表示、というようなURLのルーティングを実現することができます。

(いわゆるhas manyの関係にあるデータの表示とか)

resources :projects do
   resources :tasks, only: [:create, :destroy]
end

こうすることで、とあるプロジェクトに紐付いたタスク一覧を表示するURLを設定することができます。

  • 特定URLをアクションに結びつける

このURLにアクセスしたらこのアクションを実行したい、という場合は以下のようにすることで設定することができます。

post ‘/projects/:project_id/tasks/:id/toggle’ => ‘tasks#toggle’

tasks はコントローラです。そのコントローラの toggle メソッド(アクション)を実行する設定です。

  • Controllerのルーティングを確認する

ルーティングの設定ができたら rake routes コマンドでルーティングを確認することができます。

  • before_action, after_action

モデルの取得など、各アクションの中で共通に処理する部分があるかと思います。

その際に、同じことを書くのはDRYに反するので、before_action や after_action に処理をまとめることで共通化することができます。

具体的には以下のようにします。

controller:

class ProjectsController < ApplicationController
   before_action :anyMethod, only: [:show, :edit]

   private
       def anyMethod
           # do common action
       end
end

ちなみにこの before_action という記述はRubyの機能で、クラス・メソッドなどを指定するとそれがクラス宣言時に実行されるようになります。

※ コメントで指摘をもらったので補足しておきます。before_action というメソッド自体はRails側の機能です。ただ、クラス宣言時に実行される、という点がRubyの機能という意味です。

  • Controllerに関する規約

モデルを操作するコントローラを作成する場合は同様に、モデル名の複数形で作成する必要があります。上記の例で言えば Projects。

さらに、上記のルーティングで示されている Controller#Action の項目が、コントローラにどのメソッドを実装したらどのアクションが実行されるかを表しています。

例えば、index メソッドを実装すれば /projects(.:format) にアクセスされたときにそれが実行されます。

 

  1. View

app/views に配置されます。

HTMLをレンダリングし表示するビュー。

ちなみに ERB(Embed RuByの略) を利用してHTMLを構築します。

<% if (hoge) %>
   ここにHTML
<% end %>

<%= hoge.name %>

<% ~ %> と <%= ~ %> という記述方法がある。

前者はRubyを実行するだけで返り値は無視されますが、後者は戻り値がそのままHTMLとして出力される点が異なります。

パーシャルを使う

DRY(Don’t repeat your self)の精神で、同じことを記述することを避けるのがRails風です。

ということで、Viewの中で同じ記述が現れる箇所がある場合は、「パーシャル」という機能を使ってまとめておくと便利です。

パーシャルの使い方にもルールがあり、以下のように記述します。

<%= render ‘hoge’ %>

上記は erb ファイルの一部です。上記のように render メソッドを使ってパーシャルを呼び出します。

パーシャル自体は、Viewsの中に、renderの引数に渡された文字列にアンダースコアを付けたファイル(上記の例では _hoge.erb)を作成し、そこに共通項目を書きます。

あとはRailsが規約に則って該当のパーシャルのその位置に読み込んでくれます。

Viewに関する規約

Viewに関する規約は、コントローラのアクション名と同名のファイル名にする、という点です。

(例えば index アクションなら index.html.erb ファイル)

共通テンプレート

Viewはまた、共通テンプレートを持つことができます。HTML内のhead要素などサイト内で共通にしておきたいものはたくさんあると思います。

それらについては app/views/layouts ディレクトリ内に配置されます。

また、各Viewに記述された内容はテンプレート内の <%= yield %> に展開されるようになっています。

 

④ Railsのコマンド

 

よく使うコマンドだけメモします。参考:http://railsdoc.com/rails

  1. Scaffold: 全部入り

 

$ rails generate scaffold NAME [field[:type][:index] field[:type][:index]] [options]

 

NAME モデル名 (単数系)。under_score記法とCamelCased記法どちらでもよい
field カラム名
type
index インデックス(uniqueかindex)
options オプション

 

例: $ rails generate scaffold AdminUser name:string mail:string

  1. Scaffold_controller

コントローラとビューをデフォルトのアクション(index〜destroyの計7つ)で生成する

$ rails generate scaffold_controller NAME [options]

 

NAME モデル名(単数系)。under_score記法とCamelCased記法どちらでもよい。
options オプション

 

例: $ rails generate scaffold_controller AdminUser

  1. Controller: コントローラとビューを生成する

$ rails generate controller NAME [action action] [options]

 

NAME コントローラ名(単数系か複数系かは用途に合わせて )。under_score記法とCamelCased記法どちらでもよい
action アクション
options オプション

 

例: $ rails generate controller AdminUsers index show

 

  1. Model:モデルとマイグレーションを生成する

$ rails generate model NAME [field[:type][:index] field[:type][:index]] [options]

NAME モデル名 (単数系)。under_score記法とCamelCased記法どちらでもよい
field カラム名
type
index インデックス(uniqueかindex)
options オプション

 

例:$ rails generate model AdminUser name:string mail:string

  1. Migration:マイグレーションを生成する

$ rails g migration NAME [field[:type][:index] field[:type][:index]] [options]

 

NAME マイグレーション名
field カラム名
type
index インデックス(uniqueかindex)
options オプション

 

例:$ rails generate migration AddGroupIdToAdminUsers group_id:integer

  1. マイグレーション実行

$ rake db:migrate


⑤ 命名の慣習

  1. 大文字小文字

RubyとRailsの慣習を以下に示します。

  • クラス名: アッパーキャメルケースで表記します。例: MyClass
  • メソッド名: スネークケースで表記します。例: update_attribute
  • 変数名: スネークケースで表記します。例: @user_name

(参考:キャメルケースとスネークケース

 

  1. メソッド名の選定

メソッド名の命名に使う語彙にも慣習があります。

  • プロパティ的なメソッドには動詞を含めず、名詞のみで。
    • ○: def width
    • ○: def width=(val)
    • ×: def get_width
    • ×: def get_width=(val)

.get_widthとしなくても.widthだけで十分意味が通じるという考え方です。

以下はよく知られた慣習だと思います。

  • true/falseを返すメソッド名の末尾には?を付けます。例: valid?
  • メソッド名から推測されるよりも破壊的なメソッドの末尾には!を付けます。例: save!

前者は意味を限定して明確にし、後者は使用上の注意が必要であることを知らせます。

  1. コントローラ名とモデル名

Railsでは、コントローラ名は英語の複数形で終わり、モデル名は英語の単数形で終わることが前提となっています。また、コントローラ名とモデル名が互いに関連する場合には原則として一貫した命名をする慣習があります。

たとえば、ユーザープロファイルを扱うコントローラとモデルを作成する場合、コントローラ名はUserProfiles、モデル名はUserProfileとします。

1.#コントローラ

class UserProfiles < ApplicationController

end

2.#モデル

class UserProfile < ActiveRecord::Base

end

コントローラ名とモデル名はどちらもクラス名なのでキャメルケースで表記しますが、それぞれが保存されるファイルの名前はスネークケースで記述しますので注意してください。

  • コントローラ名: user_profiles_controller.rb
  • モデル名: user_profile.rb

なお、モデルと関連付けられるデータベースのテーブル名は「複数形かつスネークケース」となります。

デバッグ

1. ビューファイルのデバッグ

ビュー内では、次のようにdebugメソッドを使うことで、変数の値や、パラメーターの値を表示することができます。

# ビューファイル
<!–  develompent環境のときにデバッグ情報を表示する –>
<%= debug  if Rails.env.development? %>
<!– インスタンス変数(@products)の値を表示する –>
<%= debug @products %>

<!– paramsの内容を画面に表示する。–>
<%= debug params %>

<!– 他にも、session、headers、params、flash、request、responseなどの値も表示できます –>

2. モデルとコントローラーでのデバッグ

モデルとコントローラーではビューと違って画面表示がないので、logger.debugメソッドを使い、ログファイルに情報を出力します。

# コントローラーかモデル
logger.debug “出力したいデバッグ情報”

ブレイクポイントを設定した本格的なデバッグ

まず、pry-byebugというデバッグを実行できるようにするGemを追加します。

# Gemfile
group :development, :test do
 gem ‘pry-rails’  # rails console(もしくは、rails c)でirbの代わりにpryを使われる
 gem ‘pry-doc’    # methodを表示
 gem ‘pry-byebug’ # デバッグを実施(Ruby 2.0以降で動作する)
 gem ‘pry-stack_explorer’ # スタックをたどれる
end

 

Bundlerでインストールします。

bundle install

あとは、ビュー、コントローラー、モデルなど詳細にデバッグを行いたい箇所にbinding.pryと記載するとそこがブレイクポイントになります。

あとは、実際にそこの箇所になれば、サーバーが停止し、interactiveなモードになります。
例:
  <p>
     <strong>Username:</strong>
     <%= @user.username %>
=>   <% binding.pry %>
  </p>
   <p>
    <strong>Email:</strong>
    <%= @user.email %>
  </p>

そこで、変数の内容を表示したり、変数定義やコマンドを試すことができます。

また、次の4つのコマンドでソース内を移動できます。

next   # 次の行に移動する
step   # 次の行か、メソッド内の行に移動する
exit   # 次のブレークポイントまで実行する
finish  # 現在のスタックトレース(画面に表示されているメソッド)が終わるまで実行する

参考:http://guides.rubyonrails.org/debugging_rails_applications.html

⑦ GEM

Rubyのサードパーティ製のライブラリの形式のこと

  • 7つの開発用Gem

すべてのRailsプロジェクトでいれておくべき7つの開発用Gem(参考:

http://qiita.com/icb54615/items/374f76b38f673fab7744

Gemを検索サイト:https://rubygems.org/

MVC trong Laravel 5.1 ( Overview Laravel 5.1 )

Chào mừng ngày cuối tuần bằng bài viết cho những bạn mới tìm hiểu về Laravel mà còn bỡ ngỡ không biết Controller, View và Model gọi nhau thế nào nhé.

Mình chỉ nói tư tưởng và cách viết để các bạn có tư duy sơ bộ về MVC trong Laravel 5.1 như thế nào nhé.

1. View

  • Phần hiện thị ở phía Client như thế nào, đẹp xấu ra sao là do phần này các bạn viết thế nào nhé. Nó nằm trong thư mục resources/views, là thư mục quy định sẵn của Laravel 5.1 lần này. Khác với Laravel 4, các bạn sẽ thấy Views nằm trong thư mục View ngay trong App folder.
  • Trong thư mục Views này chứa những file html được giữ nguyên cách đặt tên như trong Laravel 4 đó là: fileName.blade.php
  • Các file trong Views sử dụng những thành phần trong thư mục Public gồm css, images, js.
  • Mọi truy cập từ bên ngoài vào Server của bạn sẽ dẫn tới thư mục public này, có nghĩa là mọi tấn công từ bên ngoài cũng chỉ vào được khu vực này thôi. Bạn yên tâm là họ chỉ đọc được Css, images, javascript.
  • Cùng xem một đoạn code sau trong file “home.blade.php”:

 

スクリーンショット 2015-12-05 午前10.48.26

  • Đây chỉ là một đoạn Html đơn giản, tuy nhiên chúng ta sẽ xem phải show nó lên như thế nào trong Laravel 5.1 nhé!
  • Route: Khi truy cập tới route: “home-page” bằng phương thức “get” chúng ta cần một khai báo trong router như dưới đây:

Route::get(‘home-page’, array(‘uses’ =>                                                 ‘Admin\AdminController@showHomePage’));

Có thể hiểu như sau: khi có một action get truy cập tới “home-page” thì controller: AdminController sẽ được kích hoạt và gọi tới hàm showHomePage.

2. Controller

Trong AdminController hàm showHomePage được viết như sau:

public function showHomePage() {

$userEmail = nishi@betogoo.com

$dataUser = \App\UserManage::getInfoUser($userEmail);
return View::make(‘home’, array(
‘userLogin’ => $dataUser,
));
}

Đoạn code đơn giản này đã thể hiện được cách làm việc từ việc gọi Model để lấy dữ liệu $dataUser sau đó đổ nó lên View có tên là “home” (chính là file view: “home.blade.php”) thông qua phương thức “make” , ngoài ra việc truyền nhiều biến vào View bạn có thể nhét hết vào một mảng trong “array” như trên!

3. Model

Hàm lấy thông tin “getInfoUser” này nằm trong file “UserManage” trong thư mục App chính vì thế để gọi được nó chúng ta phải chỉ ra trong controller cụ thể nó nằm ở đâu thông qua: \App\UserManage::getInfoUser

Cùng xem Model được viết như thế nào nhé:

public static function getInfoUser($email) {
$userInfo = DB::table(‘users’)->where(’email’, $email)->first();
return $userInfo;
}

Cần phải khai báo static để mọi controller có thể gọi được function này. Ta có thể thấy model này gọi tới bảng “users” với điều kiệu là email phải bằng biến $email, email này được truyền vào từ controller:

$userEmail = nishi@betogoo.com

$dataUser = \App\UserManage::getInfoUser($userEmail);

 

Một chút trên để các bạn hình dung cơ chế gọi nhau của Controller, View và Model, để thành thạo cách sử dụng chúng và thực hiện các tác vụ phức tạp hơn, các bạn hãy thực hành thật nhiều và tham khảo trang chủ của laravel.com nhé.

Install Laravel 5 in Maccccccccccccc

1. Download Composer.phar to htdocs folder (Link: https://getcomposer.org/download/)
2. Run command to require laravel:
php composer.phar global require “laravel/installer=~1.1”
3. Download Laravel by this command to “projectName” :
php composer.phar create-project laravel/laravel projectName
4. Go to “projectName”
5. Run command:
$ sudo chmod -R gu+w storage
and:
$ sudo chmod -R guo+w storage
(# Group Writable (Group, User Writable)
$ sudo chmod -R gu+w storage
# World-writable (Group, User, Other Writable)
$ sudo chmod -R guo+w storage)
6. Done!

Share link lên Facebook và các mạng xã hội trong Laravel

Bạn tải thư viện này về: https://github.com/thujohn/share-l4

sau đó trong file composer.json bạn thêm dòng: 

"thujohn/share": "dev-master" vào trong  phần Require kiểu như sau:

"require": {
 "laravel/framework": "4.2.*",
 "thujohn/share": "dev-master"
 },
Tiếp theo trong file app/config/app.php 
Bạn thêm vào phần providers và aliases những dòng như sau:
'Thujohn\Share\ShareServiceProvider', 
'Share' => 'Thujohn\Share\ShareFacade',
Tiếp theo bạn làm theo hướng dẫn của bài viết nhé ;)
Mình chỉ  hướng dẫn tới đây vì đoạn dưới anh tác giả đã 
hướng dẫn dễ hiểu rồi.

			

Create Sub Controller and Sub Model in Laravel

You have controller folder below:
controllers\
---- folder1
------------HomeController.php
In Route:
Route::get('/', 'Home\HomeController@index');
In HomeController.php have to write in header of file:
namespace folder1;
use BaseController;
(<?php
namespace folder1; 
use BaseController;
class HomeController extends BaseController {
 ... )
 And if you call a model in this controller you must use '/' before model name. 
For example we have a model is Menu, we'll call: 
$menu = \Menu::all();
To finish, in cmd you go to the laravel project and type:
php composer dump-autoload
or: 
php composer.phar dump-autoload (if composer not found)
(You don't have to change composer.json and global.php) 

2. Sub Model
as same sub controller but you must have:
namespace name_of_sub_model;
use Eloquent;
use DB; //If you want to use query builder 
So easy!

Setup Laravel 4 for Mac with Xampp

Step 1. You have to install Xampp

Step 2. Download laravel-master latest version in https://github.com/laravel/laravel

Step 3. Move folder laravel-master (which have downloaded) to folder htdocs of Xampp

Step 4. Download Composer.phar on link https://getcomposer.org/composer.phar

Step 5. Move file Composer.phar to folder laravel-master

Step 6. In Terminal cd to folder laravel-master and type:

php composer.phar install

Step 7:  chmod 777 app/storage/*

Step 8: Check http://localhost/ laravel-master/public in browser. You’ll see

You have arrived.

OK!

Upload File Bằng phương thức FTP trong C#

Chào các bạn.

Upload file bằng phương thức FTP là một phương thức upload cơ bản và nó có rủi ro là nếu bạn bị dùng đường truyền internet bình thường sẽ có thể bị ăn cắp dữ liệu và để khắc phục điều này người ta dùng một phương thức phức tạp hơn là FPTS hay là SFTP.

Nhưng trong bài viết này mình trình bày vấn đề upload cơ bản để chúng ta tìm hiểu về cách thức đưa dữ liệu lên server từ client như thế nào nhé.

Đầu tiên cần: host, user, pass để có thể truy cập vào server nhé.

private string host = null;
private string user = null;
private string pass = null;

Chúng ta cần một cái FtpWebRequest để gửi Request lên, tiếp theo là FtpWebResponse để nhận Response từ server về và cuối cùng là một Stream để như một cái ống nối vô hình từ Server với Client để truyền dữ liệu qua lại giữa 2 bạn này với nhau. Chúng ta khai báo như sau:

private FtpWebRequest ftpRequest = null;
private FtpWebResponse ftpResponse = null;
private Stream ftpStream = null;

Chúng ta khởi tạo nhé:

public Ftp(string hostIP, string userName, string password)

{

host = hostIP;

user = userName;

pass = password;

}

+ Hàm Download như sau:

/* Download File */
public bool download(string remoteFile, string localFile)
{
bool isDownloadSuccessful = false;
try
{
int bufferSize = this.getFileSize(remoteFile);
/* Create an FTP Request */
ftpRequest = (FtpWebRequest)FtpWebRequest.Create(host + “/” + remoteFile);
/* Log in to the FTP Server with the User Name and Password Provided */
ftpRequest.Credentials = new NetworkCredential(user, pass);
/* When in doubt, use these options */
ftpRequest.UseBinary = true;
ftpRequest.UsePassive = true;
ftpRequest.KeepAlive = true;
/* Specify the Type of FTP Request */
ftpRequest.Method = WebRequestMethods.Ftp.DownloadFile;
/* Establish Return Communication with the FTP Server */
ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
/* Get the FTP Server’s Response Stream */
ftpStream = ftpResponse.GetResponseStream();
/* Open a File Stream to Write the Downloaded File */
FileStream localFileStream = new FileStream(localFile, FileMode.Create);
/* Buffer for the Downloaded Data */

byte[] byteBuffer = new byte[bufferSize];
int bytesRead = ftpStream.Read(byteBuffer, 0, bufferSize);
/* Download the File by Writing the Buffered Data Until the Transfer is Complete */
try
{
while (bytesRead > 0)
{
localFileStream.Write(byteBuffer, 0, bytesRead);
bytesRead = ftpStream.Read(byteBuffer, 0, bufferSize);
}
isDownloadSuccessful = true;
}
catch (Exception ex) { Console.WriteLine(ex.ToString()); }
/* Resource Cleanup */
localFileStream.Close();
ftpStream.Close();
ftpResponse.Close();
ftpRequest = null;
}
catch (Exception ex) { Console.WriteLine(ex.ToString()); }
return isDownloadSuccessful;
}

+ Upload:

/* Upload File */

public bool doUpload(string remoteFileName, string localPathFile)
{
bool iSuccessful = false;
try
{
/*Get Local File Information*/
FileInfo objLocalFile = new FileInfo(localPathFile);

/* Create an FTP Request */
ftpRequest = (FtpWebRequest)FtpWebRequest.Create(host + “/” + remoteFileName);
/* Log in to the FTP Server with the User Name and Password Provided */
ftpRequest.Credentials = new NetworkCredential(user, pass);
/* When in doubt, use these options */
ftpRequest.UseBinary = true;
ftpRequest.UsePassive = true;
ftpRequest.KeepAlive = true;
//ftpRequest.Timeout = 1000;
//set Time out for request upload
ftpRequest.Timeout = 600000 * 3;
ftpRequest.ContentLength = objLocalFile.Length;
/* Specify the Type of FTP Request */
ftpRequest.Method = WebRequestMethods.Ftp.UploadFile;
/* Establish Return Communication with the FTP Server */
ftpStream = ftpRequest.GetRequestStream();
/* Open a File Stream to Read the File for Upload */
//FileStream remoteFileStream = new FileStream(remoteFile, FileMode.Create);
FileStream remoteFileStream = objLocalFile.OpenRead();

/* Buffer for the Uploaded Data */
int bufferSize = (int)remoteFileStream.Length;
byte[] byteBuffer = new byte[bufferSize];
int bytesSent = remoteFileStream.Read(byteBuffer, 0, bufferSize);
/* Upload the File by Sending the Buffered Data Until the Transfer is Complete */
try
{
while (bytesSent != 0)
{
ftpStream.Write(byteBuffer, 0, bytesSent);
bytesSent = remoteFileStream.Read(byteBuffer, 0, bufferSize);
}
iSuccessful = true;
}
catch (Exception ex)
{
messageUploadFile = ex.Message.ToString();
MessageBox.Show(ex.Message.ToString());
//Console.WriteLine(ex.ToString());
}
/* Resource Cleanup */
remoteFileStream.Close();
ftpStream.Close();
ftpRequest = null;
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
return iSuccessful;
}

+ Delete File như sau:

/* Delete File */
public bool delete(string deleteFile)
{
bool isDeleted = false;
try
{
/* Create an FTP Request */
ftpRequest = (FtpWebRequest)WebRequest.Create(host + “/” + deleteFile);
/* Log in to the FTP Server with the User Name and Password Provided */
ftpRequest.Credentials = new NetworkCredential(user, pass);
/* When in doubt, use these options */
ftpRequest.UseBinary = true;
ftpRequest.UsePassive = true;
ftpRequest.KeepAlive = true;
/* Specify the Type of FTP Request */
ftpRequest.Method = WebRequestMethods.Ftp.DeleteFile;
/* Establish Return Communication with the FTP Server */
ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
/* Resource Cleanup */
ftpResponse.Close();
ftpRequest = null;
isDeleted = true;
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
return isDeleted;

}

/* Rename File */
public void rename(string currentFileNameAndPath, string newFileName)
{
try
{
/* Create an FTP Request */
ftpRequest = (FtpWebRequest)WebRequest.Create(host + “/” + currentFileNameAndPath);
/* Log in to the FTP Server with the User Name and Password Provided */
ftpRequest.Credentials = new NetworkCredential(user, pass);
/* When in doubt, use these options */
ftpRequest.UseBinary = true;
ftpRequest.UsePassive = true;
ftpRequest.KeepAlive = true;
/* Specify the Type of FTP Request */
ftpRequest.Method = WebRequestMethods.Ftp.Rename;
/* Rename the File */
ftpRequest.RenameTo = newFileName;
/* Establish Return Communication with the FTP Server */
ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
/* Resource Cleanup */
ftpResponse.Close();
ftpRequest = null;
}
catch (Exception ex) { Console.WriteLine(ex.ToString()); }
return;
}

Và giờ là hàm lấy size của File, nếu không có Hàm này thì khi upload và download bạn có thể sẽ không đưa được hết dữ liệu tới nơi vì nếu cái thùng của bạn bé quá sẽ không đựng được hết dữ liệu hoặc lớn quá sẽ thừa thãi.

/* Get the Size of a File */
public int getFileSize(string fileName)
{
int fileSize = 0;
try
{
/* Create an FTP Request */
ftpRequest = (FtpWebRequest)FtpWebRequest.Create(host + “/” + fileName);
/* Log in to the FTP Server with the User Name and Password Provided */
ftpRequest.Credentials = new NetworkCredential(user, pass);
/* When in doubt, use these options */
ftpRequest.UseBinary = true;
ftpRequest.UsePassive = true;
ftpRequest.KeepAlive = true;
/* Specify the Type of FTP Request */
ftpRequest.Method = WebRequestMethods.Ftp.GetFileSize;
/* Establish Return Communication with the FTP Server */
ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
/* Establish Return Communication with the FTP Server */
ftpStream = ftpResponse.GetResponseStream();

fileSize = (int)ftpResponse.ContentLength;
/* Get the FTP Server’s Response Stream */
StreamReader ftpReader = new StreamReader(ftpStream);
/* Store the Raw Response */
string fileInfo = null;
/* Read the Full Response Stream */
try
{
while (ftpReader.Peek() != -1)
{
fileInfo = ftpReader.ReadToEnd();
}
}
catch (Exception ex)
{
//Bạn nên log những thay Exception tại đây nhé
}
/* Resource Cleanup */
ftpReader.Close();
ftpStream.Close();
ftpResponse.Close();
ftpRequest = null;
/* Return File Size */
return fileSize;
}
catch (Exception ex) { Console.WriteLine(ex.ToString()); }
/* Return an Empty string Array if an Exception Occurs */
return fileSize;
}

Nếu bạn muốn lấy những file trong một thư mục thì hàm sau sẽ giúp bạn và dữ liệu trả về sẽ là một list danh sách tên file và thông tin các các file đó:

/* List Directory Contents in Detail (Name, Size, Created, etc.) */
public List<string> directoryListDetailed(string directory)
{
List<string> listFiles = new List<string>();
this.setFtpForUpload();
try
{
/* Create an FTP Request */
ftpRequest = (FtpWebRequest)FtpWebRequest.Create(host + “/” + directory);
/* Log in to the FTP Server with the User Name and Password Provided */
ftpRequest.Credentials = new NetworkCredential(user, pass);
/* When in doubt, use these options */
ftpRequest.UseBinary = true;
ftpRequest.UsePassive = true;
ftpRequest.KeepAlive = true;
/* Specify the Type of FTP Request */
ftpRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
/* Establish Return Communication with the FTP Server */
ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
/* Establish Return Communication with the FTP Server */
ftpStream = ftpResponse.GetResponseStream();
/* Get the FTP Server’s Response Stream */
StreamReader ftpReader = new StreamReader(ftpStream);
/* Store the Raw Response */
//string directoryRaw = null;
/* Read Each Line of the Response and Append a Pipe to Each Line for Easy Parsing */
try
{
while (ftpReader.Peek() != -1)
{
//directoryRaw += ftpReader.ReadLine() + “|”;
listFiles.Add(ftpReader.ReadLine());
}
}
catch (Exception ex) { Console.WriteLine(ex.ToString()); }
/* Resource Cleanup */
ftpReader.Close();
ftpStream.Close();
ftpResponse.Close();
ftpRequest = null;
/* Return the Directory Listing as a string Array by Parsing ‘directoryRaw’ with the Delimiter you Append (I use | in This Example) */
try
{
return listFiles;
//string[] directoryList = directoryRaw.Split(“|”.ToCharArray()); return directoryList;
}
catch (Exception ex)
{
errorLog.writeErrorToLogFile(ex);
}
}
catch (Exception ex) { Console.WriteLine(ex.ToString()); }
/* Return an Empty string Array if an Exception Occurs */
return new List<string> { “” };
}
}
}

Thắc mắc xin mời các bạn hỏi ạ!