text 拆分选中的表格-8-13

拆分选中的表格-8-13

untitled
Sub splitSelectCells()

  Selection.Range.HighlightColorIndex = wdBrightGreen
  Selection.Collapse wdCollapseStart

Dim a, b As Integer
a = Selection.Tables(1).Columns.count
b = Selection.Tables(1).Range.Cells.count
If Asc(Selection.Tables(1).Cell(b, a).Range.Text) = 13 Then
  Selection.Tables(1).Cell(b, a).Range.Text = "WAITDELET"
End If
Selection.Tables(1).Cell(b, a).Range.HighlightColorIndex = wdRed

  Call SplitCells
End Sub
Sub SplitCells()
Application.ScreenUpdating = False
Dim tt As Single
tt = Timer
Dim selT As String
Dim arr
Dim i, j As Integer
Dim TC As Integer
Dim columnsC As Integer





Do
  
    selT = Selection.Range.Cells(1).Range.Text
    If Len(selT) > 5 And Selection.Range.HighlightColorIndex = wdBrightGreen Then
    If Selection.Cells(1).Range.Paragraphs.count > 1 Then
  
  
    arr = Split(selT, ChrW(13))
    Dim p As Integer
    p = Selection.Cells(1).Range.Paragraphs.count
    Selection.Range.Cells(1).Range.Cut
    Selection.Cells.Split Numrows:=p, Numcolumns:=1, MergeBeforeSplit:=False
  
    Selection.MoveRight wdCell, 2
    
      For j = 0 To UBound(arr) - 1
      
        Dim oriS, doneS As String
        oriS = Selection.Paragraphs(1).Range.Text
     If j = 0 Then
      Selection.MoveLeft wdCell, 1
       End If
       
      doneS = Selection.Paragraphs(1).Range.Text
        If j <> 0 Then
        If oriS = doneS Then
          Selection.MoveDown wdLine, 1
        End If
        End If

      Selection.TypeText arr(j)
      Next
      
      
      Selection.MoveRight unit:=wdCell
      
      ElseIf Selection.Range.Next(wdParagraph, 2).Information(wdWithInTable) Then
    
      Selection.MoveRight unit:=wdCell
      
  End If
  Else

    Selection.MoveRight unit:=wdCell
  End If

  

Loop While Selection.Range.HighlightColorIndex <> wdRed


If Selection.Range.HighlightColorIndex = wdRed Then
    selT = Selection.Range.Cells(1).Range.Text
    If Left(selT, 4) = "WAIT" Then
      Selection.Range.Cells(1).Range.Text = ""
    End If
    
    If Len(selT) > 5 Then
    If Selection.Cells(1).Range.Paragraphs.count > 1 Then
    arr = Split(selT, ChrW(13))
    p = Selection.Cells(1).Range.Paragraphs.count
    Selection.Range.Cells(1).Range.Cut
    Selection.Cells.Split Numrows:=p, Numcolumns:=1, MergeBeforeSplit:=False
    
    Selection.MoveLeft wdCell, 2
    For j = 0 To UBound(arr) - 1
    oriS = Selection.Paragraphs(1).Range.Text
    If j = 0 Then
    Selection.MoveRight wdCell, 1
    End If
       
      doneS = Selection.Paragraphs(1).Range.Text
        If j <> 0 Then
        If oriS = doneS Then
          Selection.MoveDown wdLine, 1
        End If
        End If

    Selection.TypeText arr(j)
    Next
    Else
  End If
  Else
  End If
End If
Selection.Tables(1).Range.HighlightColorIndex = wdAuto
Application.ScreenUpdating = True
End Sub

text Sqllite DB内容Flask API

返回从sqllite DB中提取的json格式数据的基本烧瓶API,将参数传递给过滤器(假设文件路径为c:\ project @\\ api \ api_final.py),使用命令c:\project \ api> python api_final运行.py <br/> <br/> http://127.0.0.1:5000/api/v1/resources/books/all <br/> http://127.0.0.1:5000/api/v1/resources/books ?author = Connie + Willis <br/> http://127.0.0.1:5000/api/v1/resources/books?author=Connie+Willis&published=1999 <br/> http://127.0.0.1:5000/api / V1 /资源/书籍?公布= 2010

api_final
import flask
from flask import request, jsonify
import sqlite3

app = flask.Flask(__name__)
app.config["DEBUG"] = True

def dict_factory(cursor, row):
    d = {}
    for idx, col in enumerate(cursor.description):
        d[col[0]] = row[idx]
    return d


