Microshaoft Cross-Domain + ASP.NET MVC 5 WebAPI 2 + Self-Host + JsonpMediaTypeFormatter + WCF + JsonP + PerformaceCounterFilter + Knockout.js + MVVM

/*
:: rem curl Post Json
D:\curl\curl-7.33.0-win64\bin\curl.exe -i -X POST -H "Accept: application/json" -H "Content-Type: application/json; charset=utf-8" -d "[{Name:'curl1',\"Age\":0,'Height':1,'Weight':2},{'Name':\"curl2\",'Age':0,'Height':1,'Weight':2}]" "http://api.asp.net.local/services/restful/api/persons/" -v
:: rem for fiddler proxy
D:\curl\curl-7.33.0-win64\bin\curl.exe -i -x http://127.0.0.1:8888 -U user01:password01! -X POST -H "Accept: application/json" -H "Content-Type: application/json; charset=utf-8" -d "[{Name:'curl1',\"Age\":0,'Height':1,'Weight':2},{'Name':\"curl2\",'Age':0,'Height':1,'Weight':2}]" "http://api.asp.net.local/services/restful/api/persons/" -v
*/
namespace Microshaoft
{
    using Microshaoft.WCF.Services;
    using Microshaoft.Web;
    using Microshaoft.Win32;
    using System;
    using System.Collections;
    using System.ComponentModel;
    using System.Configuration.Install;
    using System.Security.Principal;
    using System.ServiceModel.Web;
    using System.ServiceProcess;
    using System.Web.Http.SelfHost;
    public class WindowsServiceHost : ServiceBase
    {
        static void Main(string[] args)
        {
            Console.WriteLine(Environment.CommandLine);
            WindowsServiceHost service = new WindowsServiceHost();
            int l = 0;
            bool needFreeConsole = false;
            if (args != null)
            {
                l = args.Length;
            }
            if (l > 0)
            {
                if (args[0].ToLower() == "/console")
                {
                    needFreeConsole = true;
                    Console.Title = "Service Run as Console ...";
                    Console.WriteLine("Alloc Console ...");
                    NativeMethods.AllocConsole();
                    service.OnStart(args);
                    Console.ReadLine();
                    return;
                }
            }
            Console.WriteLine("Service");
            ServiceBase.Run(service);
            if (needFreeConsole)
            {
                Console.WriteLine("Free Console ...");
                NativeMethods.FreeConsole();
            }
        }
        //public WindowsServiceHost()
        //{
        //CanPauseAndContinue = true;
        //}
        protected override void OnStart(string[] args)
        {
            Console.WriteLine("[{0}]", string.Join(" ", args));
            Console.WriteLine("Current User Identity: {0}", WindowsIdentity.GetCurrent().Name);
            Console.WriteLine(".Net Framework version: {0}", Environment.Version.ToString());
            // MVC WebAPI Self-Host Service
            var config = new HttpSelfHostConfiguration("http://localhost:9080/");
            MvcApiConfigHelper.Config(config);
            PerformanceCountersConfiguration.AttachPerformanceCounters();
            HttpSelfHostServer httpSelfHostServer = new HttpSelfHostServer(config);
            {
                httpSelfHostServer.OpenAsync().Wait();
                //Console.WriteLine("Press Enter to quit.");
                //Console.ReadLine();
            }
            // WCF Self-Host Service
            WebServiceHost webServiceHost = new WebServiceHost(typeof(PersonsServices));
            {
                webServiceHost.Open();
                //Console.ReadLine();
            }
            // Client Test
            ClientTest
                .Program
                    .Main1
                        (
                            new string[]
                            {
                                @"http://api.asp.net.local/services/restful/api/Persons/"
                            }
                        );
            ClientTest
                .Program
                    .Main1
                        (
                            new string[]
                            {
                                @"http://localhost:9080/services/restful/api/Persons/"
                            }
                        );
        }
    }
    [RunInstallerAttribute(true)]
    public class ProjectInstaller : Installer
    {
        private ServiceInstaller _serviceInstaller;
        private ServiceProcessInstaller _processInstaller;
        public ProjectInstaller()
        {
            _processInstaller = new ServiceProcessInstaller();
            _serviceInstaller = new ServiceInstaller();
            // Service will run under system account
            _processInstaller.Account = ServiceAccount.LocalSystem;
            // Service will have Start Type of Manual
            _serviceInstaller.StartType = ServiceStartMode.Manual;
            //_serviceInstaller.ServiceName = WindowsServiceHost.serviceName;
            Installers.Add(_serviceInstaller);
            Installers.Add(_processInstaller);
        }
        public override void Install(IDictionary stateSaver)
        {
            SetServiceName();
            base.Install(stateSaver);
        }
        public override void Uninstall(IDictionary savedState)
        {
            SetServiceName();
            base.Uninstall(savedState);
        }
        private void SetServiceName()
        {
            var parameters = Context.Parameters;
            var parametersKeys = parameters.Keys;
            //foreach (KeyValuePair<string, string> kvp in parameters)
            foreach (string s in parametersKeys)
            {
                var k = s.Trim().ToLower();
                if (k == "servicename")
                {
                    //var serviceName = kvp.Value;
                    var serviceName = parameters[k];
                    _serviceInstaller.ServiceName = serviceName;
                    _serviceInstaller.DisplayName = serviceName;
                    break;
                }
            }
        }
    }
}
namespace Microshaoft
{
    using System.Diagnostics;
    public static class PerformanceCountersConfiguration
    {
        public static void AttachPerformanceCounters()
        {
            EasyPerformanceCountersHelper<CommonPerformanceCountersContainer>
                .AttachPerformanceCountersCategoryInstance
                (
                    PerformanceCountersConfiguration
                        .PerformanceCountersCategoryName
                    , PerformanceCountersConfiguration
                        .PerformanceCountersCategoryInstanceName
                );
        }
        public static string PerformanceCountersCategoryName
        {
            get
            {
                return "Microshaoft EasyPerformanceCounters Category";
            }
        }
        public static string PerformanceCountersCategoryInstanceName
        {
            get
            {
                return string.Format
                                (
                                    "{2}{0}{3}{1}{4}"
                                    , ": "
                                    , " @ "
                                    , Process.GetCurrentProcess().ProcessName
                                    , ""
                                    , "WebApiCountPerformanceActionFilter"
                                );
            }
        }
        public static MultiPerformanceCountersTypeFlags EnableCounters
        {
            get
            {
                return
                    MultiPerformanceCountersTypeFlags.ProcessCounter
                    | MultiPerformanceCountersTypeFlags.ProcessedAverageTimerCounter
                    | MultiPerformanceCountersTypeFlags.ProcessedCounter
                    | MultiPerformanceCountersTypeFlags.ProcessedRateOfCountsPerSecondCounter
                    | MultiPerformanceCountersTypeFlags.ProcessingCounter;
            }
        }
    }
}
namespace Microshaoft.Win32
{
    using System.Runtime.InteropServices;
    public class NativeMethods
    {
        /// <summary>
        /// 启动控制台
        /// </summary>
        /// <returns></returns>
        [DllImport("kernel32.dll")]
        public static extern bool AllocConsole();
        /// <summary>
        /// 释放控制台
        /// </summary>
        /// <returns></returns>
        [DllImport("kernel32.dll")]
        public static extern bool FreeConsole();
    }
}
namespace ClientTest
{
    using Microshaoft;
    using Microshaoft.Models;
    using System;
    using System.Collections.Generic;
    using System.Net.Http;
    using System.Net.Http.Headers;
    public class Program
    {
        public static void Main1(string[] args)
        {
            //@"http://api.asp.net.local/services/restful/api/Persons/";
            string url = args[0];
            HttpClient client = new HttpClient();
            client
                .DefaultRequestHeaders
                    .Accept
                        .Add
                            (
                                new MediaTypeWithQualityHeaderValue("application/json")
                            );
            Console.WriteLine("Get test:");
            var result = client.GetJsonObjects<Person>(url);
            foreach (var i in result)
            {
                Console.WriteLine(i);
            }
            Console.WriteLine("Post test:");
            HttpResponseMessage response
                = client.PostJsonObjects<Person>
                        (
                            url
                            , new Person[]
                            {
                                new Person()
                                {
                                    Name = "c1"
                                    , Height = 1
                                    , Weight = 2
                                }
                                ,
                                 new Person()
                                {
                                    Name = "c2"
                                    , Height = 1
                                    , Weight = 2
                                }
                            }
                        );
            Console.WriteLine(response.IsSuccessStatusCode);
            if (response.IsSuccessStatusCode)
            {
                result = response.Content.ReadAsAsync<IEnumerable<Person>>().Result;
                foreach (var i in result)
                {
                    Console.WriteLine(i);
                }
            }
            //Console.ReadLine();
        }
    }
}
namespace Microshaoft
{
    using System.Collections.Generic;
    using System.Net.Http;
    public static partial class HttpClientExtensionsMethodsManager
    {
        public static IEnumerable<T> GetJsonObjects<T>(this HttpClient httpClient, string url)
        {
            HttpResponseMessage response
                        = httpClient.GetAsync(url).Result;
            var result = response.Content.ReadAsAsync<IEnumerable<T>>().Result;
            return result;
        }
        public static HttpResponseMessage PostJsonObjects<T>
                                            (
                                                this HttpClient httpClient
                                                , string url
                                                , T[] jsonObjects
                                            )
        {
            HttpResponseMessage response = httpClient.PostAsJsonAsync(url, jsonObjects).Result;
            return response;
        }
    }
}
// Models.cs
namespace Microshaoft.Models
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Linq;
    using System.Net.Http.Headers;
    using System.Runtime.Serialization;
    using System.Web;
    public static class PersonsManager
    {
        public static List<Person> _persons = new Person[]
                                {
                                    new Person("张栢芝", 71, 178, 49)
                                    , new Person("章子怡", 23, 177, 33)
                                    , new Person("周迅", 12, 180, 80)
                                    , new Person("徐静蕾", 12, 150, 70)
                                    , new Person("赵薇", 23, 166, 60)
                                    , new Person("宋丹丹", 50, 183, 50)
                                    , new Person("翠花儿", 23, 177, 34)
                                    , new Person("赵丽蓉", 50, 184, 40)
                                    , new Person("郭晶晶", 50, 184, 41)
                                }.ToList();
        public static List<Person> Persons
        {
            get
            {
                return _persons;
            }
        }
    }
    [DataContract]
    public class Person : IComparable<Person>
    {
        [DataMember]
        public string Name
        {
            get;
            set;
        }
        [DataMember]
        public int Age
        {
            get;
            set;
        }
        [DataMember]
        public int Height
        {
            get;
            set;
        }
        [DataMember]
        public int Weight
        {
            get;
            set;
        }
        public Person(string name, int age, int height, int weight)
        {
            Name = name;
            Age = age;
            Height = height;
            Weight = weight;
        }
        public Person()
        {
        }
        public override string ToString()
        {
            return
                string.Format
                        (
                            "姓名:{0}, 年龄:{1:N}, 体重:{2:N}, 身高:{3:N}"
                            , Name
                            , Age
                            , Height
                            , Weight
                        );
        }
        public int CompareTo(Person other)
        {
            int r = 0;
            r = Age - other.Age;
            if (r == 0)
            {
                r = Height - other.Height;
                if (r == 0)
                {
                    r = Weight - other.Weight;
                }
            }
            return r;
        }
    }
    public class PerformanceCounterWrapper
    {
        private PerformanceCounter _performanceCounter;
        public PerformanceCounterWrapper()
        {
        }
        public PerformanceCounterWrapper(PerformanceCounter performanceCounter)
        {
            _performanceCounter = performanceCounter;
        }
        public string CategoryName
        {
            get
            {
                return _performanceCounter.CategoryName;
            }
            set
            {
            }
        }
        public string CounterName
        {
            get
            {
                return _performanceCounter.CounterName;
            }
            set
            {
            }
        }
        public string InstanceName
        {
            get
            {
                return _performanceCounter.InstanceName;
            }
            set
            {
            }
        }
        public float NextValue
        {
            get
            {
                return _performanceCounter.NextValue();
            }
            set
            {
            }
        }
        public long RawValue
        {
            get
            {
                return _performanceCounter.RawValue;
            }
            set
            {
            }
        }
        public string CounterType
        {
            get
            {
                return
                    Enum.GetName
                            (
                                typeof(PerformanceCounterType)
                                , _performanceCounter.CounterType
                            );
            }
            set
            {
            }
        }
    }
    public class CookieStateWrapper
    {
        private CookieState _cookieState = null;
        private CookieHeaderValue _cookieHeaderValue = null;
        public CookieStateWrapper()
        {
        }
        public CookieStateWrapper(CookieHeaderValue cookieHeaderValue, CookieState cookieState)
        {
            _cookieState = cookieState;
            _cookieHeaderValue = cookieHeaderValue;
        }
        public string Name
        {
            get
            {
                return _cookieState.Name;
            }
            set { }
        }
        public string Value
        {
            get
            {
                return _cookieState.Value;
            }
            set
            {
            }
        }
        public string Domain
        {
            get
            {
                return _cookieHeaderValue.Domain;
            }
            set
            {
            }
        }
        public string Path
        {
            get
            {
                return _cookieHeaderValue.Path;
            }
            set
            {
            }
        }
        public DateTimeOffset? Expires
        {
            get
            {
                return _cookieHeaderValue.Expires;
            }
            set
            {
            }
        }
    }
    public class HttpCookieWrapper
    {
        private HttpCookie _httpCookie;
        public HttpCookieWrapper()
        {
        }
        public HttpCookieWrapper(HttpCookie httpCookie)
        {
            _httpCookie = httpCookie;
        }
        public string Name
        {
            get
            {
                return _httpCookie.Name;
            }
            set
            {
            }
        }
        public string Value
        {
            get
            {
                return _httpCookie.Value;
            }
            set
            {
            }
        }
        public string Domain
        {
            get
            {
                return _httpCookie.Domain;
            }
            set
            {
            }
        }
        public string Path
        {
            get
            {
                return _httpCookie.Path;
            }
            set { }
        }
        public DateTime Expires
        {
            get
            {
                return _httpCookie.Expires;
            }
            set
            {
            }
        }
    }
}
// WCF.Contracts.cs
namespace Microshaoft.WCF.Contracts
{
    using Microshaoft.Models;
    using System.Collections.Generic;
    using System.ServiceModel;
    using System.ServiceModel.Web;
    [ServiceContract]
    public interface IPersonsServices
    {
        [OperationContract]
        [
            WebInvoke
                (
                    Method = "GET"
                    , BodyStyle = WebMessageBodyStyle.WrappedRequest
                    , ResponseFormat = WebMessageFormat.Json
                    , UriTemplate = "{name}"
                )
        ]
        IEnumerable<Person> GetData(string name);
    }
}
// WCF.Services.cs
namespace Microshaoft.WCF.Services
{
    using Microshaoft.Models;
    using Microshaoft.WCF.Contracts;
    using System.Collections.Generic;
    using System.Linq;
    using System.ServiceModel.Activation;
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class PersonsServices : IPersonsServices
    {
        public IEnumerable<Person> GetData(string name)
        {
            if (name == "*")
            {
                return PersonsManager.Persons;
            }
            else
            {
                return PersonsManager.Persons.Where(x => x.Name == name).ToList();
            }
        }
    }
}
// WebAPI.Controllers.cs
namespace Microshaoft.WebApi.Controllers
{
    using Microshaoft.Models;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Linq;
    using System.Net;
    using System.Net.Http;
    using System.Web;
    using System.Web.Http;
    //using System.Web.Cors;
    using System.Web.Http.Cors;
    // http://api.asp.net.local/services/restful/api/perfmon/Process/Private%20Bytes/Explorer
    public class PerfMonController : ApiController
    {
        [HttpGet]
        public PerformanceCounterWrapper Get
                (
                    [FromUri]
                    string category,
                    [FromUri]
                    string counter,
                    [FromUri]
                    string instance
                )
        {
            return
                new PerformanceCounterWrapper
                        (
                            new PerformanceCounter
                                    (
                                        category
                                        , counter
                                        , instance
                                        , true
                                    )
                        );
        }
    }
    // http://api.asp.net.local/services/restful/api/cookies/*
    public class CookiesController : ApiController
    {
        [HttpGet]
        public IEnumerable<CookieStateWrapper> Get()
        {
            List<CookieStateWrapper> list = new List<CookieStateWrapper>();
            //this.
            Request
                .Headers
                    .GetCookies()
                        .ToList()
                            .ForEach
                                (
                                    (x) =>
                                    {
                                        x.Cookies.ToList().ForEach
                                            (
                                                (xx) =>
                                                {
                                                    list.Add
                                                        (
                                                            new CookieStateWrapper(x, xx)
                                                        );
                                                }
                                            );
                                    }
                                );
            return list;
        }
    }
    // http://api.asp.net.local/services/restful/api/httpcookies/*
    public class HttpCookiesController : ApiController
    {
        [HttpGet]
        public IEnumerable<HttpCookieWrapper> Get()
        {
            List<HttpCookieWrapper> list = new List<HttpCookieWrapper>();
            var cookies = HttpContext.Current.Request.Cookies;
            var l = cookies.Count;
            for (int i = 0; i < l; i++)
            {
                list.Add
                    (
                        new HttpCookieWrapper(cookies[i])
                    );
            }
            return list;
        }
    }
    [EnableCors(origins: "*", headers: "*, Origin, X-Requested-With, Content-Type, Accept", methods: "*")]
    //[EnableCors(origins: "*", headers: "*", methods: "*")]
    public class PersonsController : ApiController
    {
        [HttpGet]
        public IEnumerable<Person> Jet(string name = "*")
        {
            if (name == "*")
            {
                return PersonsManager.Persons;
            }
            else
            {
                return PersonsManager.Persons.Where(x => x.Name == name).ToList();
            }
        }
        // POST api/values
        //public HttpResponseMessage Post([FromBody]string value)
        //{
        //    var response = Request.CreateResponse(HttpStatusCode.Created);
        //    return response;
        //}
        [EnableCors(origins: "*", headers: "*, Origin, X-Requested-With, Content-Type, Accept", methods: "*")]
        public HttpResponseMessage Post
                (
                    [FromBody]
                    List<Person> x,
                    [FromUri]
                    string name = ""
                )
        {
            x[0].Name = x[0].Name + name;
            PersonsManager.Persons.AddRange(x);
            //PersonsManager.Persons.Add(x);
            var response = Request.CreateResponse<List<Person>>(HttpStatusCode.Created, x);
            //var cookie = new CookieHeaderValue("customCookie", "cookieVal");
            //cookie.Expires = DateTimeOffset.Now.AddDays(1);
            //cookie.Domain = Request.RequestUri.Host;
            //cookie.Path = "/";
            //response.Headers.AddCookies(new CookieHeaderValue[] { cookie });
            //string uri = Url.Link("DefaultApi", new { Name = item.Name });
            //response.Headers.Location = new Uri(uri);
            return response;
        }
        ///        public HttpResponseMessage Post(Person item)
        ///        {
        ///            PersonsManager.Persons.Add(item);
        ///            var response = Request.CreateResponse<Person>(HttpStatusCode.Created, item);
        ///
        ///            //string uri = Url.Link("DefaultApi", new { Name = item.Name });
        ///            //response.Headers.Location = new Uri(uri);
        ///            return response;
        ///        }
        // PUT api/values/5
        public void Put(int id, [FromBody]string value)
        {
        }
        public void Put(int id, Person item)
        {
            PersonsManager.Persons[id] = item;
        }
        // DELETE api/values/5
        public void Delete(int id)
        {
            PersonsManager.Persons.RemoveAt(id);
        }
    }
}
// WebAPI.BundleConfig.cs
namespace Microshaoft.WebMvc
{
    using System.Web.Optimization;
    public class BundleConfig
    {
        // For more information on Bundling, visit http://go.microsoft.com/fwlink/?LinkId=254725
        public static void RegisterBundles(BundleCollection bundles)
        {
            bundles.Add
                    (
                        new ScriptBundle("~/bundles/jquery")
                                .Include("~/Scripts/jquery-{version}.js")
                    );
            bundles.Add
                    (
                        new ScriptBundle("~/bundles/jqueryui")
                                .Include("~/Scripts/jquery-ui-{version}.js")
                    );
            bundles.Add
                    (
                        new ScriptBundle("~/bundles/jqueryval")
                                .Include
                                    (
                                        "~/Scripts/jquery.unobtrusive*"
                                        , "~/Scripts/jquery.validate*"
                                    )
                    );
            // Use the development version of Modernizr to develop with and learn from. Then, when you're
            // ready for production, use the build tool at http://modernizr.com to pick only the tests you need.
            bundles.Add
                    (
                        new ScriptBundle("~/bundles/modernizr")
                                .Include("~/Scripts/modernizr-*")
                    );
            bundles.Add
                    (
                        new StyleBundle("~/Content/css")
                                .Include("~/Content/site.css")
                    );
            bundles.Add
                    (
                        new StyleBundle("~/Content/themes/base/css")
                                .Include
                                    (
                                        "~/Content/themes/base/jquery.ui.core.css",
                                        "~/Content/themes/base/jquery.ui.resizable.css",
                                        "~/Content/themes/base/jquery.ui.selectable.css",
                                        "~/Content/themes/base/jquery.ui.accordion.css",
                                        "~/Content/themes/base/jquery.ui.autocomplete.css",
                                        "~/Content/themes/base/jquery.ui.button.css",
                                        "~/Content/themes/base/jquery.ui.dialog.css",
                                        "~/Content/themes/base/jquery.ui.slider.css",
                                        "~/Content/themes/base/jquery.ui.tabs.css",
                                        "~/Content/themes/base/jquery.ui.datepicker.css",
                                        "~/Content/themes/base/jquery.ui.progressbar.css",
                                        "~/Content/themes/base/jquery.ui.theme.css"
                                    )
                    );
        }
    }
}
// WebAPI.FilterConfig.cs
namespace Microshaoft.WebMvc
{
    using System.Web.Mvc;
    public class FilterConfig
    {
        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new HandleErrorAttribute());
        }
    }
}
// WebAPI.RouteConfig.cs
namespace Microshaoft.WebMvc
{
    using System.Web.Mvc;
    using System.Web.Routing;
    public class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
            routes.MapRoute
                        (
                            name:
                                    "Default",
                            url:
                                    "{controller}/{action}/{id}",
                            defaults:
                                    new
                                    {
                                        controller = "Home",
                                        action = "Index",
                                        id = UrlParameter.Optional
                                    }
            );
        }
    }
}
// WebAPI.WebApiConfig.cs
namespace Microshaoft.WebApi
{
    using System.Web.Http;
    using System.Web.Http.Cors;
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            config.Routes.MapHttpRoute
                            (
                                name:
                                        "DefaultApi",
                                routeTemplate:
                                        "services/restful/api/{controller}/{name}",
                                defaults:
                                        new
                                        {
                                            name = RouteParameter.Optional
                                        }
                            );
            config.Routes.MapHttpRoute
                            (
                                name:
                                        "PerfmonApi",
                                routeTemplate:
                                        "services/restful/api/{controller}/{category}/{counter}/{instance}",
                                defaults:
                                        new
                                        {
                                            category = RouteParameter.Optional
                                            ,
                                            counter = RouteParameter.Optional
                                            ,
                                            instance = RouteParameter.Optional
                                        }
                            );
            // Uncomment the following line of code to enable query support for actions with an IQueryable or IQueryable<T> return type.
            // To avoid processing unexpected or malicious queries, use the validation settings on QueryableAttribute to validate incoming queries.
            // For more information, visit http://go.microsoft.com/fwlink/?LinkId=279712.
            //config.EnableQuerySupport();
            // To disable tracing in your application, please comment out or remove the following line of code
            // For more information, refer to: http://www.asp.net/web-api
            config.EnableSystemDiagnosticsTracing();
            var cors = new EnableCorsAttribute("*", "*, Origin, X-Requested-With, Content-Type, Accept", "*");
            config.EnableCors();
            //config.EnableCors(cors);
            //config.EnableCors();
        }
    }
}
// Global.asax.cs
// Global.asax
/*
    <%@ Application Language="C#" Inherits="Microshaoft.Web.Global" %>
*/
namespace Microshaoft.Web
{
    using Microshaoft;
    using Microshaoft.WCF.Services;
    using Microshaoft.WebApi;
    using System.ServiceModel.Activation;
    using System.Web;
    using System.Web.Http;
    using System.Web.Mvc;
    using System.Web.Routing;
    // Note: For instructions on enabling IIS6 or IIS7 classic mode, 
    // visit http://go.microsoft.com/?LinkId=9394801
    public class Global : HttpApplication
    {
        public void Application_Start()
        {
            //return;
            AreaRegistration.RegisterAllAreas();
            var config = GlobalConfiguration.Configuration;
            MvcApiConfigHelper.Config(config);
            RouteTable.Routes.Add
                            (
                                new ServiceRoute
                                        (
                                            "services/restful/wcf/persons"
                                            , new WebServiceHostFactory()
                                            , typeof(PersonsServices)
                                        )
                            );
            // PerformanceCounters
            PerformanceCountersConfiguration.AttachPerformanceCounters();
        }
    }
}
namespace Microshaoft.Web
{
    using Microshaoft.WebApi;
    using Microshaoft.WebMvc;
    using System.Web.Http;
    using System.Web.Mvc;
    using System.Web.Optimization;
    using System.Web.Routing;
    public static class MvcApiConfigHelper
    {
        public static void Config(HttpConfiguration httpConfiguration)
        {
            //var globalConfiguration = GlobalConfiguration.Configuration;
            WebApiConfig.Register(httpConfiguration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            // comment for Web API
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            // CountPerformanceActionFilter
            httpConfiguration.Filters.Add(new CountPerformanceActionFilter());
            // JsonP
            httpConfiguration.Formatters.Insert(0, new JsonpMediaTypeFormatter());
        }
    }
}
// WebAPI.JsonpMediaTypeFormatter.cs
namespace Microshaoft.WebApi
{
    using System;
    using System.IO;
    using System.Net;
    using System.Net.Http;
    using System.Net.Http.Formatting;
    using System.Net.Http.Headers;
    using System.Threading.Tasks;
    /// <summary>
    /// Adds JSONP support to the standard <see cref="JsonMediaTypeFormatter"/>.
    /// </summary>
    public class JsonpMediaTypeFormatter : JsonMediaTypeFormatter
    {
        private readonly HttpRequestMessage request;
        private string callbackQueryParameter;
        public JsonpMediaTypeFormatter()
        {
            SupportedMediaTypes.Add(DefaultMediaType);
            SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/javascript"));
            this.AddQueryStringMapping("format", "jsonp", DefaultMediaType);
        }
        public JsonpMediaTypeFormatter(HttpRequestMessage request)
            : this()
        {
            this.request = request;
        }
        public string CallbackQueryParameter
        {
            get { return callbackQueryParameter ?? "callback"; }
            set { callbackQueryParameter = value; }
        }
        public override MediaTypeFormatter GetPerRequestFormatterInstance(Type type, HttpRequestMessage request, MediaTypeHeaderValue mediaType)
        {
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }
            var r = new JsonpMediaTypeFormatter(request)
                            {
                                SerializerSettings = SerializerSettings
                            };
            return r;
        }
        public override Task WriteToStreamAsync(Type type, object value, Stream stream, HttpContent content, TransportContext transportContext)
        {
            string callback;
            if (IsJsonpRequest(request, out callback))
            {
                var writer = new StreamWriter(stream);
                writer.Write(callback + "(");
                writer.Flush();
                return
                    base.WriteToStreamAsync
                                (
                                    type
                                    , value
                                    , stream
                                    , content
                                    , transportContext
                                ).ContinueWith
                                    ( 
                                        (x) =>
                                        {
                                            //TODO: Inspecting the task status and acting on that is better
                                            writer.Write(")");
                                            writer.Flush();
                                        }
                                    );
            }
            else
            {
                return base.WriteToStreamAsync(type, value, stream, content, transportContext);
            }
        }
        private bool IsJsonpRequest(HttpRequestMessage request, out string callback)
        {
            callback = null;
            if (request == null || request.Method != HttpMethod.Get)
            {
                return false;
            }
            var query = request.RequestUri.ParseQueryString();
            callback = query[CallbackQueryParameter];
            return !string.IsNullOrEmpty(callback);
        }
    }
}
namespace Microshaoft.OLD
{
    using System;
    using System.IO;
    using System.Net;
    using System.Net.Http;
    using System.Net.Http.Formatting;
    using System.Net.Http.Headers;
    using System.Threading.Tasks;
    using System.Web;
    public class JsonpMediaTypeFormatter : JsonMediaTypeFormatter
    {
        private string _callbackQueryParamter;
        public JsonpMediaTypeFormatter()
        {
            SupportedMediaTypes.Add(DefaultMediaType);
            SupportedMediaTypes.Add(new MediaTypeWithQualityHeaderValue("text/javascript"));
            MediaTypeMappings.Add(new UriPathExtensionMapping("jsonp", DefaultMediaType));
        }
        public string CallbackQueryParameter
        {
            get
            {
                return _callbackQueryParamter ?? "callback";
            }
            set
            {
                _callbackQueryParamter = value;
            }
        }
        public override Task WriteToStreamAsync
                                    (
                                        Type type
                                        , object value
                                        , Stream writeStream
                                        , HttpContent content
                                        , TransportContext transportContext
                                    )
        {
            string callback;
            if (IsJsonpRequest(out callback))
            {
                return Task.Factory.StartNew
                                        (
                                            () =>
                                            {
                                                var writer = new StreamWriter(writeStream);
                                                writer.Write(callback + "(");
                                                writer.Flush();
                                                base.WriteToStreamAsync
                                                        (
                                                            type
                                                            , value
                                                            , writeStream
                                                            , content
                                                            , transportContext
                                                        ).Wait();
                                                writer.Write(")");
                                                writer.Flush();
                                            }
                                        );
            }
            return base.WriteToStreamAsync(type, value, writeStream, content, transportContext);
        }
        private bool IsJsonpRequest(out string callback)
        {
            callback = null;
            //switch (HttpContext.Current.Request.HttpMethod)
            switch (HttpContext.Current.Request.HttpMethod)
            {
                case "POST":
                    callback = HttpContext
                                    .Current
                                        .Request
                                            .Form[CallbackQueryParameter];
                    break;
                default:
                    callback = HttpContext
                                    .Current
                                        .Request
                                            .QueryString[CallbackQueryParameter];
                    break;
            }
            return !string.IsNullOrEmpty(callback);
        }
    }
}
// WebApi.MVC.CountPerformanceActionFilter.cs
namespace Microshaoft.Web
{
    using System;
    using System.Diagnostics;
    using System.Linq;
    using System.Web.Http.Controllers;
    using System.Web.Http.Filters;
    //using Microshaoft.WebApplications;
    public class CountPerformanceActionFilter : ActionFilterAttribute
    {
        private const string Key = "__action_duration__";
        private string _performanceCountersCategoryName
                                        = PerformanceCountersConfiguration
                                            .PerformanceCountersCategoryName;
        private string _performanceCountersCategoryInstanceName
                                        = PerformanceCountersConfiguration
                                            .PerformanceCountersCategoryInstanceName;
        private MultiPerformanceCountersTypeFlags _enableCounters
                                        = PerformanceCountersConfiguration
                                            .EnableCounters;
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            ///            if (SkipLogging(actionContext))
            ///            {
            ///                return;
            ///            }
            Stopwatch stopwatch =
                                EasyPerformanceCountersHelper<CommonPerformanceCountersContainer>
                                        .CountPerformanceBegin
                                            (
                                                _enableCounters
                                                , _performanceCountersCategoryName
                                                , _performanceCountersCategoryInstanceName
                                            );
            if (stopwatch != null)
            {
                actionContext.Request.Properties[Key] = stopwatch;
            }
        }
        public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
        {
            if (!actionExecutedContext.Request.Properties.ContainsKey(Key))
            {
                return;
            }
            var stopwatch = actionExecutedContext
                                .Request
                                    .Properties[Key] as Stopwatch;
            EasyPerformanceCountersHelper<CommonPerformanceCountersContainer>
                .CountPerformanceEnd
                                (
                                    _enableCounters
                                    , _performanceCountersCategoryName
                                    , _performanceCountersCategoryInstanceName
                                    , stopwatch
                                );
            if (stopwatch != null)
            {
                var actionName = actionExecutedContext
                                        .ActionContext
                                            .ActionDescriptor
                                                .ActionName;
                var controllerName = actionExecutedContext
                                        .ActionContext
                                            .ActionDescriptor
                                                .ControllerDescriptor
                                                    .ControllerName;
                Debug.Print
                        (
                            string.Format
                                    (
                                        "[Execution of{0}- {1} took {2}.]"
                                        , controllerName
                                        , actionName
                                        , stopwatch.Elapsed
                                    )
                        );
                stopwatch = null;
            }
        }
        private static bool SkipLogging(HttpActionContext actionContext)
        {
            return
                    actionContext
                        .ActionDescriptor
                            .GetCustomAttributes<CountPerformanceAttribute>()
                                .Any()
                    ||
                    actionContext
                        .ControllerContext
                            .ControllerDescriptor
                                .GetCustomAttributes<CountPerformanceAttribute>()
                                    .Any();
        }
    }
    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true)]
    public class CountPerformanceAttribute : Attribute
    {
    }
}
namespace TestConsoleApplication
{
    using System;
    using System.Diagnostics;
    using System.Threading;
    using System.Threading.Tasks;
    using Microshaoft;
    class Program
    {
        static void Main1(string[] args)
        {
            Console.WriteLine("Begin ...");
            Random r = new Random();
            int sleep = 2;
            int iterations = 10;
            int maxDegreeOfParallelism = 8; // Environment.ProcessorCount;
            var performanceCountersCategoryName = "Microshaoft EasyPerformanceCounters Category";
            var performanceCountersCategoryInstanceName
                    = string.Format
                            (
                                "{2}{0}{3}{1}{4}"
                                , ": "
                                , " @ "
                                , ""
                                , ""
                                , Process.GetCurrentProcess().ProcessName
                            );
            //EasyPerformanceCountersHelper 调用示例
            EasyPerformanceCountersHelper<CommonPerformanceCountersContainer>
                .AttachPerformanceCountersCategoryInstance
                                (
                                    performanceCountersCategoryName
                                    , performanceCountersCategoryInstanceName + "-1"
                                );
            EasyPerformanceCountersHelper<CommonPerformanceCountersContainer>
                .AttachPerformanceCountersCategoryInstance
                    (
                        performanceCountersCategoryName
                        , performanceCountersCategoryInstanceName + "-2"
                    );
            var enableCounters = MultiPerformanceCountersTypeFlags.ProcessCounter
                                    | MultiPerformanceCountersTypeFlags.ProcessedAverageTimerCounter
                                    | MultiPerformanceCountersTypeFlags.ProcessedCounter
                                    | MultiPerformanceCountersTypeFlags.ProcessedRateOfCountsPerSecondCounter
                                    | MultiPerformanceCountersTypeFlags.ProcessingCounter;
            Parallel.For
                        (
                            0
                            , iterations
                            , new ParallelOptions()
                            {
                                MaxDegreeOfParallelism = maxDegreeOfParallelism
                            }
                            , (x) =>
                            {
                                EasyPerformanceCountersHelper<CommonPerformanceCountersContainer>
                                    .CountPerformance
                                        (
                                            enableCounters
                                            , performanceCountersCategoryName
                                            , performanceCountersCategoryInstanceName + "-1"
                                            , null
                                            , () =>
                                            {
                                                sleep = r.Next(0, 5) * 1000;
                                                //Thread.Sleep(sleep);
                                                throw new Exception("sadsad");
                                            }
                                            , null
                                            , (xx) =>
                                            {
                                                //Console.WriteLine("Exception {0}", xx.ToString());
                                                return false;
                                            }
                                            , null
                                        );
                            }
                        );
                        Parallel.For
                            (
                                0
                                , iterations
                                , new ParallelOptions()
                                {
                                    MaxDegreeOfParallelism = maxDegreeOfParallelism
                                }
                                , (x) =>
                                {
                                    Stopwatch stopwatch = null;
                                    try
                                    {
                                        stopwatch =
                                            EasyPerformanceCountersHelper<CommonPerformanceCountersContainer>
                                                .CountPerformanceBegin
                                                    (
                                                        enableCounters
                                                        , performanceCountersCategoryName
                                                        , performanceCountersCategoryInstanceName + "-2"
                                                    );
                                        sleep = r.Next(0, 5) * 1000;
                                        //Thread.Sleep(sleep);
                                        throw new Exception("Test");
                                    }
                                    catch
                                    {
                                    }
                                    finally
                                    {
                                        EasyPerformanceCountersHelper<CommonPerformanceCountersContainer>
                                            .CountPerformanceEnd
                                                (
                                                    enableCounters
                                                    , performanceCountersCategoryName
                                                    , performanceCountersCategoryInstanceName + "-2"
                                                    , stopwatch
                                                );
                                    }
                                }
                            );
            Console.WriteLine("End ...");
            Console.ReadLine();
        }
    }
}
namespace Microshaoft
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    //using System.Collections.Concurrent;
    public static class EasyPerformanceCountersHelper<TPerformanceCountersContainer>
                                where TPerformanceCountersContainer : class, IPerformanceCountersContainer, new ()
    {
        private static Dictionary<string, TPerformanceCountersContainer> _dictionary
                        = new Dictionary<string, TPerformanceCountersContainer>();
        public static void AttachPerformanceCountersCategoryInstance
                            (
                                string performanceCountersCategoryName
                                , string performanceCountersCategoryInstanceName
                            )
        {
            string key = string.Format
                                    (
                                        "{1}{0}{2}"
                                        , "-"
                                        , performanceCountersCategoryName
                                        , performanceCountersCategoryInstanceName
                                    );
            TPerformanceCountersContainer container = null;
            if (!_dictionary.TryGetValue(key, out container))
            {
                container = new TPerformanceCountersContainer();
                _dictionary.Add
                            (
                                key
                                , container
                            );
                container
                    .AttachPerformanceCountersToProperties
                        (
                            performanceCountersCategoryInstanceName
                            , performanceCountersCategoryName
                        );
            }
        }
        private static object _lockerObject = new object();
        public static Stopwatch CountPerformanceBegin
                                    (
                                        MultiPerformanceCountersTypeFlags enabledPerformanceCounters
                                        , string performanceCountersCategoryName
                                        , string performanceCountersCategoryInstanceName
                                    )
        {
            Stopwatch r = null;
            if (enabledPerformanceCounters != MultiPerformanceCountersTypeFlags.None)
            {
                string key = string.Format
                                        (
                                            "{1}{0}{2}"
                                            , "-"
                                            , performanceCountersCategoryName
                                            , performanceCountersCategoryInstanceName
                                        );
                TPerformanceCountersContainer container = null;
                if (!_dictionary.TryGetValue(key, out container))
                {
                    lock (_lockerObject)
                    {
                        container = new TPerformanceCountersContainer();
                        _dictionary.Add
                                    (
                                        key
                                        , container
                                    );
                        container.AttachPerformanceCountersToProperties
                                            (
                                                performanceCountersCategoryInstanceName
                                                , performanceCountersCategoryName
                                            );
                    }
                }
                var enableProcessCounter =
                                            (
                                                (
                                                    enabledPerformanceCounters
                                                    & MultiPerformanceCountersTypeFlags.ProcessCounter
                                                )
                                                != MultiPerformanceCountersTypeFlags.None
                                            );
                if (enableProcessCounter)
                {
                    container.PrcocessPerformanceCounter.Increment();
                }
                var enableProcessingCounter =
                                            (
                                                (
                                                    enabledPerformanceCounters
                                                    & MultiPerformanceCountersTypeFlags.ProcessingCounter
                                                )
                                                != MultiPerformanceCountersTypeFlags.None
                                            );
                if (enableProcessingCounter)
                {
                    container.ProcessingPerformanceCounter.Increment();
                }
                var enableProcessedAverageTimerCounter =
                                            (
                                                (
                                                    enabledPerformanceCounters
                                                    & MultiPerformanceCountersTypeFlags.ProcessedAverageTimerCounter
                                                )
                                                != MultiPerformanceCountersTypeFlags.None
                                            );
                if (enableProcessedAverageTimerCounter)
                {
                    r = Stopwatch.StartNew();
                }
            }
            return r;
        }
        public static void CountPerformanceEnd
                                    (
                                        MultiPerformanceCountersTypeFlags enabledPerformanceCounters
                                        , string performanceCountersCategoryName
                                        , string performanceCountersCategoryInstanceName
                                        , Stopwatch stopwatch
                                    )
        {
            string key = string.Format
                        (
                            "{1}{0}{2}"
                            , "-"
                            , performanceCountersCategoryName
                            , performanceCountersCategoryInstanceName
                        );
            TPerformanceCountersContainer container = null;
            if (!_dictionary.TryGetValue(key, out container))
            {
                return;
            }
            var enableProcessedAverageTimerCounter =
                                        (
                                            (
                                                enabledPerformanceCounters
                                                & MultiPerformanceCountersTypeFlags.ProcessedAverageTimerCounter
                                            )
                                            != MultiPerformanceCountersTypeFlags.None
                                        );
            if (enableProcessedAverageTimerCounter)
            {
                if (stopwatch != null)
                {
                    PerformanceCounter performanceCounter = container.ProcessedAverageTimerPerformanceCounter;
                    PerformanceCounter basePerformanceCounter = container.ProcessedAverageBasePerformanceCounter;
                    stopwatch.Stop();
                    performanceCounter.IncrementBy(stopwatch.ElapsedTicks);
                    basePerformanceCounter.Increment();
                    //stopwatch = null;
                }
            }
            var enableProcessingCounter =
                                        (
                                            (
                                                enabledPerformanceCounters
                                                & MultiPerformanceCountersTypeFlags.ProcessingCounter
                                            )
                                            != MultiPerformanceCountersTypeFlags.None
                                        );
            if (enableProcessingCounter)
            {
                container.ProcessingPerformanceCounter.Decrement();
            }
            var enableProcessedPerformanceCounter =
                                    (
                                        (
                                            enabledPerformanceCounters
                                            & MultiPerformanceCountersTypeFlags.ProcessedCounter
                                        )
                                        != MultiPerformanceCountersTypeFlags.None
                                    );
            if (enableProcessedPerformanceCounter)
            {
                container.ProcessedPerformanceCounter.Increment();
            }
            var enableProcessedRateOfCountsPerSecondPerformanceCounter =
                        (
                            (
                                enabledPerformanceCounters
                                & MultiPerformanceCountersTypeFlags.ProcessedRateOfCountsPerSecondCounter
                            )
                            != MultiPerformanceCountersTypeFlags.None
                        );
            if (enableProcessedRateOfCountsPerSecondPerformanceCounter)
            {
                container.ProcessedRateOfCountsPerSecondPerformanceCounter.Increment();
            }
        }
        public static void CountPerformance
                                    (
                                        MultiPerformanceCountersTypeFlags enabledPerformanceCounters
                                        , string performanceCountersCategoryName
                                        , string performanceCountersCategoryInstanceName
                                        , Action onBeforeCountPerformanceInnerProcessAction
                                        , Action onCountPerformanceInnerProcessAction
                                        , Action onAfterCountPerformanceInnerProcessAction
                                        , Func<Exception, bool> onCaughtExceptionProcessFunc
                                        , Action<bool, Exception> onFinallyProcessAction
                                    )
        {
            if (enabledPerformanceCounters != MultiPerformanceCountersTypeFlags.None)
            {
                if (onCountPerformanceInnerProcessAction != null)
                {
                    string key = string.Format
                                            (
                                                "{1}{0}{2}"
                                                , "-"
                                                , performanceCountersCategoryName
                                                , performanceCountersCategoryInstanceName
                                            );
                    TPerformanceCountersContainer container = null;
                    if (!_dictionary.TryGetValue(key, out container))
                    {
                        lock (_lockerObject)
                        {
                            container = new TPerformanceCountersContainer();
                            _dictionary.Add
                                        (
                                            key
                                            , container
                                        );
                            container.AttachPerformanceCountersToProperties
                                                (
                                                    performanceCountersCategoryInstanceName
                                                    , performanceCountersCategoryName
                                                );
                        }
                    }
                    var enableProcessCounter =
                                                (
                                                    (
                                                        enabledPerformanceCounters
                                                        & MultiPerformanceCountersTypeFlags.ProcessCounter
                                                    )
                                                    != MultiPerformanceCountersTypeFlags.None
                                                );
                    if (enableProcessCounter)
                    {
                        container.PrcocessPerformanceCounter.Increment();
                    }
                    var enableProcessingCounter =
                                                (
                                                    (
                                                        enabledPerformanceCounters
                                                        & MultiPerformanceCountersTypeFlags.ProcessingCounter
                                                    )
                                                    != MultiPerformanceCountersTypeFlags.None
                                                );
                    if (enableProcessingCounter)
                    {
                        container.ProcessingPerformanceCounter.Increment();
                    }
                    var enableProcessedAverageTimerCounter =
                                                (
                                                    (
                                                        enabledPerformanceCounters
                                                        & MultiPerformanceCountersTypeFlags.ProcessedAverageTimerCounter
                                                    )
                                                    != MultiPerformanceCountersTypeFlags.None
                                                );
                    var reThrowException = false;
                    container
                        .ProcessedAverageTimerPerformanceCounter
                            .ChangeAverageTimerCounterValueWithTryCatchExceptionFinally
                                        (
                                            enableProcessedAverageTimerCounter
                                            , container.ProcessedAverageBasePerformanceCounter
                                            , () =>
                                            {
                                                if (onCountPerformanceInnerProcessAction != null)
                                                {
                                                    if (onBeforeCountPerformanceInnerProcessAction != null)
                                                    {
                                                        onBeforeCountPerformanceInnerProcessAction();
                                                    }
                                                    onCountPerformanceInnerProcessAction();
                                                    if (onAfterCountPerformanceInnerProcessAction != null)
                                                    {
                                                        onAfterCountPerformanceInnerProcessAction();
                                                    }
                                                }
                                            }
                                            , (x, y) =>        //catch
                                            {
                                                container
                                                    .CaughtExceptionsPerformanceCounter
                                                        .Increment();
                                                var r = reThrowException;
                                                if (onCaughtExceptionProcessFunc != null)
                                                {
                                                    r = onCaughtExceptionProcessFunc(y);
                                                }
                                                return r;
                                            }
                                            , (x, y, z, w) =>        //Finally
                                            {
                                                if (enableProcessingCounter)
                                                {
                                                    container.ProcessingPerformanceCounter.Decrement();
                                                }
                                                var enableProcessedPerformanceCounter =
                                                                        (
                                                                            (
                                                                                enabledPerformanceCounters
                                                                                & MultiPerformanceCountersTypeFlags.ProcessedCounter
                                                                            )
                                                                            != MultiPerformanceCountersTypeFlags.None
                                                                        );
                                                if (enableProcessedPerformanceCounter)
                                                {
                                                    container.ProcessedPerformanceCounter.Increment();
                                                }
                                                var enableProcessedRateOfCountsPerSecondPerformanceCounter =
                                                                        (
                                                                            (
                                                                                enabledPerformanceCounters
                                                                                & MultiPerformanceCountersTypeFlags.ProcessedRateOfCountsPerSecondCounter
                                                                            )
                                                                            != MultiPerformanceCountersTypeFlags.None
                                                                        );
                                                if (enableProcessedRateOfCountsPerSecondPerformanceCounter)
                                                {
                                                    container
                                                        .ProcessedRateOfCountsPerSecondPerformanceCounter
                                                            .Increment();
                                                }
                                            }
                                        );
                }
            }
            else
            {
                if (onCountPerformanceInnerProcessAction != null)
                {
                    onCountPerformanceInnerProcessAction();
                }
            }
        }
    }
}
namespace Microshaoft
{
    using System.Diagnostics;
    public interface IPerformanceCountersContainer
    {
        PerformanceCounter CaughtExceptionsPerformanceCounter
        {
            get;
        }
        PerformanceCounter PrcocessPerformanceCounter
        {
            get;
        }
        PerformanceCounter ProcessingPerformanceCounter
        {
            get;
        }
        PerformanceCounter ProcessedPerformanceCounter
        {
            get;
        }
        PerformanceCounter ProcessedRateOfCountsPerSecondPerformanceCounter
        {
            get;
        }
        PerformanceCounter ProcessedAverageTimerPerformanceCounter
        {
            get;
        }
        PerformanceCounter ProcessedAverageBasePerformanceCounter
        {
            get;
        }
        void AttachPerformanceCountersToProperties
                            (
                                string instanceName
                                , string categoryName
                            );
    }
}
namespace Microshaoft
{
    using System;
    using System.Diagnostics;
    public class CommonPerformanceCountersContainer
                    : IPerformanceCountersContainer
    {
        #region PerformanceCounters
        private PerformanceCounter _caughtExceptionsPerformanceCounter;
        [
            PerformanceCounterDefinitionAttribute
                (
                    CounterType = PerformanceCounterType.NumberOfItems64
                    , CounterName = "99.捕获异常次数(次)"
                )
        ]
        public PerformanceCounter CaughtExceptionsPerformanceCounter
        {
            private set
            {
                ReaderWriterLockSlimHelper
                    .TryEnterWriterLockSlimWrite<PerformanceCounter>
                        (
                            ref _caughtExceptionsPerformanceCounter
                            , value
                            , 2
                        );
            }
            get
            {
                return _caughtExceptionsPerformanceCounter;
            }
        }
        private PerformanceCounter _processPerformanceCounter;
        [
            PerformanceCounterDefinitionAttribute
                (
                    CounterType = PerformanceCounterType.NumberOfItems64
                    , CounterName = "01.接收处理笔数(笔)"
                )
        ]
        public PerformanceCounter PrcocessPerformanceCounter
        {
            private set
            {
                ReaderWriterLockSlimHelper
                    .TryEnterWriterLockSlimWrite<PerformanceCounter>
                        (
                            ref _processPerformanceCounter
                            , value
                            , 2
                        );
            }
            get
            {
                return _processPerformanceCounter;
            }
        }
        private PerformanceCounter _processingPerformanceCounter;
        [
            PerformanceCounterDefinitionAttribute
                (
                    CounterType = PerformanceCounterType.NumberOfItems64
                    , CounterName = "02.正在处理笔数(笔)"
                )
        ]
        public PerformanceCounter ProcessingPerformanceCounter
        {
            private set
            {
                ReaderWriterLockSlimHelper
                    .TryEnterWriterLockSlimWrite<PerformanceCounter>
                        (
                            ref _processingPerformanceCounter
                            , value
                            , 2
                        );
            }
            get
            {
                return _processingPerformanceCounter;
            }
        }
        private PerformanceCounter _processedPerformanceCounter;
        [
            PerformanceCounterDefinitionAttribute
                (
                    CounterType = PerformanceCounterType.NumberOfItems64
                    , CounterName = "03.完成处理笔数(笔)"
                )
        ]
        public PerformanceCounter ProcessedPerformanceCounter
        {
            private set
            {
                ReaderWriterLockSlimHelper
                    .TryEnterWriterLockSlimWrite<PerformanceCounter>
                        (
                            ref _processedPerformanceCounter
                            , value
                            , 2
                        );
            }
            get
            {
                return _processedPerformanceCounter;
            }
        }
        private PerformanceCounter _processedRateOfCountsPerSecondPerformanceCounter;
        [
            PerformanceCounterDefinitionAttribute
                (
                    CounterType = PerformanceCounterType.RateOfCountsPerSecond64
                    , CounterName = "04.每秒完成处理笔数(笔/秒)"
                )
        ]
        public PerformanceCounter ProcessedRateOfCountsPerSecondPerformanceCounter
        {
            private set
            {
                ReaderWriterLockSlimHelper
                    .TryEnterWriterLockSlimWrite<PerformanceCounter>
                        (
                            ref _processedRateOfCountsPerSecondPerformanceCounter
                            , value
                            , 2
                        );
            }
            get
            {
                return _processedRateOfCountsPerSecondPerformanceCounter;
            }
        }
        private PerformanceCounter _ProcessedAverageTimerPerformanceCounter;
        [
            PerformanceCounterDefinitionAttribute
                (
                    CounterType = PerformanceCounterType.AverageTimer32
                    , CounterName = "05.平均每笔处理耗时秒数(秒/笔)"
                )
        ]
        public PerformanceCounter ProcessedAverageTimerPerformanceCounter
        {
            private set
            {
                ReaderWriterLockSlimHelper
                    .TryEnterWriterLockSlimWrite<PerformanceCounter>
                        (
                            ref _ProcessedAverageTimerPerformanceCounter
                            , value
                            , 2
                        );
            }
            get
            {
                return _ProcessedAverageTimerPerformanceCounter;
            }
        }
        private PerformanceCounter _processedAverageBasePerformanceCounter;
        [
            PerformanceCounterDefinitionAttribute
                (
                    CounterType = PerformanceCounterType.AverageBase
                )
        ]
        public PerformanceCounter ProcessedAverageBasePerformanceCounter
        {
            private set
            {
                ReaderWriterLockSlimHelper
                    .TryEnterWriterLockSlimWrite<PerformanceCounter>
                        (
                            ref _processedAverageBasePerformanceCounter
                            , value
                            , 2
                        );
            }
            get
            {
                return _processedAverageBasePerformanceCounter;
            }
        }
        #endregion
        // indexer declaration
        public PerformanceCounter this[string name]
        {
            get
            {
                throw new NotImplementedException();
                //return null;
            }
        }
        //private bool _isAttachedPerformanceCounters = false;
        public void AttachPerformanceCountersToProperties
                            (
                                string instanceName
                                , string categoryName
                            )
        {
            var type = this.GetType();
            PerformanceCountersHelper
                .AttachPerformanceCountersToProperties<CommonPerformanceCountersContainer>
                    (
                        instanceName
                        , categoryName
                        , this
                    );
        }
    }
}
//=========================================================================================
//=========================================================================================
namespace Microshaoft
{
    using System;
    using System.Diagnostics;
    public static class PerformanceCounterExtensionMethodsManager
    {
        public static void ChangeAverageTimerCounterValueWithTryCatchExceptionFinally
                                (
                                    this PerformanceCounter performanceCounter
                                    , bool enabled
                                    , PerformanceCounter basePerformanceCounter
                                    , Action onCountPerformanceInnerProcessAction //= null
                                    , Func<PerformanceCounter, Exception, bool> onCaughtExceptionProcessFunc //= null
                                    , Action<PerformanceCounter, PerformanceCounter, bool, Exception> onFinallyProcessAction //= null
                                )
        {
            if (enabled)
            {
                var stopwatch = Stopwatch.StartNew();
                if (onCountPerformanceInnerProcessAction != null)
                {
                    bool reThrowException = false;
                    TryCatchFinallyProcessHelper
                        .TryProcessCatchFinally
                            (
                                true
                                , () =>
                                {
                                    onCountPerformanceInnerProcessAction();
                                }
                                , reThrowException
                                , (x) =>
                                {
                                    var r = reThrowException;
                                    if (onCaughtExceptionProcessFunc != null)
                                    {
                                        r = onCaughtExceptionProcessFunc(performanceCounter, x);
                                    }
                                    return r;
                                }
                                , (x, y) =>
                                {
                                    stopwatch.Stop();
                                    performanceCounter.IncrementBy(stopwatch.ElapsedTicks);
                                    stopwatch = null;
                                    basePerformanceCounter.Increment();
                                    if (onFinallyProcessAction != null)
                                    {
                                        onFinallyProcessAction
                                            (
                                                performanceCounter
                                                , basePerformanceCounter
                                                , x
                                                , y
                                            );
                                    }
                                }
                            );
                }
            }
        }
    }
}
namespace Microshaoft
{
    using System;
    using System.Diagnostics;
    [FlagsAttribute]
    public enum MultiPerformanceCountersTypeFlags : ushort
    {
        None = 0,
        ProcessCounter = 1,
        ProcessingCounter = 2,
        ProcessedCounter = 4,
        ProcessedAverageTimerCounter = 8,
        ProcessedRateOfCountsPerSecondCounter = 16
    };
    [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
    public class PerformanceCounterDefinitionAttribute : Attribute
    {
        public PerformanceCounterType CounterType;
        public string CounterName;
    }
}
namespace Microshaoft
{
    using System.Diagnostics;
    using System.Linq;
    public static class PerformanceCountersHelper
    {
        public static void AttachPerformanceCountersToProperties<T>
                                    (
                                        string performanceCounterInstanceName
                                        , string category
                                        , T target //= default(T)
                                    )
        {
            var type = typeof(T);
            var propertiesList = type.GetProperties().ToList();
            propertiesList = propertiesList.Where
                                                (
                                                    (pi) =>
                                                    {
                                                        var parameters = pi.GetIndexParameters();
                                                        return
                                                            (
                                                                pi.PropertyType == typeof(PerformanceCounter)
                                                                && (parameters == null ? 0 : parameters.Length) <= 0
                                                            );
                                                    }
                                                ).ToList();
            if (PerformanceCounterCategory.Exists(category))
            {
                propertiesList.ForEach
                                    (
                                        (pi) =>
                                        {
                                            if (PerformanceCounterCategory.CounterExists(pi.Name, category))
                                            {
                                                if (PerformanceCounterCategory.InstanceExists(performanceCounterInstanceName, category))
                                                {
                                                    //var pc = new PerformanceCounter(category, pi.Name, instanceName, false);
                                                    //pc.InstanceName = instanceName;
                                                    //pc.RemoveInstance();
                                                }
                                            }
                                        }
                                    );
                //PerformanceCounterCategory.Delete(category);
            }
            if (!PerformanceCounterCategory.Exists(category))
            {
                var ccdc = new CounterCreationDataCollection();
                propertiesList.ForEach
                                (
                                    (pi) =>
                                    {
                                        var propertyName = pi.Name;
                                        var performanceCounterType = PerformanceCounterType.NumberOfItems64;
                                        var performanceCounterName = propertyName;
                                        var attribute = pi.GetCustomAttributes(false).FirstOrDefault
                                                                                    (
                                                                                        (x) =>
                                                                                        {
                                                                                            return x as PerformanceCounterDefinitionAttribute != null;
                                                                                        }
                                                                                    ) as PerformanceCounterDefinitionAttribute;
                                        if (attribute != null)
                                        {
                                            var counterName = attribute.CounterName;
                                            if (!string.IsNullOrEmpty(counterName))
                                            {
                                                performanceCounterName = counterName;
                                            }
                                            var counterType = attribute.CounterType;
                                            //if (counterType != null)
                                            {
                                                performanceCounterType = counterType;
                                            }
                                        }
                                        var ccd = PerformanceCountersHelper
                                                    .GetCounterCreationData
                                                        (
                                                            performanceCounterName
                                                            , performanceCounterType
                                                        );
                                        ccdc.Add(ccd);
                                    }
                                );
                PerformanceCounterCategory.Create
                                (
                                    category,
                                    string.Format("{0} Category Help.", category),
                                    PerformanceCounterCategoryType.MultiInstance,
                                    ccdc
                                );
            }
            propertiesList.ForEach
                            (
                                (pi) =>
                                {
                                    var propertyName = pi.Name;
                                    var performanceCounterType = PerformanceCounterType.NumberOfItems64;
                                    var performanceCounterName = propertyName;
                                    var attribute =
                                                    pi
                                                        .GetCustomAttributes(false)
                                                            .FirstOrDefault
                                                                (
                                                                    (x) =>
                                                                    {
                                                                        return
                                                                            (
                                                                                (x as PerformanceCounterDefinitionAttribute)
                                                                                != null
                                                                            );
                                                                    }
                                                                ) as PerformanceCounterDefinitionAttribute;
                                    if (attribute != null)
                                    {
                                        var counterName = attribute.CounterName;
                                        if (!string.IsNullOrEmpty(counterName))
                                        {
                                            performanceCounterName = counterName;
                                        }
                                        var counterType = attribute.CounterType;
                                        //if (counterType != null)
                                        {
                                            performanceCounterType = counterType;
                                        }
                                    }
                                    var pc = new PerformanceCounter()
                                    {
                                        CategoryName = category
                                        ,
                                        CounterName = performanceCounterName
                                        ,
                                        InstanceLifetime = PerformanceCounterInstanceLifetime.Process
                                        ,
                                        InstanceName = performanceCounterInstanceName
                                        ,
                                        ReadOnly = false
                                        ,
                                        RawValue = 0
                                    };
                                    if (pi.GetGetMethod().IsStatic)
                                    {
                                        var setter =
                                                    DynamicPropertyAccessor
                                                        .CreateSetStaticPropertyValueAction<PerformanceCounter>
                                                            (
                                                                type
                                                                , propertyName
                                                            );
                                        setter(pc);
                                    }
                                    else
                                    {
                                        if (target != null)
                                        {
                                            var setter =
                                                        DynamicPropertyAccessor
                                                            .CreateSetPropertyValueAction<PerformanceCounter>
                                                                (
                                                                    type
                                                                    , propertyName
                                                                );
                                            setter(target, pc);
                                        }
                                    }
                                }
                            );
        }
        public static CounterCreationData GetCounterCreationData
                                            (
                                                string counterName
                                                , PerformanceCounterType performanceCounterType
                                            )
        {
            return new CounterCreationData()
            {
                CounterName = counterName
                ,
                CounterHelp = string.Format("{0} Help", counterName)
                ,
                CounterType = performanceCounterType
            };
        }
    }
}
namespace Microshaoft
{
    using System;
    using System.Threading;
    public static class ReaderWriterLockSlimHelper
    {
        public static bool TryEnterWriterLockSlimWrite<T>
                                                (
                                                     ref T target
                                                    , T newValue
                                                    , int enterTimeOutSeconds
                                                )
                                                    where T : class
        {
            bool r = false;
            var rwls = new ReaderWriterLockSlim();
            int timeOut = Timeout.Infinite;
            if (enterTimeOutSeconds >= 0)
            {
                timeOut = enterTimeOutSeconds * 1000;
            }
            try
            {
                r = (rwls.TryEnterWriteLock(timeOut));
                if (r)
                {
                    Interlocked.Exchange<T>(ref target, newValue);
                    r = true;
                }
            }
            finally
            {
                if (r)
                {
                    rwls.ExitWriteLock();
                }
            }
            return r;
        }
        public static bool TryEnterWriterLockSlim
                                (
                                    Action action
                                    , int enterTimeOutSeconds
                                )
        {
            bool r = false;
            if (action != null)
            {
                var rwls = new ReaderWriterLockSlim();
                int timeOut = Timeout.Infinite;
                if (enterTimeOutSeconds >= 0)
                {
                    timeOut = enterTimeOutSeconds * 1000;
                }
                try
                {
                    r = (rwls.TryEnterWriteLock(timeOut));
                    if (r)
                    {
                        action();
                        r = true;
                    }
                }
                finally
                {
                    if (r)
                    {
                        rwls.ExitWriteLock();
                    }
                }
            }
            return r;
        }
    }
}
namespace Microshaoft
{
    using System;
    using System.Linq;
    using System.Linq.Expressions;
    using System.Reflection;
    public class DynamicPropertyAccessor
    {
        private static Assembly GetAssemblyByTypeName(string typeName)
        {
            return
                AppDomain
                    .CurrentDomain
                        .GetAssemblies()
                            .First
                                (
                                    (a) =>
                                    {
                                        return
                                            a
                                                .GetTypes()
                                                    .Any
                                                        (
                                                            (t) =>
                                                            {
                                                                return
                                                                    (
                                                                        t.FullName
                                                                        == typeName
                                                                    );
                                                            }
                                                        );
                                    }
                                );
        }
        public static Func<object, object> CreateGetPropertyValueFunc
                        (
                            string typeName
                            , string propertyName
                            , bool isTypeFromAssembly = false
                        )
        {
            Type type;
            if (isTypeFromAssembly)
            {
                var assembly = GetAssemblyByTypeName(typeName);
                type = assembly.GetType(typeName);
            }
            else
            {
                type = Type.GetType(typeName);
            }
            return CreateGetPropertyValueFunc(type, propertyName);
        }
        public static Func<object, object> CreateGetPropertyValueFunc
                        (
                            Type type
                            , string propertyName
                        )
        {
            var target = Expression.Parameter(typeof(object));
            var castTarget = Expression.Convert(target, type);
            var getPropertyValue = Expression.Property(castTarget, propertyName);
            var castPropertyValue = Expression.Convert(getPropertyValue, typeof(object));
            var lambda = Expression.Lambda<Func<object, object>>(castPropertyValue, target);
            return lambda.Compile();
        }
        public static Func<object, TProperty> CreateGetPropertyValueFunc<TProperty>
                        (
                            string typeName
                            , string propertyName
                            , bool isTypeFromAssembly = false
                        )
        {
            Type type;
            if (isTypeFromAssembly)
            {
                var assembly = GetAssemblyByTypeName(typeName);
                type = assembly.GetType(typeName);
            }
            else
            {
                type = Type.GetType(typeName);
            }
            return CreateGetPropertyValueFunc<TProperty>(type, propertyName);
        }
        public static Func<object, TProperty> CreateGetPropertyValueFunc<TProperty>
                        (
                            Type type
                            , string propertyName
                        )
        {
            var target = Expression.Parameter(typeof(object));
            var castTarget = Expression.Convert(target, type);
            var getPropertyValue = Expression.Property(castTarget, propertyName);
            var lambda = Expression.Lambda<Func<object, TProperty>>(getPropertyValue, target);
            return lambda.Compile();
        }
        public static Func<TProperty> CreateGetStaticPropertyValueFunc<TProperty>
                        (
                            string typeName
                            , string propertyName
                            , bool isTypeFromAssembly = false
                        )
        {
            Type type;
            if (isTypeFromAssembly)
            {
                var assembly = GetAssemblyByTypeName(typeName);
                type = assembly.GetType(typeName);
            }
            else
            {
                type = Type.GetType(typeName);
            }
            return CreateGetStaticPropertyValueFunc<TProperty>(type, propertyName);
        }
        public static Func<TProperty> CreateGetStaticPropertyValueFunc<TProperty>
                        (
                            Type type
                            , string propertyName
                        )
        {
            Func<TProperty> func = null;
            var property = type.GetProperty(propertyName, typeof(TProperty));
            if (property == null)
            {
                property =
                            type
                                .GetProperties()
                                    .ToList()
                                        .FirstOrDefault
                                            (
                                                (x) =>
                                                {
                                                    return
                                                        (
                                                            x.Name.ToLower()
                                                            == propertyName.ToLower()
                                                        );
                                                }
                                            );
            }
            if (property != null)
            {
                var getPropertyValue = Expression.Property(null, property);
                var lambda = Expression.Lambda<Func<TProperty>>(getPropertyValue, null);
                func = lambda.Compile();
            }
            return func;
        }
        public static Func<object> CreateGetStaticPropertyValueFunc
                        (
                            Type type
                            , string propertyName
                        )
        {
            Func<object> func = null;
            var property = type.GetProperty(propertyName);
            if (property == null)
            {
                property =
                            type
                                .GetProperties()
                                    .ToList()
                                        .FirstOrDefault
                                            (
                                                (x) =>
                                                {
                                                    return
                                                        (
                                                            x.Name.ToLower()
                                                            == propertyName.ToLower()
                                                        );
                                                }
                                            );
            }
            if (property != null)
            {
                var getPropertyValue = Expression.Property(null, property);
                var castPropertyValue = Expression.Convert(getPropertyValue, typeof(object));
                var lambda = Expression.Lambda<Func<object>>(castPropertyValue, null);
                func = lambda.Compile();
            }
            return func;
        }
        public static Func<object> CreateGetStaticPropertyValueFunc
                        (
                            string typeName
                            , string propertyName
                            , bool isTypeFromAssembly = false
                        )
        {
            Type type;
            if (isTypeFromAssembly)
            {
                var assembly = GetAssemblyByTypeName(typeName);
                type = assembly.GetType(typeName);
            }
            else
            {
                type = Type.GetType(typeName);
            }
            return CreateGetStaticPropertyValueFunc(type, propertyName);
        }
        public static Action<object, object> CreateSetPropertyValueAction
                        (
                            Type type
                            , string propertyName
                        )
        {
            Action<object, object> action = null;
            var property = type.GetProperty(propertyName);
            if (property == null)
            {
                property =
                            type
                                .GetProperties()
                                    .ToList()
                                        .FirstOrDefault
                                            (
                                                (x) =>
                                                {
                                                    return
                                                        (
                                                            x.Name.ToLower()
                                                            == propertyName.ToLower()
                                                        );
                                                }
                                            );
            }
            if (property != null)
            {
                var target = Expression.Parameter(typeof(object));
                var propertyValue = Expression.Parameter(typeof(object));
                var castTarget = Expression.Convert(target, type);
                var castPropertyValue = Expression.Convert(propertyValue, property.PropertyType);
                var getSetMethod = property.GetSetMethod();
                if (getSetMethod == null)
                {
                    getSetMethod = property.GetSetMethod(true);
                }
                var call = Expression.Call(castTarget, getSetMethod, castPropertyValue);
                var lambda = Expression.Lambda<Action<object, object>>(call, target, propertyValue);
                action = lambda.Compile();
            }
            return action;
        }
        public static Action<object, object> CreateSetPropertyValueAction
                        (
                            string typeName
                            , string propertyName
                            , bool isTypeFromAssembly = false
                        )
        {
            Type type;
            if (isTypeFromAssembly)
            {
                var assembly = GetAssemblyByTypeName(typeName);
                type = assembly.GetType(typeName);
            }
            else
            {
                type = Type.GetType(typeName);
            }
            return CreateSetPropertyValueAction(type, propertyName);
        }
        public static Action<object, TProperty> CreateSetPropertyValueAction<TProperty>
                        (
                            Type type
                            , string propertyName
                        )
        {
            Action<object, TProperty> action = null;
            var property = type.GetProperty(propertyName);
            if (property == null)
            {
                property =
                            type
                                .GetProperties()
                                    .ToList()
                                        .FirstOrDefault
                                            (
                                                (x) =>
                                                {
                                                    return
                                                        (
                                                            x.Name.ToLower()
                                                            == propertyName.ToLower()
                                                        );
                                                }
                                            );
            }
            if (property != null)
            {
                var target = Expression.Parameter(typeof(object));
                var propertyValue = Expression.Parameter(typeof(TProperty));
                var castTarget = Expression.Convert(target, type);
                var castPropertyValue = Expression.Convert(propertyValue, property.PropertyType);
                var getSetMethod = property.GetSetMethod();
                if (getSetMethod == null)
                {
                    getSetMethod = property.GetSetMethod(true);
                }
                var call = Expression.Call(castTarget, getSetMethod, castPropertyValue);
                var lambda = Expression.Lambda<Action<object, TProperty>>(call, target, propertyValue);
                action = lambda.Compile();
            }
            return action;
        }
        public static Action<object, TProperty> CreateSetPropertyValueAction<TProperty>
                        (
                            string typeName
                            , string propertyName
                            , bool isTypeFromAssembly = false
                        )
        {
            Type type;
            if (isTypeFromAssembly)
            {
                var assembly = GetAssemblyByTypeName(typeName);
                type = assembly.GetType(typeName);
            }
            else
            {
                type = Type.GetType(typeName);
            }
            return CreateSetPropertyValueAction<TProperty>(type, propertyName);
        }
        public static Action<object> CreateSetStaticPropertyValueAction
                        (
                            Type type
                            , string propertyName
                        )
        {
            Action<object> action = null;
            var property = type.GetProperty(propertyName);
            if (property == null)
            {
                property =
                            type
                                .GetProperties()
                                    .ToList()
                                        .FirstOrDefault
                                            (
                                                (x) =>
                                                {
                                                    return
                                                        (
                                                            x.Name.ToLower()
                                                            == propertyName.ToLower()
                                                        );
                                                }
                                            );
            }
            if (property != null)
            {
                var propertyValue = Expression.Parameter(typeof(object));
                var castPropertyValue = Expression.Convert(propertyValue, property.PropertyType);
                var getSetMethod = property.GetSetMethod();
                if (getSetMethod == null)
                {
                    getSetMethod = property.GetSetMethod(true);
                }
                var call = Expression.Call(null, getSetMethod, castPropertyValue);
                var lambda = Expression.Lambda<Action<object>>(call, propertyValue);
                action = lambda.Compile();
            }
            return action;
        }
        public static Action<object> CreateSetStaticPropertyValueAction
                        (
                            string typeName
                            , string propertyName
                            , bool isTypeFromAssembly = false
                        )
        {
            Type type;
            if (isTypeFromAssembly)
            {
                var assembly = GetAssemblyByTypeName(typeName);
                type = assembly.GetType(typeName);
            }
            else
            {
                type = Type.GetType(typeName);
            }
            return CreateSetStaticPropertyValueAction(type, propertyName);
        }
        public static Action<TProperty> CreateSetStaticPropertyValueAction<TProperty>
                        (
                            Type type
                            , string propertyName
                        )
        {
            Action<TProperty> action = null;
            var property = type.GetProperty(propertyName);
            if (property == null)
            {
                property =
                            type
                                .GetProperties()
                                    .ToList()
                                        .FirstOrDefault
                                            (
                                                (x) =>
                                                {
                                                    return
                                                        (
                                                            x.Name.ToLower()
                                                            == propertyName.ToLower()
                                                        );
                                                }
                                            );
            }
            if (property != null)
            {
                var propertyValue = Expression.Parameter(typeof(TProperty));
                //var castPropertyValue = Expression.Convert(propertyValue, property.PropertyType);
                var getSetMethod = property.GetSetMethod();
                if (getSetMethod == null)
                {
                    getSetMethod = property.GetSetMethod(true);
                }
                var call = Expression.Call(null, getSetMethod, propertyValue);
                var lambda = Expression.Lambda<Action<TProperty>>(call, propertyValue);
                action = lambda.Compile();
            }
            return action;
        }
        public static Action<TProperty> CreateSetStaticPropertyValueAction<TProperty>
                        (
                            string typeName
                            , string propertyName
                            , bool isTypeFromAssembly = false
                        )
        {
            Type type;
            if (isTypeFromAssembly)
            {
                var assembly = GetAssemblyByTypeName(typeName);
                type = assembly.GetType(typeName);
            }
            else
            {
                type = Type.GetType(typeName);
            }
            return CreateSetStaticPropertyValueAction<TProperty>(type, propertyName);
        }
    }
}
namespace Microshaoft
{
    using System;
    using System.Diagnostics;
    using System.Reflection;
    using System.Threading.Tasks;
    public static class TryCatchFinallyProcessHelper
    {
        public static async Task<T> TryProcessCatchFinallyAsync<T>
                                    (
                                        bool needTry
                                        , Func<Task<T>> onTryProcessFunc
                                        , bool reThrowException = false
                                        , Func<Exception, bool> onCaughtExceptionProcessFunc = null
                                        , Action<bool, Exception> onFinallyProcessAction = null
                                    )
        {
            T r = default(T);
            //if (onTryProcessAction != null)
            {
                if (needTry)
                {
                    Exception exception = null;
                    var caughtException = false;
                    try
                    {
                        r = await onTryProcessFunc();
                        return r;
                    }
                    catch (Exception e)
                    {
                        caughtException = true;
                        exception = e;
                        var currentCalleeMethod = MethodInfo.GetCurrentMethod();
                        var currentCalleeType = currentCalleeMethod.DeclaringType;
                        StackTrace stackTrace = new StackTrace();
                        StackFrame stackFrame = stackTrace.GetFrame(1);
                        var callerMethod = stackFrame.GetMethod();
                        var callerType = callerMethod.DeclaringType;
                        var frame = (stackTrace.FrameCount > 1 ? stackTrace.FrameCount - 1 : 1);
                        stackFrame = stackTrace.GetFrame(frame);
                        var originalCallerMethod = stackFrame.GetMethod();
                        var originalCallerType = originalCallerMethod.DeclaringType;
                        var innerExceptionMessage = string.Format
                                (
                                    "Rethrow caught [{1}] Exception{0} at Callee Method: [{2}]{0} at Caller Method: [{3}]{0} at Original Caller Method: [{4}]"
                                    , "\r\n\t"
                                    , e.Message
                                    , string.Format("{1}{0}{2}", "::", currentCalleeType, currentCalleeMethod)
                                    , string.Format("{1}{0}{2}", "::", callerType, callerMethod)
                                    , string.Format("{1}{0}{2}", "::", originalCallerType, originalCallerMethod)
                                );
                        Console.WriteLine(innerExceptionMessage);
                        if (onCaughtExceptionProcessFunc != null)
                        {
                            reThrowException = onCaughtExceptionProcessFunc(e);
                        }
                        if (reThrowException)
                        {
                            throw
                                new Exception
                                        (
                                            innerExceptionMessage
                                            , e
                                        );
                        }
                        return r;
                    }
                    finally
                    {
                        if (onFinallyProcessAction != null)
                        {
                            onFinallyProcessAction(caughtException, exception);
                        }
                    }
                }
                else
                {
                    return await onTryProcessFunc();
                }
            }
        }
        public static void TryProcessCatchFinally
                                    (
                                        bool needTry
                                        , Action onTryProcessAction
                                        , bool reThrowException = false
                                        , Func<Exception, bool> onCaughtExceptionProcessFunc = null
                                        , Action<bool, Exception> onFinallyProcessAction = null
                                    )
        {
            if (onTryProcessAction != null)
            {
                if (needTry)
                {
                    Exception exception = null;
                    var caughtException = false;
                    try
                    {
                        onTryProcessAction();
                    }
                    catch (Exception e)
                    {
                        caughtException = true;
                        exception = e;
                        var currentCalleeMethod = MethodInfo.GetCurrentMethod();
                        var currentCalleeType = currentCalleeMethod.DeclaringType;
                        StackTrace stackTrace = new StackTrace(e, true);
                        StackFrame stackFrame = stackTrace.GetFrame(1);
                        var callerMethod = stackFrame.GetMethod();
                        var callerType = callerMethod.DeclaringType;
                        var frame = (stackTrace.FrameCount > 1 ? stackTrace.FrameCount - 1 : 1);
                        stackFrame = stackTrace.GetFrame(frame);
                        var originalCallerMethod = stackFrame.GetMethod();
                        var originalCallerType = originalCallerMethod.DeclaringType;
                        var innerExceptionMessage = string.Format
                                (
                                    "Rethrow caught [{1}] Exception{0} at Callee Method: [{2}]{0} at Caller Method: [{3}]{0} at Original Caller Method: [{4}]"
                                    , "\r\n\t"
                                    , e.Message
                                    , string.Format("{1}{0}{2}", "::", currentCalleeType, currentCalleeMethod)
                                    , string.Format("{1}{0}{2}", "::", callerType, callerMethod)
                                    , string.Format("{1}{0}{2}", "::", originalCallerType, originalCallerMethod)
                                );
                        //Console.WriteLine(innerExceptionMessage);
                        if (onCaughtExceptionProcessFunc != null)
                        {
                            reThrowException = onCaughtExceptionProcessFunc(e);
                        }
                        if (reThrowException)
                        {
                            throw
                                new Exception
                                        (
                                            innerExceptionMessage
                                            , e
                                        );
                        }
                    }
                    finally
                    {
                        //Console.WriteLine("Finally");
                        if (onFinallyProcessAction != null)
                        {
                            onFinallyProcessAction(caughtException, exception);
                        }
                    }
                }
                else
                {
                    onTryProcessAction();
                }
            }
        }
    }
}
// .html
/*
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Microshaoft Cross-Domain + ASP.NET MVC 4 WebAPI  + JsonpMediaTypeFormatter + Knockout.js + MVVM Sample</title>
    <!-- <base href="http://api.asp.net.local" /> -->
    <!-- <script src="http://api.asp.net.local/Scripts/jquery.mobile-1.3.1.js" type="text/javascript"></script> -->
    <script src="http://scripts.asp.net.local/Scripts/jquery-2.0.3.js" type="text/javascript"></script>
    <script src="http://scripts.asp.net.local/Scripts/knockout-2.3.0.js" type="text/javascript"></script>
    <script src="http://scripts.asp.net.local/Scripts/knockout.simpleGrid.1.3.js" type="text/javascript"></script>
</head>
<body>
    <input type="button" value="Load from IIS+WebAPI+JsonP+Cross-Domain" onclick="GetData('http://api.asp.net.local/services/restful/api/persons/*?callback=?');" />
    <br />
    <input type="button" value="Load from WebAPI Self-Host+JsonP+Cross-Domain" onclick="GetData('http://localhost:9080/services/restful/api/persons/*?callback=?');" />
    <br />
    <input type="button" value="Load from Console+WCF+JsonP+Cross-Domain" onclick="GetData('http://api.asp.net.local:1080/services/restful/wcf/persons/*?callback=?');" />
    <br />
    <input type="button" value="Load from IIS+WCF+Json" onclick="GetData('http://portal.asp.net.local/services/restful/wcf/persons/*');" />
    <br />
    <input type="button" value="Load from WebAPI Self-Host+Json" onclick="GetData('http://localhost:9080/services/restful/api/persons/*');" />
    <br />
    <div>
        <div data-bind='simpleGrid: gridViewModel'>
            PlaceHolder
        </div>
        <button data-bind='click: sortByPriceDesc'>
            Sort by Price Desc
        </button>
        <button data-bind='click: jumpToFirstPage, enable: gridViewModel.currentPageIndex'>
            Jump to first page
        </button> 
    </div>
    <div>
        Name:<input type="text"  />
        <br />
        Age:<input type="text"  />
        <br />
        Height:<input type="text"  />
        <br />
        Weight:<input type="text"  />
        <br />
        <input type="button" value="Post to IIS" onclick="PostData('http://api.asp.net.local/services/restful/api/persons/?NAME=发财發財facai')" />
        <br />
        <input type="button" value="Post to Self-Host" onclick="PostData('http://localhost:9080/services/restful/api/persons/?NAME=发财發財facai')" />
    </div>
    <script type="text/javascript">
    <!--
        function PostData(url)
        {
            var func = function(scriptCode) {
                            var code = "(" + scriptCode + ");";
                            return eval(code);
                        };
            var jsonText, r;
            jsonText = 
                        '[{Name : "' + document.getElementById("text1").value + "\" ,"
                    +    "\"Age\" : " + document.getElementById("text2").value + " ,"
                    +    '"Height" : "' + document.getElementById("text3").value + "\", "
                    +    "\"Weight\" : " + document.getElementById("text3").value + ' }]';
            //jsonText = '[{"Name":"page1","Age":0,"Height":1,"Weight":2},{"Name":"page2","Age":0,"Height":1,"Weight":2}]';//jsonText,
            //alert(jsonText);
            r = func(jsonText);
            //alert(r[0].Name);
            $.ajax({
                        url: url,
                        type: 'POST',
                        data: jsonText,//'[{"Name":"page1","Age":0,"Height":1,"Weight":2},{"Name":"page2","Age":0,"Height":1,"Weight":2}]',//jsonText,
                        //crossDomain: true,
                        dataType: 'json',
                        contentType: "application/json; charset=utf-8",
                        success: function (x) {
                                        alert("callback: " + x[0].Name);
                                    },
                        error: function (x) {
                                        alert(x);
                                    }
                });
        }
        function GetData(url)
        {
            //jsonp cross domain
            //alert(url);
            $.getJSON(
                        url
                        , function(data){
                            //alert(data);
                            $.each(data, function(i ,item){
                                vm.addItem(item);
                                        }
                                    );
                            }
                    );
            //jsonp cross domain
//            $.ajax({
//                url : 'http://api.asp.net.local/services/restful/api/persons',
//                type : 'GET',
//                dataType : 'jsonp',
//                success : function (data) {
//                    vm.addItems(data);
//                }
//            });
//            $.get(
//                    'http://api.asp.net.local/services/restful/api/persons'
//                    , function (data) {
//                        vm.addItems(data);
//                    }
//                );
        }
        var PagedGridModel = function(items) {
            this.items = ko.observableArray(items);
            this.addItem = function(item) {
                this.items.push(item);
            };
            this.addItems = function(items) {
                for (var i in items) {
                    this.items.push(items[i]);
                }
            };
            this.sortByPriceDesc = function() {
                this.items.sort(function(a, b) {
                    var r = a.Weight.toFixed(2) < b.Weight.toFixed(2) ? 1 : -1;
                    return r;
                });
            };
            this.jumpToFirstPage = function() {
                this.gridViewModel.currentPageIndex(0);
            };
            this.gridViewModel = new ko.simpleGrid.viewModel(
                {
                    data: this.items ,
                    columns: [
                                {
                                    headerText : "Item Name",
                                    rowText : "Name"
                                },
                                {
                                    headerText : "Sales Count",
                                    rowText : "Age"
                                },
                                {
                                    headerText : "Price",
                                    rowText : function (item) {
                                                    return "$" + item.Weight.toFixed(2)
                                                }
                                }
                    ],
                    pageSize : 9
                });
        };
        var vm = new PagedGridModel([]);
        ko.applyBindings(vm);
    //-->
    </script>
</body>
</html>
*/
// Web.Config
/*
<?xml version="1.0" encoding="utf-8"?>
<!--
    For more information on how to configure your ASP.NET application, please visit
    http://go.microsoft.com/fwlink/?LinkId=169433
-->
<configuration>
    <configSections>
        <section name="glimpse" type="Glimpse.Core.Configuration.Section, Glimpse.Core" />
    </configSections>
    <system.serviceModel>
        <behaviors>
            <endpointBehaviors>
                <behavior name="webHttpBehavior">
                    <webHttp />
                </behavior>
            </endpointBehaviors>
        </behaviors>
        <bindings>
            <webHttpBinding>
                <binding
                    name="webHttpBindingWithJsonP"
                    crossDomainScriptAccessEnabled="true"
                />
            </webHttpBinding>
        </bindings>
        <services>
            <service name="Microshaoft.WCF.Services.PersonsServices">
                <endpoint
                    binding="webHttpBinding"
                    bindingConfiguration="webHttpBindingWithJsonP"
                    contract="Microshaoft.WCF.Contracts.IPersonsServices"
                    behaviorConfiguration="webHttpBehavior"
                />
            </service>
        </services>
        <serviceHostingEnvironment
            aspNetCompatibilityEnabled="true"
            multipleSiteBindingsEnabled="true"
        />
    </system.serviceModel>
    <connectionStrings>
        <add
            name="GlimpseAppDB"
            connectionString="Application Name=GlimpseApp;Persist Security Info=False;Data Source=.\Enterprise2012;Integrated Security=SSPI;"
            providerName="System.Data.SqlClient"
        />
    </connectionStrings>
    <system.diagnostics>
            <sources>
                <source name="Example Source" switchName="sourceSwitch" switchType="System.Diagnostics.SourceSwitch">
                    <listeners>
                        <add name="GlimpseListener"/>
                    </listeners>
                </source>
            </sources>
            <switches>
                <add name="sourceSwitch" value="Warning"/>
            </switches>
        <sharedListeners>
            <add name="GlimpseListener" type="Glimpse.Core.TraceListener, Glimpse.Core"/>
        </sharedListeners>
    </system.diagnostics>
    <system.web>
    <!--
        Glimpse: This can be commented in to add additional data to the Trace tab when using WebForms
        <trace writeToDiagnosticsTrace="true" enabled="true" pageOutput="false"/>
    -->
        <trace enabled="false" pageOutput="false" localOnly="false"/>
        <httpModules>
            <add name="Glimpse" type="Glimpse.AspNet.HttpModule, Glimpse.AspNet" />
        </httpModules>
        <httpHandlers>
            <add path="glimpse.axd" verb="GET" type="Glimpse.AspNet.HttpHandler, Glimpse.AspNet" />
        </httpHandlers>
        <httpRuntime requestPathInvalidCharacters="" requestValidationMode="2.0" />
        <pages validateRequest="false" />
    </system.web>
    <system.webServer>
        <httpProtocol>
            <customHeaders>
                <add name="Access-Control-Allow-Origin" value="*" />
                <add name="Access-Control-Allow-Methods" value="*" />
                <add name="Access-Control-Allow-Credentials" value="true" />
                <add name="Access-Control-Allow-Headers" value="*, Origin, X-Requested-With, Content-Type, Accept" />
                <!-- <add name="Access-Control-Allow-Headers" value="*" /> -->
            </customHeaders>
        </httpProtocol>
        <validation validateIntegratedModeConfiguration="false" />
        <handlers>
            <add name="Glimpse" path="glimpse.axd" verb="GET" type="Glimpse.AspNet.HttpHandler, Glimpse.AspNet" preCondition="integratedMode" />
        </handlers>
        <modules>
            <add name="Glimpse" type="Glimpse.AspNet.HttpModule, Glimpse.AspNet" preCondition="integratedMode" />
        </modules>
    </system.webServer>
    <glimpse defaultRuntimePolicy="On" endpointBaseUri="~/Glimpse.axd">
    <!--
        If you are having issues with Glimpse, please include this. It will help us figure out whats going on.
        <logging level="Trace" />
    -->
    <!--
        Want to use Glimpse on a remote server? Ignore the LocalPolicy by removing this comment.
        <runtimePolicies>
            <ignoredTypes>
                <add type="Glimpse.AspNet.Policy.LocalPolicy, Glimpse.AspNet"/>
            </ignoredTypes>
        </runtimePolicies>
    -->
    </glimpse>
</configuration>
*/
// Web.Config
/*
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <behaviors>
            <endpointBehaviors>
                <behavior name="webHttpBehavior">
                    <webHttp />
                </behavior>
            </endpointBehaviors>
        </behaviors>
        <bindings>
            <webHttpBinding>
                <binding
                    name="webHttpBindingWithJsonP"
                    crossDomainScriptAccessEnabled="true"
                />
            </webHttpBinding>
        </bindings>
        <services>
            <service name="Microshaoft.WCF.Services.PersonsServices">
                <!--
                    address="http://api.asp.net.local:1080/services/restful/wcf/persons"
                -->
                <endpoint
                    address="http://api.asp.net.local:1080/services/restful/wcf/persons"
                    binding="webHttpBinding"
                    bindingConfiguration="webHttpBindingWithJsonP"
                    contract="Microshaoft.WCF.Contracts.IPersonsServices"
                    behaviorConfiguration="webHttpBehavior"
                />
            </service>
        </services>
        <serviceHostingEnvironment
            aspNetCompatibilityEnabled="true"
            multipleSiteBindingsEnabled="true"
        />
    </system.serviceModel>
</configuration>
*/