File manager with CKFinder

File manager with CKFinder – Quản lý file với CKFinder

Các bước dưới đây hướng dẫn sử dụng CKFinder để quản lý và upload file với ASP.NET MVC

  • Download CKFinder và chép vào thư mục gốc của website
  • Trước thẻ </body> của trang _Layout.cshtml chèn thêm đoạn mã sau
ckfinder3
  •  Trong view cần dùng CKFinder để chèn ảnh, upload ảnh bổ sung đoạn mã sau
<input id="xFilePath" name="FilePath" type="text" class="input-block-level" />
<input type="button" value="Browse Server" onclick="BrowseServer();" class="controls" />

Lưu ý ID của điều khiển tương ứng với tên sử dụng trong phương thứ SetFileField(..)

Sau khi chạy kết quả hiển thị như hình sau

ckfinder1

Khi người dùng click nút Browse Server, màn hình như ảnh sau

ckfinder2

ASP.NET MVC Upload file – Error with FileName with full path

Lỗi:

  • Khi upload file – muốn chỉ lấy tên file nhưng trả về tên file và đường dẫn đầy đủ

Giải quyết:

  • Một số trình duyệt gặp trường hợp như vậy (như Edge) nhưng với 1 số trình duyệt thì không (Chrome, firefox)
  • Để tránh cho tất cả các trình duyệt thì sử dụng thêm mã sau
public ActionResult UploadFile(HttpPostedFile postedFile) {
    var filename = IO.Path.GetFileName(postedFile.FileName);
    var pathToSave ="Your path";
    postedFile.SaveAs(pathToSave+"/"+filename);
....
}

ASP.NET MVC Role manager Demo

Các bước dưới đây hướng dẫn cách tạo module để quản lý và phân quyền dựa trên vai trò người dùng (Role-based security)

  • Cấu hình web.config để chỉ đến cơ sở dữ liệu cần dùng

<add name=”DefaultConnection” connectionString=”Data Source=(local);Initial Catalog=DatTour;uid=sa;pwd=xxxxxx”
providerName=”System.Data.SqlClient” />

  • Tạo role và user admin mặc định

Mở file Startup.cs ngay trong thư mục gốc của ứng dụng, viết thêm đoạn mã sau

public partial class Startup
{
public void Configuration(IAppBuilder app)
{
ConfigureAuth(app);
createRolesandUsers();
}

// In this method we will create default User roles and Admin user for login
private void createRolesandUsers()
{
ApplicationDbContext context = new ApplicationDbContext();

var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(context));
var UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));
// In Startup iam creating first Admin Role and creating a default Admin User
if (!roleManager.RoleExists(“Admin”))
{

// first we create Admin rool
var role = new Microsoft.AspNet.Identity.EntityFramework.IdentityRole();
role.Name = “Admin”;
roleManager.Create(role);

//Here we create a Admin super user who will maintain the website

var user = new ApplicationUser();
user.UserName = “khanhn”;
user.Email = “khanhdsp@gmail.com”;

string userPWD = “12121212”;

var chkUser = UserManager.Create(user, userPWD);

//Add default User to Role Admin
if (chkUser.Succeeded)
{
var result1 = UserManager.AddToRole(user.Id, “Admin”);

}
}

// creating Creating Manager role
if (!roleManager.RoleExists(“Manager”))
{
var role = new Microsoft.AspNet.Identity.EntityFramework.IdentityRole();
role.Name = “Manager”;
roleManager.Create(role);

}

// creating Creating Employee role
if (!roleManager.RoleExists(“Employee”))
{
var role = new Microsoft.AspNet.Identity.EntityFramework.IdentityRole();
role.Name = “Employee”;
roleManager.Create(role);

}
}
}

Bây giờ chạy ứng dụng có thể kiểm tra được role và user được tạo ra trong csdl

  • Customize form đăng ký (Register)

Bổ sung thêm 2 đoạn code highlight dưới đây vào view Register.cshtml