@app.route('/', methods=['GET'])
def home():
    return '''<h1>Distant Reading Archive</h1>
<p>A prototype API for distant reading of science fiction novels.</p>'''


@app.route('/api/v1/resources/books/all', methods=['GET'])
def api_all():
    conn = sqlite3.connect('books.db')
    conn.row_factory = dict_factory
    cur = conn.cursor()
    all_books = cur.execute('SELECT * FROM books;').fetchall()

    return jsonify(all_books)



@app.errorhandler(404)
def page_not_found(e):
    return "<h1>404</h1><p>The resource could not be found.</p>", 404


@app.route('/api/v1/resources/books', methods=['GET'])
def api_filter():
    query_parameters = request.args

    id = query_parameters.get('id')
    published = query_parameters.get('published')
    author = query_parameters.get('author')

    query = "SELECT * FROM books WHERE"
    to_filter = []

    if id:
        query += ' id=? AND'
        to_filter.append(id)
    if published:
        query += ' published=? AND'
        to_filter.append(published)
    if author:
        query += ' author=? AND'
        to_filter.append(author)
    if not (id or published or author):
        return page_not_found(404)

    query = query[:-4] + ';'

    conn = sqlite3.connect('books.db')
    conn.row_factory = dict_factory
    cur = conn.cursor()

    results = cur.execute(query, to_filter).fetchall()

    return jsonify(results)

app.run()

text 基本Flask API

返回json格式的basic flask API,将参数传递给filter(假设文件路径为c:\ project @\\ api \ api.py),使用命令c:\project \ api> python api.py $ b $运行b <br/> 127.0.0.1:5000/api/v1/resources/books?id=0 <br/> 127.0.0.1:5000/api/v1/resources/books?id=1 <br/> 127.0.0.1 :5000 / api / v1 / resources / books?id = 2 <br/> 127.0.0.1:5000/api/v1/resources/books?id=3

api
import flask
from flask import request, jsonify

app = flask.Flask(__name__)
app.config["DEBUG"] = True

# Create some test data for our catalog in the form of a list of dictionaries.
books = [
    {'id': 0,
     'title': 'A Fire Upon the Deep',
     'author': 'Vernor Vinge',
     'first_sentence': 'The coldsleep itself was dreamless.',
     'year_published': '1992'},
    {'id': 1,
     'title': 'The Ones Who Walk Away From Omelas',
     'author': 'Ursula K. Le Guin',
     'first_sentence': 'With a clamor of bells that set the swallows soaring, the Festival of Summer came to the city Omelas, bright-towered by the sea.',
     'published': '1973'},
    {'id': 2,
     'title': 'Dhalgren',
     'author': 'Samuel R. Delany',
     'first_sentence': 'to wound the autumnal city.',
     'published': '1975'}
]


@app.route('/', methods=['GET'])
def home():
    return '''<h1>Distant Reading Archive</h1>
<p>A prototype API for distant reading of science fiction novels.</p>'''


@app.route('/api/v1/resources/books/all', methods=['GET'])
def api_all():
    return jsonify(books)


@app.route('/api/v1/resources/books', methods=['GET'])
def api_id():
    # Check if an ID was provided as part of the URL.
    # If ID is provided, assign it to a variable.
    # If no ID is provided, display an error in the browser.
    if 'id' in request.args:
        id = int(request.args['id'])
    else:
        return "Error: No id field provided. Please specify an id."

    # Create an empty list for our results
    results = []

    # Loop through the data and match results that fit the requested ID.
    # IDs are unique, but other fields might return many results
    for book in books:
        if book['id'] == id:
            results.append(book)

    # Use the jsonify function from Flask to convert our list of
    # Python dictionaries to the JSON format.
    return jsonify(results)

app.run()

text 在Jquery中通过类名追加或替换元素

Append or Replace elements via Class Name in Jquery
jQuery(document).ready(function($) {
    //$( "div.hero-search__content" ).replaceWith( "<h2>New heading</h2>" );
    $( ".hero-search__title" ).append( "<h2>New heading</h2>" );
    $( ".hero-search__title" ).replace( "<h2>New heading</h2>" );
    $("h4:contains('Wrap')").replaceWith("<h4>Gift Message</h4>");
});

text 在Wordpres中添加自定义Jquery脚本

在Wordpres中添加自定义Jquery脚本

Add Custom Jquery Scripts in Wordpres
https://benfrain.com/how-to-easily-add-jquery-scripts-to-a-wordpress-child-theme/

Add @ functions.php of child theme:

if ( !is_admin() ) { // instruction to only load if it is not the admin area
    // register your script location, dependencies and version
    wp_register_script('custom_script',
        get_bloginfo('stylesheet_directory') . '/js/custom_script.js',
        array('jquery'),
        '1.0' );

    // enqueue the script
    wp_enqueue_script('custom_script');
}

Make sure to add jquery functions like the following template:

jQuery(document).ready(function($) {
    //$( "div.hero-search__content" ).replaceWith( "<h2>New heading</h2>" );
    $( ".hero-search__title" ).replaceWith( "<h2>New heading</h2>" );
});

text 补全页码-8-13

补全页码-8-13

untitled
Sub cpn(ByVal control As IRibbonControl)
Dim unit As String
  Call layout_search_replace.jump_to_reference_section
  With Selection.Find
    .Text = " [0-9]{1,}[-–][0-9]{1,}[!0-9]"
    .MatchWildcards = True
    .Wrap = wdFindStop
    
    .Forward = True
    Do
    .Execute
    unit = Selection.Range.Text
      If Not .Found Then
      Exit Do
        Else
        If InStr(Selection.Range.Text, "-") > 0 Then
        
          arr = Split(Selection.Range.Text, "-")
        
        Else
          arr = Split(Selection.Range.Text, ChrW(8211))
        End If


        If Len(Trim(arr(0))) > Len(Left(arr(1), Len(arr(1)) - 1)) Then
          Selection.Range.Text = FunctionGroup.ComLackPage(Selection.Range.Text)
          Selection.MoveRight wdCharacter, Len(unit)
        End If
        
        
        
      End If
    Loop
  End With
  
End Sub
Function ComLackPage(str As String) As String
   Dim reg As Object
    Set reg = CreateObject("VBScript.Regexp")
    Dim is_exist As Boolean
    With reg
        .Global = True
        .Pattern = " (\d\d+)([-–]\d+)(?!\d)"
        is_exist = .test(str)
    End With
    Dim matches As Object, match As Object
    Set matches = reg.Execute(str)
    
    If is_exist = True Then
      For Each match In matches
      
        firstNum = match.submatches(0)
        NextNum = Right(match.submatches(1), Len(match.submatches(1)) - 1)
        
        
          Select Case Len(firstNum)
          
          Case 2
            If Len(NextNum) = 1 Then
            If CInt(Right(firstNum, Len(firstNum) - 1)) < CInt(NextNum) Then
              oldnum = match
              
              newnum = Replace(match, NextNum, Left(firstNum, 1) + NextNum)
            End If
            End If
          Case 3
          
            Select Case Len(NextNum)
            
            Case 1
            If CInt(Right(firstNum, Len(firstNum) - 2)) < CInt(NextNum) Then
              oldnum = match
              
              newnum = Replace(match, NextNum, Left(firstNum, 2) + NextNum)
            End If
            
            Case 2
            If CInt(Right(firstNum, Len(firstNum) - 1)) < CInt(NextNum) Then
              oldnum = match
              
              newnum = Replace(match, NextNum, Left(firstNum, 1) + NextNum)
            End If
            
            End Select
          
          Case 4
            Select Case Len(NextNum)
            
            Case 1
            If CInt(Right(firstNum, Len(firstNum) - 3)) < CInt(NextNum) Then
              oldnum = match
              
              newnum = Replace(match, NextNum, Left(firstNum, 3) + NextNum)
            End If
            
            Case 2
            If CInt(Right(firstNum, Len(firstNum) - 2)) < CInt(NextNum) Then
              oldnum = match
              
              newnum = Replace(match, NextNum, Left(firstNum, 2) + NextNum)
            End If
            
          
            
            Case 3
            If CInt(Right(firstNum, Len(firstNum) - 1)) < CInt(NextNum) Then
              oldnum = match
              
              newnum = Replace(match, NextNum, Left(firstNum, 1) + NextNum)
            End If
            
            End Select
            
          Case 5
            
            Select Case Len(NextNum)
            
            Case 1
            If CInt(Right(firstNum, Len(firstNum) - 4)) < CInt(NextNum) Then
              oldnum = match
              
              newnum = Replace(match, NextNum, Left(firstNum, 4) + NextNum)
            End If
            
            Case 2
            If CInt(Right(firstNum, Len(firstNum) - 3)) < CInt(NextNum) Then
              oldnum = match
              
              newnum = Replace(match, NextNum, Left(firstNum, 3) + NextNum)
            End If
            
          
            
            Case 3
            If CInt(Right(firstNum, Len(firstNum) - 2)) < CInt(NextNum) Then
              oldnum = match
              
              newnum = Replace(match, NextNum, Left(firstNum, 2) + NextNum)
            End If
            
            Case 4
            If CInt(Right(firstNum, Len(firstNum) - 1)) < CInt(NextNum) Then
              oldnum = match
              
              newnum = Replace(match, NextNum, Left(firstNum, 1) + NextNum)
            End If
            
            End Select
  
          End Select
        
      Next
    End If
    
    ComLackPage = Replace(Replace(str, oldnum, newnum), "-", "–")
