Friday, July 31, 2015

加拿大退休计划面面观

移民加拿大都是鉴于这里优美的自然环境、优厚的福利制度以及丰富的多元文化,为了追求更美好的生活,并实现老有所养。那么,当在你打拼数十年,到了安度晚年的时候,你将能享受哪些加拿大的国家福利待遇呢?领到的退休金是否能保证晚年无忧呢?自己需要做哪些方面的储蓄准备呢?
 
  加拿大退休金计划始于1966年。设立的目的是为保障供款人在年老退休时,或者因伤残而失去工作能力或去世时,他本人及其家人不致陷入经济困境。这是一个集合了由雇员、雇主、自雇人士的供款及加拿大退休金计划投资基金所投资的收益。除魁北克省外,在加拿大其它各省均有实行。

  无论受雇或自雇人士,都必须将所赚取的工资的一个百分率供给退休金计划。雇员供多少,雇主亦要供同样数目的款项入雇员的退休金计划户口内。如果是自雇人士,就要自己负担全部的供款。供款越多或年期越长,则将来可领取的退休金金额会愈高。

  加拿大退休金计划可提供的福利金:
  • 伤残津贴
  • 遗属养恤金,包括:
  o 一次支付的死亡抚恤金;
  o 向已经去世的供款人的配偶或同居伴侣按月支付遗属养恤金,
  o 向已经去世的加拿大退休金计划供款人的受抚养子女按月支付子女抚养费。

  伤残津贴:
  • 符合某些要求的加拿大退休金计划供款人及其子女。供款人必须由于严重且长期持续的伤残而不能从事任何正常工作。

  遗属养恤金:
  • 如果已经去世的供款人向加拿大退休金计划缴纳供款的时间长度达到最低期限,其配偶、同居伴侣、子女则可领取遗属养恤金,或将该福利金归入其财产。

  申请领取退休金的人士,必须符合以下资格:
  (1) 曾经在加拿大工作及供过退休金供款
  (2) 年龄在65岁或以上
  (3)如你选择在60至64岁之间领取退休金,必定要在开始领取退休金这个月及上个月底前,完全或大部份时间停止受雇或自雇工作。意思即是你的收入不能超过现时65岁退休人士可领取最高的退休金金额。

  退休金是不会在你退休后自动发给你,你必须向加拿大人力资及社会发展部的入息保障办事处申请,除非你已经正在领取伤残退休金,就会在你65岁时自动改领一般的退休金。
  
