2017年6月9日 星期五

JSON 資料轉換

1
2
JObject json = JObject.Parse(jsonstring);
MyObject myobj = json.ToObject<MyObject>());

MVC 接收 POST 字串資料

1
2
3
Request.InputStream.Seek(0, SeekOrigin.Begin);
string jsonData = new StreamReader(Request.InputStream).ReadToEnd();
string tmp = HttpUtility.UrlDecode(jsonData);

2017年2月17日 星期五

Linq Join 方式

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// linq 正規 Join 方式
DataTable dt = (from l in db.Log
                    join u in db.User on l.InsertUserId equals u.Id into lu
                from j1 in lu.DefaultIfEmpty()
                    join i in db.Item on l.ItemId equals i.Id into li
                from j2 in li.DefaultIfEmpty()
                join it in db.ItemType on j2.ItemTypeId equals it.Id
                select new
                {
                    Id = l.Id,
                    日期 = l.Date,
                    項目 = it.ItemTypeName + "-" + j2.ItemName,
                    價格 = l.Price,
                    人員 = j1.UserName,
                }
).ToDataTable();

// linq 非正規 Join 方式
DataTable dt = (
    from l in db.Log
    from u in db.User
    from i in db.Item
    from it in db.ItemType
    where 1 == 1
    && l.InsertUserId == u.Id
    && l.ItemId == i.Id
    && i.ItemTypeId == it.Id
    && (i.ItemName.Contains(Query) || it.ItemTypeName.Contains(Query))
    select new
    {
        Id = l.Id,
        日期 = l.Date,
        項目 = it.ItemTypeName + "-" + i.ItemName,
        價格 = l.Price,
        人員 = u.UserName,
    }
).ToDataTable();

EventHandler 自訂事件

UserControl1.cs
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public partial class UserControl1 : UserControl
{
    /// <summary>
    /// 建立事件處理
    /// </summary>
    new public event EventHandler TextChanged;
        
    /// <summary>
    /// 事件處理函數
    /// </summary>
    protected void OnTextChanged()
    {
        // 如果有建立事件監聽,則Invoke
        TextChanged?.Invoke(this.textBox1, new EventArgs());
    }
    public UserControl1()
    {
        InitializeComponent();
    }

    /// <summary>
    /// 使用者控制項 的 TextBox 預設 TextChanged 事件
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void textBox1_TextChanged(object sender, EventArgs e)
    {
        OnTextChanged();
    }
}


Form1.cs
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        // 針對使用者控制項新增自訂的 TextChanged 事件
        this.userControl11.TextChanged += UserControl11_TextChanged;
    }

    /// <summary>
    /// 使用者控制項新增自訂的 TextChanged 事件處理函數
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void UserControl11_TextChanged(object sender, EventArgs e)
    {
        if (sender is TextBox)
        {
            TextBox tb = sender as TextBox;
            label1.Text = tb.Text;
        }
    }
}

2016年6月30日 星期四

使用擴充方法將Linq資料集合轉成DataTable

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
static class IQueryableExtension
{
    public static DataTable ToDataTable<T>(this IQueryable<T> data)
    {
        PropertyDescriptorCollection properties =
            TypeDescriptor.GetProperties(typeof(T));
        DataTable table = new DataTable();
        foreach (PropertyDescriptor prop in properties)
            table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
        foreach (T item in data)
        {
            DataRow row = table.NewRow();
            foreach (PropertyDescriptor prop in properties)
                row[prop.Name] = prop.GetValue(item) ?? DBNull.Value;
            table.Rows.Add(row);
        }
        return table;
    }
}

遠端資料夾、網路芳鄰存取檔案

網路上別人寫好的遠端資料夾、網路芳鄰存取檔案的程式碼

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
namespace MyNameSpace
{

    #region Using directives.
    // ----------------------------------------------------------------------

    using System;
    using System.Security.Principal;
    using System.Runtime.InteropServices;
    using System.ComponentModel;

    // ----------------------------------------------------------------------
    #endregion

    /////////////////////////////////////////////////////////////////////////