End Function

text Полезныессылки

links
CoreData

1. https://cocoacasts.com/managing-records-with-fetched-results-controllers

text Git命令

git.txt
Clone repo
git clone https://Bhavesh_iblazing@bitbucket.org/Bhavesh_iblazing/shobash.git

Checkout branch
git fetch && git checkout xmpp

text 身份服务器4

identity server 4
*******in server**********

config.cs

public class Config
{
    private readonly IConfiguration _configuration;

    public Config(IConfiguration configuration)
    {
        _configuration = configuration;
    }
    // scopes define the resources in your system
    public IEnumerable<IdentityResource> GetIdentityResources()
    {
        return new List<IdentityResource>
        {
            new IdentityResources.OpenId(),
            new IdentityResources.Profile(),
        };
    }

    public IEnumerable<ApiResource> GetApiResources(string companyCode, bool isTest)
    {

        return new List<ApiResource>
        {
            new ApiResource(){
                Name = "APIServiceHUB",
                ApiSecrets =
                {
                    new Secret(GetSecret(companyCode, isTest).Sha256())
                },
                Scopes =
                {
                    new Scope()
                    {
                        Name = "APIServiceHUB",
                        DisplayName = "APIService HUB",
                    }
                }
            },

            new ApiResource("projects-api", "Projects API")
        };
    }

    // clients want to access resources (aka scopes)
    public IEnumerable<Client> GetClients(string companyCode, bool isTest)
    {
        var optionsBuilder = new DbContextOptionsBuilder<DickerDataContext>();
        DickerDataContext dickerDataContext = new DickerDataContext(optionsBuilder.Options);
        // client credentials client
        return new List<Client>
        {
            new Client
            {
                ClientId = "client",
                AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,
                ClientName =  "APIService HUB",
                RedirectUris = new List<string>{ "http://dev-webservices.dickerdata.com.au/signin-oidc" },
                RequireConsent = false,
                AllowOfflineAccess = true,
                //Access token life time is 14400 seconds (4 hours)
                AccessTokenLifetime = 14400,
                //Identity token life time is 14400 seconds (4 hours)
                IdentityTokenLifetime = 14400,
                ClientSecrets =
                {
                    new Secret(GetSecret(companyCode, isTest).Sha256())
                },
                AllowedScopes =
                {
                    "APIServiceHUB"
                }
            },


            // OpenID Connect implicit flow client (MVC)
            new Client
            {
                ClientId = "mvc",
                ClientName = "MVC Client",
                AllowedGrantTypes = GrantTypes.Implicit,

                RedirectUris = { "http://localhost:60948/signin-oidc" },
                PostLogoutRedirectUris = { "http://localhost:60948/signout-callback-oidc" },

                AllowedScopes =
                {
                    IdentityServerConstants.StandardScopes.OpenId,
                    IdentityServerConstants.StandardScopes.Profile
                }
            }
        };
    }

    private string GetSecret(string companyCode, bool isTest)
    {
        var optionsBuilder = new DbContextOptionsBuilder<DickerDataContext>();
        optionsBuilder.UseSqlServer(_configuration.GetConnectionString("DickerDataConString"));
        DickerDataContext dickerDataContext = new DickerDataContext(optionsBuilder.Options);
        string secret = dickerDataContext.SiteConfig.Where(x => x.Vendor == "SERVICEHUB" && x.CompanyCode == companyCode && (x.IsTest ?? false) == isTest).FirstOrDefault().Value;
        return secret;
    }
}

in startup.cs

services.AddIdentityServer()
  .AddDeveloperSigningCredential()
  .AddInMemoryApiResources(Config.GetApiResources())
  .AddInMemoryClients(Config.GetClients());


in Service file

public TokenModelResponse GetToken(string clientId, string secret)
{
    string url = _dBManager.GetURL(APIList.SH_DD_Token);
    TokenModel inputModel = new TokenModel()
    {
        ClientId = clientId,
        Secret = secret
    };
    var token = ServiceHubJsonExtractor.GetJsonResult<TokenModelResponse>("http://localhost:51678/api/Token/Authenticate", WebMethods.GET, inputModel, null, null);
    return token;
}