计算退休金的金额是根据你在供款的年期内曾供款多少及多久而决定,塬则上,供款愈多及年期愈长,则将来可领取的退休金金额会愈高。领取的金额是你的供款年期平均每月退休金供款入息的25%。此外,领取退休金时的年龄也会响你可领取的金额。退休金一般是65岁时领取,但如果你年龄在60至64岁之间,而完全或大部份时间已停止工作,则可提早领取。同样,你也可选择延迟领取退休金,但最迟只可延至70岁,其分别如下:

  (1) 选择在65岁领取退休金的人士可在65岁生日后的一个月开始领取退休金。领取的金额是你的供款年期平均每月供款收入的25%。你不必在开始领取退休金后便停止工作,只是不再需要供款给加拿大退休金计划。退休金金额是会每年按生活指数而调整的。

  (2) 选择在60岁至64岁间领取退休金的人士,所得的退休金金额会少过选择在65岁时应领取退休金的数目,每早一个月则少领0.5%。举例来说,在65岁应得 100%退休金,但如果在60岁时退休,即在65岁前60个月退休并领取退休金,金额会每早一个月少0.5%,提早60个月则一共少了30%,所得的金额只有65岁时领取的70%。又举例如果在63岁时退休并申请退休金,即在65岁前提早24个月领取,便会少12%,所得的金额是65岁时领取的88%。选择提早领取退休金的金额是不会在65岁时自动调整回65岁退休时应得的数目,但你领取的年期已比在65岁时领取较长。另外,选择在60至64岁之间领取退休金,在领取这个月及上个月底前,必定要完全或大部份时间停止受雇或自雇工作。同样,当开始领取退休金后,就不需要再供款给加拿大退休金计划。而每年随着生活指数的改变,退休金的数目亦会作出适当的调整。

  (3) 选择在65岁至70岁之间领取退休金的人士,所得的退休金金额是会比在65岁时领取的应得数目为多,而每迟一个月则多0.5%。举例来说,在65岁时领取退休金应得100%,但如延到67岁才领取,即在65岁后24个月,每迟一个月可多领0.5%,24个月则多了12%,所得的金额是65岁时领取的 112%。又举例如果在70岁才领取退休金的话,即65岁后的60个月,金额便比65岁时领取多出30%。选择在65岁之后领取退休金的人士是不用停止工作,一旦开始领取退休金,是不用再供款给加拿大退休金计划。同样所得的金额是会按生活指数而调整的。退休金最迟于70岁时申请,如你在70岁之后才申请,金额是会与70岁时申请一样。因为任何人士过了70岁后,不论是否已领取退休金或继续工作,也不能再继续供款给加拿大退休金计划。)

  申请退休金的人士可在其计划开始领取的日期前6个月递交申请表,若你迟交申请表,在某些情况下,加拿大退休金计划会补回前12个月的退休金给你。表格可向你居住地区的加拿大人力资及社会发展部入息保障办事处索取或致电1-800-277-9914。你也可以从其网址www.sdc.gc.ca下载表格。填妥表格后,连同有关的加拿大身份証明文件寄回入息保障办事处,地址附于表格内。如你附上証明文件的影印本,必须由指定的专业人仕认证。

  不论选择在60岁至70岁之间任何一个年龄领取退休金的人士,都可以在领取退休金首六个月内申请退出,只要用书面提出要求并归还全部已领取的款项。如果在领取退休金首六个月的期间仍继续工作,则还要补供退休金供款。

  退休金是按月以支票寄给你或自动转账存入你指定的户口内,通常是每月最后的叁天内收到金额,就算申请人并非在加拿大居住,也可以一直领取退休金,直至去世为止。

  你会得到多少钱?按目前的标准,合资格人士每月最多可获发551.54元老年退休金。

  若你的收入不高,也可以获发保证收入补助金。门槛是个人收入16,728元,包括全数老年退休金;二人收入上限则为22,080元,当中包括二人全数领取的老年退休金。

  什么时候将註册退休储蓄计划(RRSP)兑为入息?
  你必须在年届71岁那年的12月31日或以前,将RRSP中所有投资套现或兑为入息。你可随时把RRSP转为註册退休入息基金(RRIF)或终身年金,无须等到71岁。RRIF帐户后每年设最低提款下限,金额逐年递增,而提出的金钱须全支付全额税款。你可能想在限期前提早把RRSP变换,并把不是日常开支的部分转帐至免税储蓄户口,或非註册投资帐户。这样做能加强管理税款,避免被挤到更高的税级中。退休人士要考虑的不是税前、而是税后入息。

  你会更新雇员福利吗?
  你的雇主或会替你支付或津贴各种保险费用,包括牙科保健、视力保健、药物和嵴椎保健等。这些福利或会在你退休、或年届65岁后(就算仍在工作)遭削减。你应自行购买保险吗?应买保额多少的计划?

  认可理财规划师Heather Freed,负责在人们从团体保险过渡至个人保险期间提供协助。她表示,一个家庭每月的保健和牙医保险费,约为250至350元,个人的保险费则平均为125至175元,两者皆未包括人寿和残疾保险。

  Freed又说,人们作出决定前,必须知道两项重要事情,你的员工保险值多少钱?承保范围是什么?赔偿金额有多少?

  若你是员工保险的经常使用者,应察看能否把它转变为个人保险。更改死线可能十分短促,注意不要延误。

  这些决定都不容易做,应小心考虑采纳各种方案后的影响,并寻求有能顾问协助。

Monday, July 27, 2015

Enabling ASP.Net MVC client validation for Kendo UI components

You might have stumbled upon this page because you are getting crazy in trying out all sort of solutions to make the client validation work for your Kendo components such as DropDownListForDatePickerForComboBoxFor, etc. You might have tried several suggestions you saw online like setting the validator defaults in your JavaScript like the samples below
$.validator.setDefaults({
    ignore: ""
});
or
   <script>
       $.validator.defaults.ignore = "";
   </script>
or
<script type="text/javascript">
    $(function () {
        var form = $('#yourFormName');
        form.data('validator').settings.ignore = ''// default is ":hidden".
    });