@model shanuMVCUserRoles.Models.RegisterViewModel   
@{   
    ViewBag.Title = "Register";   
}   
<h2>@ViewBag.Title.</h2>   
@using (Html.BeginForm("Register", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))   
{   
    @Html.AntiForgeryToken()   
    <h4>Create a new account.</h4>   
    <hr />   
    @Html.ValidationSummary("", new { @class = "text-danger" })   
    
 class="form-group"           @Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" })            
 class="col-md-10"               @Html.TextBoxFor(m => m.Email, new { @class = "form-control" })            
        </div>        
 class="form-group"           @Html.LabelFor(m => m.UserName, new { @class = "col-md-2 control-label" })            
 class="col-md-10"               @Html.TextBoxFor(m => m.UserName, new { @class = "form-control" })            
        </div>        
 class="form-group"           @Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" })            
 class="col-md-10"               @Html.PasswordFor(m => m.Password, new { @class = "form-control" })            
        </div>        
 class="form-group"           @Html.LabelFor(m => m.ConfirmPassword, new { @class = "col-md-2 control-label" })            
 class="col-md-10"               @Html.PasswordFor(m => m.ConfirmPassword, new { @class = "form-control" })            
        </div>        
 class="form-group"           @Html.Label("user Role", new { @class = "col-md-2 control-label" })            
 class="col-md-10"               @*@Html.DropDownList("Name")*@                @Html.DropDownList("UserRoles", (SelectList)ViewBag.Name, " ")            
        </div>        
 class="form-group"           
 class="col-md-offset-2 col-md-10"                type="submit" class="btn btn-default" value="Register" />            
        </div>    }    @section Scripts {        @Scripts.Render("~/bundles/jqueryval")    }
  • Thay đổi RegisterViewModel trong lớp AccountViewModel.cs
public class RegisterViewModel   
    {   
        [Required]   
        [Display(Name = "UserRoles")]   
        public string UserRoles { getset; }   
   
        [Required]   
        [EmailAddress]   
        [Display(Name = "Email")]   
        public string Email { getset; }   
   
        [Required]   
        [Display(Name = "UserName")]   
        public string UserName { getset; }   
   
        [Required]   
        [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]   
        [DataType(DataType.Password)]   
        [Display(Name = "Password")]   
        public string Password { getset; }   
   
        [DataType(DataType.Password)]   
        [Display(Name = "Confirm password")]   
        [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]   
        public string ConfirmPassword { getset; }   
    }
  • Thay đổi code sau trong AccountController.cs

ApplicationDbContext context;

public AccountController()
{
context = new ApplicationDbContext();
}

[AllowAnonymous]
public ActionResult Register()
{
ViewBag.Name = new SelectList(context.Roles.Where(u =>!u.Name.Contains(“Admin”)).ToList(), “Name”, “Name”);
return View();
}

  • Sửa lại mã trong Register method của AccountController.cs
// POST: /Account/Register   
        [HttpPost]   
        [AllowAnonymous]   
        [ValidateAntiForgeryToken]   
        public async Task<ActionResult> Register(RegisterViewModel model)   
        {   
            if (ModelState.IsValid)   
            {   
                var user = new ApplicationUser { UserName = model.UserName, Email = model.Email };   
                var result = await UserManager.CreateAsync(user, model.Password);   
                if (result.Succeeded)   
                {   
                    await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);   
   
                    // For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=320771   
                    // Send an email with this link   
                    // string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);   
                    // var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);   
                    // await UserManager.SendEmailAsync(user.Id, "Confirm your account", "Please confirm your account by clicking <a href=\"" + callbackUrl + "\">here</a>");   
                    //Assign Role to user Here      
                    await this.UserManager.AddToRoleAsync(user.Id, model.UserRoles);   
                    //Ends Here    
                    return RedirectToAction("Index""Users");   
                }   
                ViewBag.Name = new SelectList(context.Roles.Where(u => !u.Name.Contains("Admin"))   
                                          .ToList(), "Name""Name");   
                AddErrors(result);   
            }   
   
            // If we got this far, something failed, redisplay form   
            return View(model);   
        }
  • Customize Login.cshtml để đăng nhập bằng UserName thay cho Email
@using shanuMVCUserRoles.Models   
@model LoginViewModel   
@{   
    ViewBag.Title = "Log in";   
}   
   
