2019年8月8日木曜日

[パワポマン]パワポマンコレクション【工場の人】

使い勝手が良くてコレクション&独自作成している廃止されたパワポマン画像

その2.工場の人








2019年7月29日月曜日

[パワポマン]パワポマンコレクション【サラリーマン】

使い勝手が良くてコレクション&独自作成している廃止されたパワポマン画像

その1.サラリーマン








[C#]LINEWORKS用のJWT認証を行ってメッセージを送る

そのものズバリな記事がなかったので、作成。
C#のLINEのチャットbotの作り方はありますけどLINE WORKSはまだまだ全然ない…
そもそもC#でLINE WORKS作る人少なそう…

①ー1 まずはLINEWORKSとの連携に必要な値の設定
以下の様に値を宣言します。
LINE WORKS Developersで設定した値をセットします。

static int botNo = 9999;
static string apiId = "kfew******Oy";
static string serverId = "afei*******24239e";
static string consumerKey = "WOpe*******elK";
static string privateKey = "-----BEGIN PRIVATE KEY-----MAIEvA******JZhJIZ=-----END PRIVATE KEY-----";

serverId …ServerList(ID固定タイプ)のIDをセット
consumerKey …ServerApiConsumerKeyをセット
privateKey ServerList(ID固定タイプ)の認証キーを1行につなげます。


②ー1 JWT認証を使ってアクセストークンの取得(準備)


Pemキー(privatekey)を.NETで扱うのは難しく、RSAとして使用するには一度xmlに変換しないといけないらしい…これがつらかった。
これを解消する為に、Nugetで「opensslkey」を追加しておきます
(OpensslKey.csというプログラムが出来るだけ)

②ー2 JWT認証を使ってアクセストークンの取得(関数)


OpensslKeyを使って以下の関数を作ります。これでアクセストークンが取得できます。


public string GetAccessToken()
        {
            //JWTトークンの作成=======================================================
            string request_jwt = null;
            //privatekeyRSAとして使用できるように変換
            var pkcs8privatekey = Security.opensslkey.DecodePkcs8PrivateKey(privateKey); 
            var rsa = Security.opensslkey.DecodePrivateKeyInfo(pkcs8privatekey);  
            var key = new Microsoft.IdentityModel.Tokens.RsaSecurityKey(rsa);
            // トークン操作用のクラスを用意
            var handler = new System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler();
            // 署名情報クラスを生成
            var credentials = new Microsoft.IdentityModel.Tokens.SigningCredentials(key, "RS256");
            var descriptor = new Microsoft.IdentityModel.Tokens.SecurityTokenDescriptor
            {
                Issuer = serverId,
                SigningCredentials = credentials,
                IssuedAt = DateTime.UtcNow,
                Expires = (DateTime.UtcNow).AddMinutes(10),
            };
            // トークンの生成
            var token = handler.CreateJwtSecurityToken(descriptor);
            // トークンの文字列表現を取得
            var tokenString = handler.WriteToken(token);


            //アクセストークンの取得=======================================================
            //認証URL
            string TOKEN_ENDPOINT = @"https://auth.worksmobile.com/b/" + apiId + "/server/token";
            var client = new WebClient();
            client.Encoding = Encoding.UTF8;
            var content = new NameValueCollection();
            request_jwt = tokenString;
            content["assertion"] = request_jwt;
            content["grant_type"] = "urn:ietf:params:oauth:grant-type:jwt-bearer";
            string response = Encoding.UTF8.GetString(client.UploadValues(TOKEN_ENDPOINT, "POST", content));
            var result = JsonConvert.DeserializeObject<Token>(response);           
            return result.AccessToken;
        }






③ー1 送信してみる
content(内容)は省きますが、以下の様に行えば実際に送信できます。


//(obj_contentは各自でModelを作って作成)
 string jsonRequest = JsonConvert.SerializeObject(obj_content);

 StringContent content = new StringContent(jsonRequest);
 content.Headers.ContentType = new MediaTypeHeaderValue("application/json");

 HttpClient client = new HttpClient(); 
 var url = "https://apis.worksmobile.com/"apiId + "/message/sendMessage/v2";
 var token = GetAccessToken();
 var request = new HttpRequestMessage(HttpMethod.Post, url);
 request.Headers.Add("ContentType", "application/json");
 request.Headers.Add("Authorization", "Bearer " + token);
 request.Headers.Add(@"consumerKey", @""consumerKey );

 request.Content = content;
 var response = await client.SendAsync(request);

 //string responseContent = await response.Content.ReadAsStringAsync();




2019年2月15日金曜日

[.NET]コード内Enumだけで宣言したデータでドロップダウンの候補をセット

オリジナルのドロップダウンを作成する場合、宣言部だけで使いまわしたい…
ということで以下。

①Enum宣言
----------------------------------------------

public enum enumHito : byte
 {
            [Display(Name = "太郎")]
            Tarou = 12334,
            [Display(Name = "花子")]
            Hanako = 19483,
}

----------------------------------------------
②宣言したEnumから属性:NameをGetする共通関数を作成しておく。

----------------------------------------------

//属性:Nameを取得
public static class GetAttribute
    {
        public static string Name(object obj)
        {
            var fieldInfo = obj.GetType().GetField(obj.ToString());
            var descriptionAttributes = fieldInfo.GetCustomAttributes(typeof(DisplayAttribute), false) as DisplayAttribute[];
            if (descriptionAttributes != null && descriptionAttributes.Length > 0)
            {
                return descriptionAttributes[0].Name;
            }
            else
            {
                return string.Empty;
            }
        }

    }
----------------------------------------------

③②を使って①情報からドロップダウン候補をデータバインドする。

----------------------------------------------
var data = new List<Tuple<int, string>>();
foreach (enumKenaskuShubetsu row in Enum.GetValues(typeof(enumHito)))
{
  data.Add(new Tuple<int, string>((int)row, GetAttribute.Name(row)));
}
ddlhoge.DataValueField = "item1";
ddlhoge.DataTextField = "item2";
ddlhoge.DataSource = data;

ddlhoge.DataBind();

----------------------------------------------

[.NET]オブジェクト内に同じプロパティがあった場合、同じ値をセットする

①以下のような関数を作成。
------------------------------------------------

/// <summary>
/// 同じプロパティから同じ値をセットします
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="self"></param>
/// <param name="Frommodel"></param>
public static void CopyFromSameProperty<T>(this T self, object Frommodel, List<string> Lstexcept = null)
        {
            PropertyInfo[] propertyInfo = Frommodel.GetType().GetProperties();
            foreach (PropertyInfo p in propertyInfo)
            {
                if (Lstexcept != null && Lstexcept.Contains(p.Name)){ continue; }

                //コピー元
                var arg = p.GetValue(Frommodel, null);
                //コピー先
                PropertyInfo pTo = self.GetType().GetProperty(p.Name);
                if (pTo != null)
                {
                    pTo.SetValue(self, arg);
                }

            }
}
------------------------------------------------
②使い方は以下。
------------------------------------------------
// ベースとなる行
var baseRow = db.T_hoge.Where(d => d.番号 == 1234).FirstOrDefault();
var newRow = new T_hoge();

newRow.CopyFromSameProperty(baseRow); //一度全項目コピーする
------------------------------------------------

※「このプロパティはコピーしたくない!」というものがあるならば
 以下の様にプロパティ名を指定すればOK
newRow.CopyFromSameProperty(baseRow, new List<string> { "番号" }); //一度全項目コピーする