public class ServiceHubJsonExtractor
{
    public static T GetJsonResult<T>(string baseUrl, WebMethods method, 
                                    dynamic queryParameters = null, 
                                    dynamic bodyContent = null, 
                                    dynamic token = null, 
                                    string contentType = "application/json") where T : new()
    {
        string url = string.Empty;
        if (queryParameters != null)
        {
            url = BuildUrl(baseUrl, queryParameters);
        }
        else
        {
            url = baseUrl;
        }
        var request = (HttpWebRequest)HttpWebRequest.Create(url);

        request.Accept = "application/json";
        request.Method = method.ToString();
        request.ContentType = contentType;

        if (token != null)
        {
            request.Headers.Add("Authorization", $"{token.Token_Type} {token.Access_Token}");
        }

        var settings = new JsonSerializerSettings
        {
            PreserveReferencesHandling = PreserveReferencesHandling.Objects,
            Converters = { new JsonExtractor.StringOrArrayConverter() },
            Error = (sender, args) =>
            {
                if (System.Diagnostics.Debugger.IsAttached)
                {
                    System.Diagnostics.Debug.Write(args.CurrentObject.ToString());
                    System.Diagnostics.Debugger.Break();
                }
            }
        };

        try
        {
            if (bodyContent != null)
            {
                string contentString = string.Empty;
                if (bodyContent is String)
                {
                    contentString = bodyContent;
                }
                else
                {
                    contentString = JsonConvert.SerializeObject(bodyContent);
                }
                using (var writer = new StreamWriter(request.GetRequestStream()))
                {
                    writer.Write(contentString);
                }
            }
            var response = request.GetResponse();
            using (var reader = new StreamReader(response.GetResponseStream()))
            {
                var responseContent = reader.ReadToEnd();

                var result = new T();

                try
                {
                    if (!string.IsNullOrWhiteSpace(responseContent))
                        result = JsonConvert.DeserializeObject<T>(responseContent, settings);
                }
                catch (Exception ex)
                {
                    throw ex;
                }
                return result;

            }
        }
        catch (WebException webException)
        {
            string error = string.Empty;
            try
            {
                var errroResponse = new StreamReader(webException.Response.GetResponseStream());
                error = errroResponse.ReadToEnd();
            }
            catch
            {
                throw webException;
            }

            throw new Exception(error);

        }
    }

    private static string BuildUrl(string baseUrl, dynamic queryParameters)
    {
        string url = string.Empty, parameterList = string.Empty;
        if (queryParameters != null)
        {
            try
            {
                // the parameters could be dictionary or list

                Type type = queryParameters.GetType();
                if (type.Name == "Dictionary`2" || type.Name == "List`1") // dictionary/list
                {
                    foreach (KeyValuePair<string, string> param in queryParameters)
                    {
                        if (parameterList.Length > 0) parameterList += "&";
                        parameterList += string.Format("{0}={1}", param.Key, param.Value);
                    }
                }
                else // class with properties
                {
                    foreach (PropertyInfo propertyInfo in type.GetProperties())
                    {
                        if (propertyInfo.CanRead)
                        {
                            if (parameterList.Length > 0) parameterList += "&";
                            parameterList += string.Format("{0}={1}", propertyInfo.Name, propertyInfo.GetValue(queryParameters, null));
                        }
                    }
                }
            }
            catch (JsonException jex)
            {
                throw jex;
            }
            catch (Exception ex)
            {
                throw ex;
            }

        }

        if (!string.IsNullOrWhiteSpace(parameterList))
        {
            url = string.Format("{0}?{1}", baseUrl, parameterList);
        }
        else
        {
            url = baseUrl;
        }

        return url;
    }

}


*******in api project********

*******Fetch token from other server:

private async Task<TokenModelResponse> FetchToken(string clientId, string secret)
{
    var disco = await DiscoveryClient.GetAsync("http://localhost:60948");
   
    //var response = new AuthorizeResponse("http://localhost:60948");
    if (disco.IsError)
    {
        Console.WriteLine(disco.Error);
        return new TokenModelResponse { Message = "Fail to get token from server" };
    }
    // request token
    var tokenClient = new TokenClient(disco.TokenEndpoint, clientId, secret);
    var tokenResponse = await tokenClient.RequestClientCredentialsAsync("APIServiceHUB");
    if (tokenResponse.IsError)
    {
        Console.WriteLine(tokenResponse.Error);
        return new TokenModelResponse { Message = "Fail to get token from server" };
    }
    var introspectionClient = new IntrospectionClient(
        disco.IntrospectionEndpoint,
        "APIServiceHUB",
        secret);
    var introspectionResponse = await introspectionClient.SendAsync(
                        new IntrospectionRequest { Token = tokenResponse.AccessToken });
    if (introspectionResponse.IsError)
    {
        Console.WriteLine(introspectionResponse.Error);
        return new TokenModelResponse { Message = "Fail to get token from server" };
    }
    TokenModelResponse tokenModelResponse = new TokenModelResponse();
    tokenModelResponse.Access_Token = tokenResponse.AccessToken;
    tokenModelResponse.Token_Type = tokenResponse.TokenType;
    tokenModelResponse.Expires_In = tokenResponse.ExpiresIn;
    tokenModelResponse.Issured = ToDateTimeFromEpoch(long.Parse(introspectionResponse.Json.GetValue("nbf").ToString())).ToString("r");
    tokenModelResponse.Expires = ToDateTimeFromEpoch(long.Parse(introspectionResponse.Json.GetValue("exp").ToString())).ToString("r");
    tokenModelResponse.Message = "Successfully get token";
    return tokenModelResponse;
}

private DateTime ToDateTimeFromEpoch(long intDate)
{
    var timeInTicks = intDate * TimeSpan.TicksPerSecond;
    return new DateTime(1970, 1, 1, 10, 0, 0, 0, DateTimeKind.Local).AddTicks(timeInTicks);
}

[HttpGet]
public async Task<IHttpActionResult> Authenticate() // controller method to get token
{
    var loginResponse = new LoginResponse { };
    //LoginRequest loginrequest = new LoginRequest { };
    //loginrequest.Username = login.Username.ToLower();
    //loginrequest.Password = login.Password;

    IHttpActionResult response;
    HttpResponseMessage responseMsg = new HttpResponseMessage();
    bool isUsernamePasswordValid = true;

    //if(login != null)
    //isUsernamePasswordValid=loginrequest.Password=="admin" ? true:false;
    // if credentials are valid
    if (isUsernamePasswordValid)
    {
        string token = await FetchToken();
        //return the token
        return Ok(token);
    }
    else
    {
        // if credentials are not valid send unauthorized status code in response
        loginResponse.responseMsg.StatusCode = HttpStatusCode.Unauthorized;
        response = ResponseMessage(loginResponse.responseMsg);
        return response;
    }
}

*******login response model

public class TokenModel
{
    public string ClientId { get; set; }
    public string Secret { get; set; }
}
public class LoginRequest
{
    public string Username { get; set; }
    public string Password { get; set; }
}

public class LoginResponse
{
    public LoginResponse()
    {

        this.Token = "";
        this.responseMsg = new HttpResponseMessage() { StatusCode = System.Net.HttpStatusCode.Unauthorized };
    }

    public string Token { get; set; }
    public HttpResponseMessage responseMsg { get; set; }

}

public class TokenModelResponse
{
    public string Access_Token { get; set; }
    public string Token_Type { get; set; }
    public long Expires_In { get; set; }
    public string UserName { get; set; }
    public string FullName { get; set; }
    public string Logo { get; set; }
    public string ChannelPortalId { get; set; }
    public string Permissions { get; set; }
    public string WorkflowUserGroup { get; set; }
    public string LogonId { get; set; }
    public string Issured { get; set; }
    public string Expires { get; set; }
}

*******validate token:

using IdentityModel;
using IdentityModel.Client;
using Microsoft.IdentityModel.Protocols;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Threading.Tasks;
using System.Web;

internal class TokenValidationHandler : DelegatingHandler
{
    const string auth0Domain = "http://localhost:50191/";
    private static bool TryRetrieveToken(HttpRequestMessage request, out string token)
    {
        token = null;
        IEnumerable<string> authzHeaders;
        if (!request.Headers.TryGetValues("Authorization", out authzHeaders) || authzHeaders.Count() > 1)
        {
            return false;
        }
        var bearerToken = authzHeaders.ElementAt(0);
        token = bearerToken.StartsWith("Bearer ") ? bearerToken.Substring(7) : bearerToken;
        return true;
    }

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        HttpStatusCode statusCode;
        string token;
        //determine whether a jwt exists or not
        if (!TryRetrieveToken(request, out token))
        {
            statusCode = HttpStatusCode.Unauthorized;
            //allow requests with no token - whether a action method needs an authentication can be set with the claimsauthorization attribute
            return await base.SendAsync(request, cancellationToken);
        }