<h2>@ViewBag.Title</h2>   
class="row">        
class="col-md-8">            
"loginForm">                @using (Html.BeginForm("Login""Account"new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { @class = "form-horizontal", role = "form" }))                {                    @Html.AntiForgeryToken()                    

Use a local account to log in.

                    
                    @Html.ValidationSummary(true""new { @class = "text-danger" })                    
class="form-group">                        @Html.LabelFor(m => m.UserName, new { @class = "col-md-2 control-label" })                        
class="col-md-10">                            @Html.TextBoxFor(m => m.UserName, new { @class = "form-control" })                            @Html.ValidationMessageFor(m => m.UserName, ""new { @class = "text-danger" })                        
                    </div>                    
class="form-group">                        @Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" })                        
class="col-md-10">                            @Html.PasswordFor(m => m.Password, new { @class = "form-control" })                            @Html.ValidationMessageFor(m => m.Password, ""new { @class = "text-danger" })                        
                    </div>                    
class="form-group">                        
class="col-md-offset-2 col-md-10">                            
class="checkbox">                                @Html.CheckBoxFor(m => m.RememberMe)                                @Html.LabelFor(m => m.RememberMe)                            
                        </div>                    </div>                    
class="form-group">                        
class="col-md-offset-2 col-md-10">                            "submit" value="Log in" class="btn btn-default" />                        
                    </div>                    <p>                        @Html.ActionLink("Register as a new user""Register")                    </p>                    @* Enable this once you have account confirmation enabled for password reset functionality                        <p>                            @Html.ActionLink("Forgot your password?""ForgotPassword")                        </p>*@    }            </section>        </div>        
class="col-md-4">            
"socialLoginForm">                @Html.Partial("_ExternalLoginsListPartial"new ExternalLoginListViewModel { ReturnUrl = ViewBag.ReturnUrl })            
        
    </div>        @section Scripts {        @Scripts.Render("~/bundles/jqueryval")    }
  • Sửa lại LoginViewModel
public class LoginViewModel   
    {   
        [Required]   
        [Display(Name = "UserName")]   
        public string UserName { getset; }   
 
        [Required]   
        [DataType(DataType.Password)]   
        [Display(Name = "Password")]   
        public string Password { getset; }   
   
        [Display(Name = "Remember me?")]   
        public bool RememberMe { getset; }   
    }
  • Sửa lại code của Login action method của AccountController.cs