    /// <summary>
    /// Impersonation of a user. Allows to execute code under another
    /// user context.
    /// Please note that the account that instantiates the Impersonator class
    /// needs to have the 'Act as part of operating system' privilege set.
    /// </summary>
    /// <remarks> 
    /// This class is based on the information in the Microsoft knowledge base
    /// article http://support.microsoft.com/default.aspx?scid=kb;en-us;Q306158
    /// 
    /// Encapsulate an instance into a using-directive like e.g.:
    /// 
    /// ...
    /// using ( new Impersonator( "myUsername", "myDomainname", "myPassword" ) )
    /// {
    /// ...
    /// [code that executes under the new context]
    /// ...
    /// }
    /// ...
    /// 
    /// Please contact the author Uwe Keim (mailto:uwe.keim@zeta-software.de)
    /// for questions regarding this class.
    /// </remarks>
    public class Impersonator :
        IDisposable
    {
        #region Public methods.
        // ------------------------------------------------------------------

        /// <summary>
        /// Constructor. Starts the impersonation with the given credentials.
        /// Please note that the account that instantiates the Impersonator class
        /// needs to have the 'Act as part of operating system' privilege set.
        /// </summary>
        /// <param name="userName">The name of the user to act as.</param>
        /// <param name="domainName">The domain name of the user to act as.</param>
        /// <param name="password">The password of the user to act as.</param>
        public Impersonator(
            string userName,
            string domainName,
            string password)
        {
            ImpersonateValidUser(userName, domainName, password);
        }

        // ------------------------------------------------------------------
        #endregion

        #region IDisposable member.
        // ------------------------------------------------------------------

        public void Dispose()
        {
            UndoImpersonation();
        }

        // ------------------------------------------------------------------
        #endregion

        #region P/Invoke.
        // ------------------------------------------------------------------

        [DllImport("advapi32.dll", SetLastError = true)]
        private static extern int LogonUser(
            string lpszUserName,
            string lpszDomain,
            string lpszPassword,
            int dwLogonType,
            int dwLogonProvider,
            ref IntPtr phToken);

        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern int DuplicateToken(
            IntPtr hToken,
            int impersonationLevel,
            ref IntPtr hNewToken);

        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern bool RevertToSelf();

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        private static extern bool CloseHandle(
            IntPtr handle);

        private const int LOGON32_LOGON_INTERACTIVE = 2;
        private const int LOGON32_PROVIDER_DEFAULT = 0;
        private const int LOGON32_LOGON_NETWORK = 3;
        private const int LOGON32_LOGON_BATCH = 4;
        private const int LOGON32_LOGON_SERVICE = 5;
        private const int LOGON32_LOGON_UNLOCK = 7;
        private const int LOGON32_LOGON_NETWORK_CLEARTEXT = 8; // Only for Win2K or higher 
        private const int LOGON32_LOGON_NEW_CREDENTIALS = 9; // Only for Win2K or higher 


        // ------------------------------------------------------------------
        #endregion

        #region Private member.
        // ------------------------------------------------------------------

        /// <summary>
        /// Does the actual impersonation.
        /// </summary>
        /// <param name="userName">The name of the user to act as.</param>
        /// <param name="domainName">The domain name of the user to act as.</param>
        /// <param name="password">The password of the user to act as.</param>
        private void ImpersonateValidUser(
            string userName,
            string domain,
            string password)
        {
            WindowsIdentity tempWindowsIdentity = null;
            IntPtr token = IntPtr.Zero;
            IntPtr tokenDuplicate = IntPtr.Zero;

            try
            {
                if (RevertToSelf())
                {//LOGON32_LOGON_NETWORK_CLEARTEXT通常是在Server為了配合多平台的檔案寫入(例如:linux)
                    //才會用這個降低安全性的選項,讓server允許直接帳號密碼登入並且寫入檔案系統
                    //LOGON32_LOGON_NEW_CREDENTIALS才是一般server會採用的安全性作法,使用者需利用帳密取得一組credential
                    //再用credential去登入server, 方可寫入server的檔案系統
                    //完整的LogonType解釋詳見msdn
                    //https://msdn.microsoft.com/en-us/library/windows/desktop/aa378184(v=vs.85).aspx
                    //Server的這個設定在 程式集=>系統管理工具=>本機安全性原則裡面,此設定為進階設定,非mis人員通常很少設定他
                    if (LogonUser(
                        userName,
                        domain,
                        password,
                        LOGON32_LOGON_NEW_CREDENTIALS,
                        LOGON32_PROVIDER_DEFAULT,
                        ref token) != 0)
                    {
                        if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
                        {
                            tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
                            impersonationContext = tempWindowsIdentity.Impersonate();
                        }
                        else
                        {
                            throw new Win32Exception(Marshal.GetLastWin32Error());
                        }
                    }
                    else
                    {
                        throw new Win32Exception(Marshal.GetLastWin32Error());
                    }
                }
                else
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }
            }
            finally
            {
                if (token != IntPtr.Zero)
                {
                    CloseHandle(token);
                }
                if (tokenDuplicate != IntPtr.Zero)
                {
                    CloseHandle(tokenDuplicate);
                }
            }
        }

        /// <summary>
        /// Reverts the impersonation.
        /// </summary>
        private void UndoImpersonation()
        {
            if (impersonationContext != null)
            {
                impersonationContext.Undo();
            }
        }

        private WindowsImpersonationContext impersonationContext = null;

        // ------------------------------------------------------------------
        #endregion
    }

    /////////////////////////////////////////////////////////////////////////
}

使用方法:
1
2
3
4
5
6
7
8
string remotePath = @"\\RemoteIP\\Folder\\";
using (new Impersonator("yourUserName", "yourDomainName","yourPassword"))
{

 string[] Files = Directory.GetFiles(remotePath);

 File.Copy("localFile", "remoteFile", true);
}

參考資料:[.net]程式碼如何寫入網芳、網路磁碟、網路硬碟