        try
        {
            //const string sec = "401b09eab3c013d4ca54922bb802bec8fd5318192b0a75f201d8b3727429090fb337591abd3e44453b954555b7a0812e1081c39b740293f765eae731f5a65ed1";
            //var now = DateTime.UtcNow;
            //var securityKey = new SymmetricSecurityKey(System.Text.Encoding.Default.GetBytes(sec));
            SecurityToken securityToken;
            JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler();
            handler.InboundClaimTypeMap.Clear();
            var disco = await DiscoveryClient.GetAsync("http://localhost:60948");
            var keylist = new List<SecurityKey>();
            foreach (var webKey in disco.KeySet.Keys)
            {
                var exp = Base64Url.Decode(webKey.E);
                var mod = Base64Url.Decode(webKey.N);
                var key = new RsaSecurityKey(new RSAParameters() { Modulus = mod, Exponent = exp });
                keylist.Add(key);
            }
            TokenValidationParameters validationParameters = new TokenValidationParameters()
            {
                ValidAudience = "http://localhost:60948/resources",
                ValidIssuer = "http://localhost:60948",
                ValidateLifetime = true,
                ValidateIssuerSigningKey = true,
                LifetimeValidator = this.LifetimeValidator,
                IssuerSigningKeys = keylist
            };

            //extract and assign the user of the jwt
            Thread.CurrentPrincipal = handler.ValidateToken(token, validationParameters, out securityToken);
            HttpContext.Current.User = handler.ValidateToken(token, validationParameters, out securityToken);

            return await base.SendAsync(request, cancellationToken);
        }
        catch (SecurityTokenValidationException e)
        {
            statusCode = HttpStatusCode.Unauthorized;
        }
        catch (Exception ex)
        {
            statusCode = HttpStatusCode.InternalServerError;
        }
        return await Task<HttpResponseMessage>.Factory.StartNew(() => new HttpResponseMessage(statusCode) { });
    }

    public bool LifetimeValidator(DateTime? notBefore, DateTime? expires, SecurityToken securityToken, TokenValidationParameters validationParameters)
    {
        if (expires != null)
        {
            if (DateTime.UtcNow < expires) return true;
        }
        return false;
    }

    private async Task<OpenIdConnectConfiguration> GetSigningKeys()
    {
        IConfigurationManager<OpenIdConnectConfiguration> configurationManager = new ConfigurationManager<OpenIdConnectConfiguration>($"{auth0Domain}.well-known/openid-configuration", new OpenIdConnectConfigurationRetriever());
        OpenIdConnectConfiguration openIdConfig = await configurationManager.GetConfigurationAsync(CancellationToken.None);
        return openIdConfig;
    }
}

********API controller

add [Authorize] to controller class


_________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________



*******create token and validate************

private string createToken(string username)
{
    //Set issued at date
    DateTime issuedAt = DateTime.UtcNow;
    //set the time when it expires
    DateTime expires = DateTime.UtcNow.AddDays(7);

    //http://stackoverflow.com/questions/18223868/how-to-encrypt-jwt-security-token
    var tokenHandler = new JwtSecurityTokenHandler();

    //create a identity and add claims to the user which we want to log in
    ClaimsIdentity claimsIdentity = new ClaimsIdentity(new[]
    {
        new Claim(ClaimTypes.Name, username)
    });

    const string sec = "401b09eab3c013d4ca54922bb802bec8fd5318192b0a75f201d8b3727429090fb337591abd3e44453b954555b7a0812e1081c39b740293f765eae731f5a65ed1";
    var now = DateTime.UtcNow;
    var securityKey = new Microsoft.IdentityModel.Tokens.SymmetricSecurityKey(System.Text.Encoding.Default.GetBytes(sec));
    var signingCredentials = new Microsoft.IdentityModel.Tokens.SigningCredentials(securityKey, Microsoft.IdentityModel.Tokens.SecurityAlgorithms.HmacSha256Signature);


    //create the jwt
    var token =
        (JwtSecurityToken)
            tokenHandler.CreateJwtSecurityToken(issuer: "http://localhost:60948", audience: "http://localhost:60948/resources",
                subject: claimsIdentity, notBefore: issuedAt, expires: expires, signingCredentials: signingCredentials);
    var tokenString = tokenHandler.WriteToken(token);

    return tokenString;
}