// POST: /Account/Login   
        [HttpPost]   
        [AllowAnonymous]   
        [ValidateAntiForgeryToken]   
        public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)   
        {   
            if (!ModelState.IsValid)   
            {   
                return View(model);   
            }   
   
            // This doesn't count login failures towards account lockout   
            // To enable password failures to trigger account lockout, change to shouldLockout: true   
            var result = await SignInManager.PasswordSignInAsync(model.UserName, model.Password, model.RememberMe, shouldLockout: false);   
            switch (result)   
            {   
                case SignInStatus.Success:   
                    return RedirectToLocal(returnUrl);   
                case SignInStatus.LockedOut:   
                    return View("Lockout");   
                case SignInStatus.RequiresVerification:   
                    return RedirectToAction("SendCode"new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });   
                case SignInStatus.Failure:   
                default:   
                    ModelState.AddModelError("""Invalid login attempt.");   
                    return View(model);   
            }   
        }   
  • Tạo UsersController.cs và viết code cho Controller như sau

[Authorize]
public class UsersController : Controller
{
// GET: Users
public ActionResult Index()
{
if (User.Identity.IsAuthenticated)
{
var user = User.Identity;
ViewBag.Name = user.Name;

ViewBag.displayMenu = “No”;

if (isAdminUser())
{
ViewBag.displayMenu = “Yes”;
}
return View();
}
else
{
ViewBag.Name = “Not Logged IN”;
}
return View();
}
public Boolean isAdminUser()
{
if (User.Identity.IsAuthenticated)
{
var user = User.Identity;
ApplicationDbContext context = new ApplicationDbContext();
var UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));
var s = UserManager.GetRoles(user.GetUserId());
if (s[0].ToString() == “Admin”)
{
return true;
}
else
{
return false;
}
}
return false;
}
}

  • Index.cshtml view của Users controller

@{
ViewBag.Title = “Index”;
}

@if (ViewBag.displayMenu == “Yes”)
{
<h1>Welcome Admin. Now you can create user Role.</h1>
<h3>
<li>@Html.ActionLink(“Manage Role”, “Index”, “Role”)</li>
</h3>
}
else
{
<h2> Welcome <strong>@ViewBag.Name</strong> 🙂 .We will add user module soon </h2>
}

  • Tạo Empty RoleController.cs và viết code như sau

[Authorize]
public class RoleController : Controller
{
ApplicationDbContext context;

public RoleController()
{
context = new ApplicationDbContext();
}
// GET: Role
public ActionResult Index()
{
if (User.Identity.IsAuthenticated)
{
if (!isAdminUser())
{
return RedirectToAction(“Index”, “Home”);
}
}
else
{
return RedirectToAction(“Index”, “Home”);
}
var Roles = context.Roles.ToList();
return View(Roles);
}

public Boolean isAdminUser()
{
if (User.Identity.IsAuthenticated)
{
var user = User.Identity;
ApplicationDbContext context = new ApplicationDbContext();
var UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));
var s = UserManager.GetRoles(user.GetUserId());
if (s[0].ToString() == “Admin”)
{
return true;
}
else
{
return false;
}
}
return false;
}
/// <summary>
/// Create a New role
/// </summary>
/// <returns></returns>
public ActionResult Create()
{
if (User.Identity.IsAuthenticated)
{
if (!isAdminUser())
{
return RedirectToAction(“Index”, “Home”);
}
}
else
{
return RedirectToAction(“Index”, “Home”);
}
var Role = new IdentityRole();
return View(Role);
}

/// <summary>
/// Create a New Role
/// </summary>
/// <param name=”Role”></param>
/// <returns></returns>
[HttpPost]
public ActionResult Create(IdentityRole Role)
{
if (User.Identity.IsAuthenticated)
{
if (!isAdminUser())
{
return RedirectToAction(“Index”, “Home”);
}
}
else
{
return RedirectToAction(“Index”, “Home”);
}
context.Roles.Add(Role);
context.SaveChanges();
return RedirectToAction(“Index”);
}
}

  • Tạo Index view và create view cho RoleController như sau

Index.cshtml

@model IEnumerable<Microsoft.AspNet.Identity.EntityFramework.IdentityRole>
@{
ViewBag.Title = “Add Role”;
}
<table style=” background-color:#FFFFFF; border: dashed 3px #6D7B8D; padding: 5px;width: 99%;table-layout:fixed;” cellpadding=”6″ cellspacing=”6″>
<tr style=”height: 30px; background-color:#336699 ; color:#FFFFFF ;border: solid 1px #659EC7;”>
<td align=”center” colspan=”2″>
<h2> Create User Roles</h2>
</td>

</tr>

<tr>
<td>
<table id=”tbrole” style=”width:100%; border:dotted 1px; background-color:gainsboro; padding-left:10px;”>

@foreach (var item in Model)
{
<tr>
<td style=”width:100%; border:dotted 1px;”>
@item.Name
</td>
</tr>}
</table>
</td>
<td align=”right” style=”color:#FFFFFF;padding-right:10;”>
<h3> @Html.ActionLink(“Click to Create New Role”, “Create”, “Role”) </h3>
</td>
</tr>
</table>

Create.cshtml

@model Microsoft.AspNet.Identity.EntityFramework.IdentityRole
@{
ViewBag.Title = “Add New Role”;
}
<h2>Add New User Role:</h2>

@using (Html.BeginForm())
{
<p> Enter User Role Name:</p>

@Html.EditorFor(m => m.Name)
<input type=”submit” value=”Create Role” />
}

Code hơi dài, hy vọng bạn thực hiện theo các bước thành công. Nếu không bạn có thể download mã nguồn ở link này

Source: bài viết có tham khảo demo của Micrsoft.

ASP.NET MVC Razor pass model to layout

Các  bước thực hiện:

  1. Add thuộc tính vào controller hoặc Base controller, ví dụ LayoutViewModel hoặc bất kỳ tên gì bạn muốn.
  2. Trong hàm dựng (Constructor của Controller), khởi tạo dữ liệu cho thuộc tính đó
  3. Gán cho ViewData hoặc ViewBag
  4. Trong Layout, ép kiểu hoặc sử dụng dữ liệu đó một cách phù hợp

Ví dụ Controller:

public class MyController : Controller
{
    public DataTable LayoutViewModel { get; set; }

    public MyController()
    {
        this.LayoutViewModel = new LayoutViewModel();
        this.LayoutViewModel = new LoadDataTable();

        this.ViewData["LayoutViewModel"] = this.LayoutViewModel;
    }

}

Trong Layout Page

@{
var viewModel = (DataTable)ViewBag.LayoutViewModel;
}

Sau khi chúng ta đã có biến viewModel chưa dữ liệu cần lấy, lúc đó kết gán hoặc hiển thị theo chúng ta muốn.

Broadcast real time when data change in database

Hướng dẫn dưới đây về việc broadcase real time khi có thay đổi dữ liệu trong cơ sở dữ liệu (broadcase realtime when data change in database).

Kỹ thuật liên quan để áp dụng bao gồm:

  • SignalR
  • SqlDependency class
  • Sql Service Broker

Các bước cài đặt

  • Thiết lập Sql Service Broker: ON

ALTER DATABASE MyDB SET ENABLE_BROKER;

  • Cài đặt và viết mã SignalR

Mở NuGet Package Manager Console  và gõ lệnh sau

install-package Microsoft.AspNet.SignalR

  • Thiết lập chuỗi kết nối

 

DefaultConnection” connectionString=”data source=SERVER-NAME;database=DATABASENAME;user id =USERID;password=PASSOWRD” providerName=”System.Data.SqlClient” />

 

  • Tạo SignalR Hub class và viết mã nguồn như sau (sử dụng SqlDependency)

[HubName(“notificationHub”)]
public class NotificationHub : Hub
{

Int16 totalNewMessages = 0;
Int16 totalNewCircles = 0;
Int16 totalNewJobs = 0;
Int16 totalNewNotification = 0;

[HubMethodName(“sendNotifications”)]
public void SendNotifications()
{
using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings[“DefaultConnection”].ConnectionString))
{
string query = “SELECT NewMessageCount, NewCircleRequestCount, NewNotificationsCount, NewJobNotificationsCount FROM [dbo].[Modeling_NewMessageNotificationCount] WHERE UserProfileId= 1”;
//(select max(UserProfileId) from [dbo].[Modeling_NewMessageNotificationCount])
connection.Open();
using (SqlCommand command = new SqlCommand(query, connection))
{
try {
command.Notification = null;
DataTable dt = new DataTable();
SqlDependency dependency = new SqlDependency(command);
dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);
if (connection.State == ConnectionState.Closed)
connection.Open();
var reader = command.ExecuteReader();
dt.Load(reader);
if (dt.Rows.Count > 0)
{
totalNewMessages = Int16.Parse(dt.Rows[0][“NewMessageCount”].ToString());
totalNewCircles = Int16.Parse(dt.Rows[0][“NewCircleRequestCount”].ToString());
totalNewJobs = Int16.Parse(dt.Rows[0][“NewJobNotificationsCount”].ToString());
totalNewNotification = Int16.Parse(dt.Rows[0][“NewNotificationsCount”].ToString());
}
connection.Close();
}
catch(Exception ex)
{
throw;
}
}
}

//Call function on Client
IHubContext context = GlobalHost.ConnectionManager.GetHubContext();
context.Clients.All.RecieveNotification(totalNewMessages, totalNewCircles, totalNewJobs, totalNewNotification);
}
private void dependency_OnChange(object sender, SqlNotificationEventArgs e)
{
if (e.Type == SqlNotificationType.Change)
{
NotificationHub nHub = new NotificationHub();
nHub.SendNotifications();
}
}
}

  • Mapping SignalR trong Startup.cs class
[assembly: OwinStartup("Testing", typeof(MyStartup))]
 public class MyStartup
 {
 public void Configuration(IAppBuilder app)
 {
 app.MapSignalR(); 
 }
 }
  • Start and Stop SqlDependency
Global.asax 
void Application_Start(object sender, EventArgs e)  
    { 
        // Code that runs on application startup 
        System.Data.SqlClient.SqlDependency.Start(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString); 
    } 
     
    void Application_End(object sender, EventArgs e)  
    { 
        //  Code that runs on application shutdown 
        System.Data.SqlClient.SqlDependency.Stop(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString); 
 
    }
  • Client code
 
    New Notifications 
    "Scripts/jquery-1.6.4.min.js"> 
    "Scripts/jquery.signalR-2.0.2.min.js">         
    "signalr/hubs"> 
    "text/javascript"> 
        $(function () {             
            // Declare a proxy to reference the hub. 
            var notifications = $.connection.notificationHub; 
            debugger; 
            // Create a function that the hub can call to broadcast messages. 
            notifications.client.recieveNotification = function (totalNewMessages, totalNewCircles, totalNewJobs, totalNewNotifications) { 
                // Add the message to the page.                 
                $('#spanNewMessages').text(totalNewMessages); 
                $('#spanNewCircles').text(totalNewCircles); 
                $('#spanNewJobNotifications').text(totalNewJobs); 
                $('#spanNewNotifications').text(totalNewNotifications); 
            }; 
            // Start the connection. 
            $.connection.hub.start().done(function () { 
                notifications.server.sendNotifications(); 
            }).fail(function (e) { 
                alert(e); 
            }); 
            //$.connection.hub.start();             
        }); 
     
  

Broadcast Realtime SQL data using SignalR


You have “spanNewMessages”>0 New Message Notification.
You have “spanNewCircles”>0 New Circles Notification.
You have “spanNewJobNotifications”>0 New Job Notification.
You have “spanNewNotifications”>0 New Notification.

 

Source: Microsoft