</script>
Some even offer not equating it to empty string but use an empty array
Do they all look similar?
Don't worry I tried them all as well but no luck and if you are using Unobtrusive validation I am not sure those solutions will not work.
Lets say you have a simple form like this.
01 Form
All you want to do is show that red outline when it’s validating like the one shown by the red arrows. But look at those other components shown by the blue arrows they are not validating.
02 Form
Whats the difference? they are all Kendo UI objects and since it’s a Kendo UI object we can use their validators so we don’t need to recreate whats already in there.
Lets just get some parts on my codes to properly demonstrate this.
First you need to properly set your DataAnnotation attributes. So for the viewModel in that example it will look like this
public class RegisterPageViewModel
{
    [DisplayName("First Name")]
    [Required]
    public string FirstName { getset; }

    [DisplayName("Last Name")]
    [Required]
    public string LastName { getset; }

    [DisplayName("Company Email")]
    [Required]
    public string CompanyEmail { getset; }

    [DisplayName("Date of Birth")]
    [Required]
    public DateTime? BirthDate { getset; }

    [DisplayName("First Secret Question")]
    [Required]
    public int SecretQuestion1Id { getset; }

    public IList<SelectListItem> SecretQuestion1IdList { getset; }

    [DisplayName("Answer to First Secret Question")]
    [Required]
    public string SecretQuestionAnswer1 { getset; }

    [DisplayName("Second Secret Question")]
    [Required]
    public int SecretQuestion2Id { getset; }

    public IList<SelectListItem> SecretQuestion2IdList { getset; }

    [DisplayName("Answer to Second Secret Question")]
    [Required]
    public string SecretQuestionAnswer2 { getset; }

    [Required]
    public int TrustedDomainId { getset; }

    public IList<SelectListItem> TrustedDomain { getset; }

}
Then on your view it looks like this
@model ExternalUserManagement.Web.Mvc.Controllers.ViewModels.Register.RegisterPageViewModel
@{
    ViewBag.Title = "Register";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
<div id="accountDetails" class="centre-container">
    @using (Ajax.BeginForm("CreateAccount""Register",
        new AjaxOptions
        {
            UpdateTargetId = "accountDetails",
            OnBegin = "windowHelper.displayWaitingDialog('Saving Registration Details, please wait...')",
            OnComplete = "windowHelper.close()"
        }))
    {  
        <p class="message information">Register you details, then click submit.</p>

        <div class="row">
            @Html.LabelFor(m => m.FirstName, new { @class = "label" })
            @Html.TextBoxFor(m => m.FirstName, new { @class = "input k-textbox" })
        </div>
        <div class="row">
            @Html.LabelFor(m => m.LastName, new { @class = "label" })
            @Html.TextBoxFor(m => m.LastName, new { @class = "input k-textbox" })

        </div>
        <div class="row">
            @Html.LabelFor(m => m.CompanyEmail, new { @class = "label" })
            @Html.TextBoxFor(m => m.CompanyEmail, new { @class = "input-left k-textbox" })
            
            @(Html.Kendo().DropDownListFor(m => m.TrustedDomainId)
                      .DataTextField("Text")
                      .DataValueField("Value")
                      .BindTo(Model.TrustedDomain)
                      .OptionLabel(" -- Please Select --")
                      .HtmlAttributes(new { @class = "input-right" })
                      )
        </div>
        <div class="row">
            @Html.LabelFor(m => m.BirthDate, new { @class = "label" })
            @Html.Kendo().DatePickerFor(m => m.BirthDate).HtmlAttributes(new { @class = "input" })
        </div>
        <div class="row">
            @Html.LabelFor(m => m.SecretQuestion1Id, new { @class = "label" })
            @(Html.Kendo().DropDownListFor(m => m.SecretQuestion1Id)
                      .DataTextField("Text")
                      .DataValueField("Value")
                      .BindTo(Model.SecretQuestion1IdList)
                      .OptionLabel(" -- Please Select --")
                      .HtmlAttributes(new { @class = "input" })
                      )
        </div>
        <div class="row">
            @Html.LabelFor(m => m.SecretQuestionAnswer1, new { @class = "label" })
            @Html.TextBoxFor(m => m.SecretQuestionAnswer1, new { @class = "input k-textbox" })
        </div>
        <div class="row">
            @Html.LabelFor(m => m.SecretQuestion2Id, new { @class = "label" })
            @(Html.Kendo().DropDownListFor(m => m.SecretQuestion2Id)
                      .DataTextField("Text")
                      .DataValueField("Value")
                      .BindTo(Model.SecretQuestion2IdList)
                      .OptionLabel(" -- Please Select --")
                      .HtmlAttributes(new { @class = "input" }).AutoBind(true)
                      )
        </div>
        <div class="row">
            @Html.LabelFor(m => m.SecretQuestionAnswer2, new { @class = "label" })
            @Html.TextBoxFor(m => m.SecretQuestionAnswer2, new { @class = "input k-textbox" })
        </div>
        <div class="captcha row">
            @Html.Label("Are you a human?"new { @class = "label" })
            <br />
            @Html.Raw(Html.GenerateCaptcha("captcha""clean"))
            @Html.ValidationMessage("Invalid Characters")
        </div>
        <div class="row">
            <div class="commands">
                <button class="k-button" type="submit" title="Sumbit">
                    <img src="@Url.Content("~/Content/Images/Icons/disk.png")" alt="" />
                    Sumbit
                </button>
            </div>
        </div>
    }
</div>
So if you’re not using Kendo UI components it would work normally but you are, that’s why you are reading this.  So the solution is simple.
Just add this
<script>
    $(function () {
        $("form").kendoValidator();
    });
</script>
and it would all start to magically validate like this.  Anyways if you found any other solution other than this, I guess you need to change it as this is directly using Kendo’s validation functions and is documented here.
03 Working
You do not even need a ValidationMessageFor.  But if you really need to you can add them like this without any side effects :)
@(Html.Kendo().DropDownListFor(m => m.TrustedDomainId)
            .DataTextField("Text")
            .DataValueField("Value")
            .BindTo(Model.TrustedDomain)
            .OptionLabel(" -- Please Select --")
            .HtmlAttributes(new { @class = "input-right" })
            )