internal class TokenValidationHandler : DelegatingHandler
{
    private static bool TryRetrieveToken(HttpRequestMessage request, out string token)
    {
        token = null;
        IEnumerable<string> authzHeaders;
        if (!request.Headers.TryGetValues("Authorization", out authzHeaders) || authzHeaders.Count() > 1)
        {
            return false;
        }
        var bearerToken = authzHeaders.ElementAt(0);
        token = bearerToken.StartsWith("Bearer ") ? bearerToken.Substring(7) : bearerToken;
        return true;
    }

    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        HttpStatusCode statusCode;
        string token;
                    //determine whether a jwt exists or not
        if (!TryRetrieveToken(request, out token))
        {
            statusCode = HttpStatusCode.Unauthorized;
            //allow requests with no token - whether a action method needs an authentication can be set with the claimsauthorization attribute
            return base.SendAsync(request, cancellationToken);
        }

        try
        {
            const string sec = "401b09eab3c013d4ca54922bb802bec8fd5318192b0a75f201d8b3727429090fb337591abd3e44453b954555b7a0812e1081c39b740293f765eae731f5a65ed1";
            var now = DateTime.UtcNow;
            var securityKey = new SymmetricSecurityKey(System.Text.Encoding.Default.GetBytes(sec));                


            SecurityToken securityToken;
            JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler();
            TokenValidationParameters validationParameters = new TokenValidationParameters()
            {
                ValidAudience = "http://localhost:50191",
                ValidIssuer = "http://localhost:5001",
                ValidateLifetime = true,
                ValidateIssuerSigningKey = true,
                LifetimeValidator = this.LifetimeValidator,                    
                IssuerSigningKey = securityKey                
            };
            //extract and assign the user of the jwt
            Thread.CurrentPrincipal = handler.ValidateToken(token, validationParameters, out securityToken);
            HttpContext.Current.User = handler.ValidateToken(token, validationParameters, out securityToken);

            return base.SendAsync(request, cancellationToken);
        }
        catch (SecurityTokenValidationException e)
        {
            statusCode = HttpStatusCode.Unauthorized;
        }
        catch (Exception ex)
        {
            statusCode = HttpStatusCode.InternalServerError;
        }
        return Task<HttpResponseMessage>.Factory.StartNew(() => new HttpResponseMessage(statusCode){ });
    }

    public bool LifetimeValidator(DateTime? notBefore, DateTime? expires, SecurityToken securityToken, TokenValidationParameters validationParameters)
    {
        if (expires != null)
        {
            if (DateTime.UtcNow < expires) return true;
        }
        return false;
    }

    
}

text 关于文化和本土化

将日期转换为字符串,将字符串转换为日期,将数字转换为字符串

note
DATE
=================================================
--- js
formatDateTime(CreatedOnUTC)

CONVERT Numeric to String sesuai culture
=================================================
-- cshtml
@Html.DecimalTextBox("HiddenPriceTextBox", "0", null, new { @style="display:none" })
<input decimalplaces="0" decimalseparator="," id="HiddenPriceTextBox" name="HiddenPriceTextBox" onblur="formatNumeric(this, '', false);" ondblclick="highlight(this);" onfocus="preformatNumeric(this);" onkeydown="keyCheck(event);" onkeyup="filterNumeric(this, '', false, false, false);" style="display:none" thousandsseparator="." type="text" value="0">
-- js
$("#CostPrice").val(formatNumericFromNumber("HiddenPriceTextBox", item.CostPrice));

CONVERT string to numeric
=================================================
--- js
convertStringToNumeric("DiscountPrice", self.finalCostPrice())
globalThousandsSeparator
globalDecimalSeparator
 toNumeric(finalProfitPercent, globalThousandsSeparator, globalDecimalSeparator, 2, false, null, true);
--- cs
decimalVariable.FormatNumeric()

C#
===================================================
 decimal newFinalCostPriceDecimal = Convert.ToDecimal(newFinalCostPrice, new CultureInfo("en-US"));
 
 Convert decimal ke string currency
 ---
 CultureInfo cultureInfo = CultureInfo.CurrentCulture;
  StringBuilder sbStringFormat = new StringBuilder("##,#");
  int decimalPlace = applicationSettingRepository.GetApplicationSettingByte(ApplicationSettingTypeEnum.NumberOfDecimalPlaces);
  if (decimalPlace > 0)
  {
      sbStringFormat.Append(".");
      for (int i = 0; i < decimalPlace; i++)
      {
          sbStringFormat.Append("0");
      }
  }
  string stringFormat = sbStringFormat.ToString();
  
  product.Price.ToString(stringFormat, cultureInfo) //decimalValue.toString()