@Html.ValidationMessageFor(m => m.TrustedDomainId)

Tuesday, July 21, 2015

Handling authentication-specific issues for AJAX-calls

For modern web-applications has become the usual to use AJAX when you create user interfaces. However, it makes our headache from time to time. And often these difficulties are associated with authentication and processing such requests on the client.

Introduction

For modern web-applications has become the usual to use AJAX when you create user interfaces. However, it makes our headache from time to time. And often these difficulties are associated with authentication and processing such requests on the client.

The problem

Imagine, that you have some web-application which communicates with server by using jQuery and JSON.
Server side:
[HttpPost]
public ActionResult GetData()
{
 return Json(new
 {
  Items = new[]
  {
   "Li Chen",
   "Abdullah Khamir",
   "Mark Schrenberg",
   "Katy Sullivan",
   "Erico Gantomaro",
  }
 });
}
Client side:
var $list = $("#list");
var $status = $("#status");
$list.empty();
$status.text("Loading...");

$.post("/home/getdata")
 .always(function() {
  $status.empty();
 })
 .success(function(data) {
  for (var i = 0; i < data.Items.length; i++) {
   $list.append($("
  • "
  • ).text(data.Items[i])); } });
    That is pretty simple. Let’s add a simple authentication to our web-application. And again it is a pretty simple – just use Forms Authentication and Authorize attribute from ASP.NET MVC. The controller’ code will change as:
    [HttpPost]
    [Authorize]
    public ActionResult GetData()
    {
     return Json(new
     {
      Items = new[]
      {
       "Li Chen",
       "Abdullah Khamir",
       "Mark Schrenberg",
       "Katy Sullivan",
       "Erico Gantomaro",
      }
     });
    }
    Still have no problems. Once user authenticated in application, he able to see the page and can retreive a data. However, there is a some problem when authentication timeout expired. In this case server will send to user…HTTP 302 Found.
    HTTP 302 Found
    Obviously, that the client code in our case did not expect this and as a result application will not work properly.

    Reasons

    Before we will fix the code, let’s understand what happens. Why server send HTTP 302? That would be logical to assume that there must be a HTTP 401. The point is that when we use FormsAuthentication at backstage acts FormsAuthenticationModule (which registered in global web.config file by default). Look under the hood of the module, you can easily understand that if the current code for HTTP is 401, then it performs a redirect, i.e. replaces it on 302:
    Redirect
    It is easy to guess that the purpose is to redirect a user to the login page, if the request is not processed successfully (status code is 401). In this case, the user will see the good login form, but not the IIS error code. Makes sense, doesn't it?
    From the point of view of our ASP.NET MVC application a pipeline is something like this:
    1. A request comes in to the application, where faced a filter AuthorizeAttribute.
    2. Because of the user is not authenticated, then this filter will return the HTTP 401, which is logical (see this easily enough by using reflector and check implementation of this filter).
    3. Well, after that our FormsAuthenticationModule acts and replaces HTTP 401 with redirect.
    As a result – when we trying to request a page with usual HTTP-request we will see login page (which is good), but when we use AJAX-calls, there is too hard to parse such answers (which is bad).

    The solution

    So, what we need to solve the problem –
    1. Server should return HTTP 401/403 for AJAX-calls and HTTP 302 for usual HTTP-calls.
    2. To handle HTTP 401/403 on a client-side.
    To be honest, you can override FormsAuthenticationModule logic to don’t replace HTTP 401 request with 302. To do it you can use SuppressFormsAuthenticationRedirect propery:
    SuppressFormsAuthenticationRedirect
    The only question is when to modify this property and who will do it?
    Before answering this question, let’s turn our attention to how client should handle cases with HTTP-errors. There is two ways –
    1. The user is not authenticated in application (401). In this case we should redirect him to a login page.
    2. The user is authenticated in application, but have no enough permissions to access to the resource (403). For example, user not in role, which is necessary for current HTTP-request. In this case it is too silly to redirect him to a login page. The more preferred way is to say him that he is not have a necessary permissions.
    Thus we should handle both cases. Let’s take a look on AuthorizeAttribute once again.
    AuthorizeAttribute
    …i.e. he will always send HTTP 401.
    Not good. Therefore we should fix a bit this behavior. So, let’s get started.
    First – let’s determine whether current HTTP-request is AJAX-request. If yes, we should disable replacing HTTP 401 with HTTP 302:
    public class ApplicationAuthorizeAttribute : AuthorizeAttribute
    {
     protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
     {
      var httpContext = filterContext.HttpContext;
      var request = httpContext.Request;
      var response = httpContext.Response;
    
      if (request.IsAjaxRequest())
       response.SuppressFormsAuthenticationRedirect = true;
    
      base.HandleUnauthorizedRequest(filterContext);
     }
    }
    Second – let’s add a condition:: if user authenticated, then we will send HTTP 403; and HTTP 401 otherwise.
    public class ApplicationAuthorizeAttribute : AuthorizeAttribute
    {
     protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
     {
      var httpContext = filterContext.HttpContext;
      var request = httpContext.Request;
      var response = httpContext.Response;
      var user = httpContext.User;
    
      if (request.IsAjaxRequest())
      {
       if (user.Identity.IsAuthenticated == false)
        response.StatusCode = (int)HttpStatusCode.Unauthorized;
       else
        response.StatusCode = (int)HttpStatusCode.Forbidden;
    
       response.SuppressFormsAuthenticationRedirect = true;
       response.End();
      }
    
      base.HandleUnauthorizedRequest(filterContext);
     }
    }
    Well done. Now we should replace all usings of standard AuthorizeAttribute with this new filter. It may be not applicable for sime guys, who is aesthete of code. But I don’t know any other way. If you have, let’s go to comments, please.
    The last, what we should to do – to add HTTP 401/403 handling on a client-side. We can use ajaxError at jQuery to avoid code duplication:
    $(document).ajaxError(function (e, xhr) {
     if (xhr.status == 401)
      window.location = "/Account/Login";
     else if (xhr.status == 403)
      alert("You have no enough permissions to request this resource.");
    });
    The result –
    • If user is not authenticated, then he will be redirected to a login page after any AJAX-call.
    • If user is authenticated, but have no enough permissions, then he will see user-friendly erorr message.
    • If user is authenticated and have enough permissions, the there is no any errors and HTTP-request will be proceeded as ususal.
    The only disadvantage is necessity to use ApplicationAuthorizeAttribute instead of standard AuthorizeAttribute. So, if you have some code which uses AuthorizeAttribute, then you should fix it.
    Sources placed on github.

    License

    This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)