多级反向代理下,C#获取请求客户端的真实IP地址的方法.

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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.NetworkInformation;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace RfSoft.MapleTr.Framework.Core.Utilities
{
public sealed class RequestHelper
{
/// <summary>
/// 获取客户端IP地址
/// </summary>
public static string ClientIP
{
get
{
var request = HttpContext.Current.Request;


String ipAddress = request.Headers.Get("x-forwarded-for");
if (ipAddress == null || ipAddress.Length == 0 || "unknown".Equals(ipAddress, StringComparison.InvariantCultureIgnoreCase))
{
ipAddress = request.Headers.Get("Proxy-Client-IP");
}
if (ipAddress == null || ipAddress.Length == 0 || "unknown".Equals(ipAddress, StringComparison.InvariantCultureIgnoreCase))
{
ipAddress = request.Headers.Get("WL-Proxy-Client-IP");
}
if (ipAddress == null || ipAddress.Length == 0 || "unknown".Equals(ipAddress, StringComparison.InvariantCultureIgnoreCase))
{
ipAddress = request.UserHostAddress;
if (ipAddress.Equals("127.0.0.1") || ipAddress.Equals("0:0:0:0:0:0:0:1"))
{
//根据网卡取本机配置的IP
NetworkInterface inet = NetworkInterface.GetAllNetworkInterfaces().FirstOrDefault();
try
{
ipAddress = inet.GetIPProperties().WinsServersAddresses.FirstOrDefault().ToString();
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
}
//对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
if (ipAddress != null && ipAddress.Length > 15)
{ //"***.***.***.***".length() = 15
if (ipAddress.IndexOf(",") > 0)
{
ipAddress = ipAddress.Substring(0, ipAddress.IndexOf(","));
}
}
return ipAddress;

//var clientIP = request.Headers.Get("x-forwarded-for");
//if (string.IsNullOrEmpty(clientIP))
//{
// return request.UserHostAddress;
//}
//return clientIP;
}
}
}
}

javascript获取各种高度

1
2
3
4
5
6
7
8
alert($(window).height()); //浏览器当前窗口可视区域高度
alert($(document).height()); //浏览器当前窗口文档的高度
alert($(document.body).height());//浏览器当前窗口文档body的高度
alert($(document.body).outerHeight(true));//浏览器当前窗口文档body的总高度 包括border padding margin
alert($(window).width()); //浏览器当前窗口可视区域宽度
alert($(document).width());//浏览器当前窗口文档对象宽度
alert($(document.body).width());//浏览器当前窗口文档body的高度
alert($(document.body).outerWidth(true));//浏览器当前窗口文档body的总宽度 包括border padding margin

Linq 实现动态查询

  • 直接上代码
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
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;

namespace RfSoft.MapleTr.Controllers.Utilities
{
public static class LinqDynamicQuery
{
/// <summary>
/// Linq动态查询
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="sourceList"></param>
/// <param name="queryConditionList"></param>
/// <param name="orderByConditionList"></param>
/// <returns></returns>
public static IEnumerable<T> GetDataByDynamicQuery<T>(this IEnumerable<T> sourceList, List<QueryCondition> queryConditionList, params OrderByCondition[] orderByConditionList)
{
if (null == sourceList)
{
throw new ArgumentException("数据源不能为空");
}

IQueryable<T> sourceLs = sourceList.AsQueryable();

Expression finalExpr;
Expression filter, totalExpr;
filter = totalExpr = Expression.Constant(true);

ParameterExpression param = Expression.Parameter(typeof(T), "n");
foreach (var item in queryConditionList ?? Enumerable.Empty<QueryCondition>())
{
//反射找出所有查询条件的属性值,如果该查询条件值为空或者null不添加动态lambda表达式
string propertyName = item.ConditionField;
var propertyVal = item.FieldValue;
if (null != propertyVal)
{
propertyVal = propertyVal.Trim();
}
if (!string.IsNullOrEmpty(propertyName) && propertyVal != null && propertyVal.ToString() != string.Empty)
{
//n.property
PropertyInfo property = typeof(T).GetProperty(propertyName);
Expression left = Expression.Property(param, property);
//等式右边的值
Expression right = Expression.Constant(propertyVal);

//当前字段类型
Type propertyType = property.PropertyType;
//对可空数据类型的处理
if (propertyType.IsGenericType)
{
Type genericTypeDefinition = propertyType.GetGenericTypeDefinition();
if (genericTypeDefinition == typeof(Nullable<>))
{
NullableConverter nullableDataType = new NullableConverter(propertyType);
right = Expression.Constant(nullableDataType.ConvertFromString(propertyVal), propertyType);
}
}
else
{
right = Expression.Constant(Convert.ChangeType(propertyVal, propertyType), propertyType);
}

MethodInfo containsmethod;
switch (item.Relation)
{
case RelationFlags.Equal:
if (typeof(string) == property.PropertyType)
{
containsmethod = typeof(string).GetMethod("Equals", new[] { typeof(string), typeof(string), typeof(StringComparison) });

filter = Expression.Call(containsmethod, left, right, Expression.Constant(StringComparison.OrdinalIgnoreCase));
}
else
{
filter = Expression.Equal(left, right);
}
break;
case RelationFlags.NoEqual:
filter = Expression.NotEqual(left, right);
break;
case RelationFlags.GreaterThan:
filter = Expression.GreaterThan(left, right);
break;
case RelationFlags.LessThan:
filter = Expression.LessThan(left, right);
break;
case RelationFlags.GreaterThanOrEqual:
filter = Expression.GreaterThanOrEqual(left, right);
break;
case RelationFlags.LessThanOrEqual:
filter = Expression.LessThanOrEqual(left, right);
break;
case RelationFlags.LikeWildcardBoth:
if (typeof(string) == property.PropertyType)
{
containsmethod = property.PropertyType.GetMethod("Contains", new Type[] { property.PropertyType });
filter = Expression.Call(left, containsmethod, right);
}
else
{
throw new ArgumentException(" 'like %x%' operator work on string type only ");
}
break;
case RelationFlags.LikeLeftWildcardOnly:
if (typeof(string) == property.PropertyType)
{
containsmethod = property.PropertyType.GetMethod("EndsWith", new Type[] { property.PropertyType });
filter = Expression.Call(left, containsmethod, right);
}
else
{
throw new ArgumentException(" 'like %x' operator work on string type only ");
}
break;
case RelationFlags.LikeRightWildcardOnly:
if (typeof(string) == property.PropertyType)
{
containsmethod = property.PropertyType.GetMethod("StartsWith", new Type[] { property.PropertyType });
filter = Expression.Call(left, containsmethod, right);
}
else
{
throw new ArgumentException(" 'like x%' operator work on string type only ");
}
break;
case RelationFlags.In:
Expression rightTmp, filterTmp;
Expression totalExprTmp = Expression.Constant(false);
foreach (var itemValue in propertyVal as IEnumerable ?? Enumerable.Empty<object>())
{
rightTmp = Expression.Constant(itemValue);
if (typeof(string) == property.PropertyType)
{
containsmethod = typeof(string).GetMethod("Equals", new[] { typeof(string), typeof(string), typeof(StringComparison) });
filterTmp = Expression.Call(containsmethod, left, rightTmp, Expression.Constant(StringComparison.OrdinalIgnoreCase));
}
else
{
filterTmp = Expression.Equal(left, rightTmp);
}
totalExprTmp = Expression.Or(filterTmp, totalExprTmp);
}
filter = totalExprTmp = Expression.And(totalExprTmp, Expression.Constant(true));
break;
default:
filter = Expression.Constant(true);
break;
}
switch (item.Condition)
{
case ConditionFlags.And:
totalExpr = Expression.And(totalExpr, filter);
break;
case ConditionFlags.Or:
totalExpr = Expression.Or(totalExpr.NodeType.Equals(Expression.Constant(true).NodeType) ? Expression.Constant(false) : totalExpr, filter);
break;
default:
break;
}
}
}
//Where部分条件
Expression pred = Expression.Lambda(totalExpr, param);
finalExpr = Expression.Call(typeof(Queryable), "Where", new Type[] { typeof(T) }, Expression.Constant(sourceLs), pred);
string orderByFunctionName = "OrderBy";
string orderByDescFunctionName = "OrderByDescending";
foreach (var orderbyCondition in orderByConditionList ?? Enumerable.Empty<OrderByCondition>())
{
PropertyInfo pInfo = typeof(T).GetProperty(orderbyCondition.OrderField);
//OrderBy部分排序
finalExpr = Expression.Call(typeof(Queryable), orderbyCondition.IsDesc ? orderByDescFunctionName : orderByFunctionName, new Type[] { typeof(T), pInfo.PropertyType }, finalExpr, Expression.Lambda(Expression.Property(param, pInfo), param));
orderByFunctionName = "ThenBy";
orderByDescFunctionName = "ThenByDescending";
}

return sourceLs.Provider.CreateQuery<T>(finalExpr);
}
}

public enum ConditionFlags
{
And = 0,
Or = 1,
}

public enum RelationFlags
{
/// <summary>
/// 等于
/// </summary>
Equal = 0,

/// <summary>
/// 不等于
/// </summary>
NoEqual = 1,

/// <summary>
/// 大于
/// </summary>
GreaterThan = 2,

/// <summary>
/// 小于
/// </summary>
LessThan = 3,

/// <summary>
/// 大于等于
/// </summary>
GreaterThanOrEqual = 4,

/// <summary>
/// 小于等于
/// </summary>
LessThanOrEqual = 5,

/// <summary>
/// like "%xxxx%"
/// </summary>
LikeWildcardBoth = 6,

/// <summary>
/// like "%xxx"
/// </summary>
LikeLeftWildcardOnly = 7,

/// <summary>
/// like "xxx%"
/// </summary>
LikeRightWildcardOnly = 8,

/// <summary>
/// 包含,多个值
/// </summary>
In = 9,
}

public class QueryCondition
{
public string ConditionField { get; set; }
public string FieldValue { get; set; }
public ConditionFlags Condition { get; set; }
public RelationFlags Relation { get; set; }
}

public class OrderByCondition
{
public string OrderField { get; set; }
public bool IsDesc { get; set; }
}
}

Oracle 修改用户密码

  • 输入命令sqlplus /nolog ,进入oracle控制台
  • 输入命令 conn /as sysdba; (注意分号)以DBA角色进入
  • 连接成功后,输入“select username from dba_users; ”查看用户列表
  • 修改某一个用户密码、用户口令:alter user 用户名 identified by 新密码;
  • 以system 为例,密码修改为 123456. 可输入:alter user system identified by 123456;

C# 抽象类和接口的区别和应用场景

  • 1.abstract class 在c#语言中表示的是一种继承关系,一个类只能使用一次继承关系。但是,一个类却可以实现多个interface。
  • 2.在abstract class 中可以有自己的数据成员,也可以有非abstarct的成员方法,而在interface中,只能够有静态的不能被修改的数据成员(也就是必须是static final的,不过在 interface中一般不定义数据成员),所有的成员方法都是abstract的。
  • 3.abstract class和interface所反映出的设计理念不同。其实abstract class表示的是”is-a”关系,interface表示的是”like-a”关系。
  • 4.实现抽象类和接口的类必须实现其中的所有方法。抽象类中可以有非抽象方法。接口中则不能有实现方法。
  • 5.接口中定义的变量默认是public static final 型,且必须给其初值,所以实现类中不能重新定义,也不能改变其值。
  • 6.抽象类中的变量默认是 friendly 型,其值可以在子类中重新定义,也可以重新赋值。
  • 7.接口中的方法默认都是 public,abstract 类型的。
shift+ctrl+X 打开脚本输入下方脚本:

'******************************************************************************
'* File:     pdm2excel.txt
'* Title:    pdm export to excel
'* Purpose:  To export the tables and columns to Excel
'* Model:    Physical Data Model
'* Objects:  Table, Column, View
'* Author:   ziyan
'* Created:  2012-05-03
'* Version:  1.0
'******************************************************************************
Option Explicit
   Dim rowsNum
   rowsNum = 0
'-----------------------------------------------------------------------------
' Main function
'-----------------------------------------------------------------------------
' Get the current active model
Dim Model
Set Model = ActiveModel
If (Model Is Nothing) Or (Not Model.IsKindOf(PdPDM.cls_Model)) Then
  MsgBox "The current model is not an PDM model."
Else
 ' Get the tables collection
 '创建EXCEL APP
 dim beginrow
 DIM EXCEL, SHEET
 set EXCEL = CREATEOBJECT("Excel.Application")
 EXCEL.workbooks.add(-4167)'添加工作表
 EXCEL.workbooks(1).sheets(1).name ="test"
 set sheet = EXCEL.workbooks(1).sheets("test")

 ShowProperties Model, SHEET
 EXCEL.visible = true
 '设置列宽和自动换行
 sheet.Columns(1).ColumnWidth = 20 
 sheet.Columns(2).ColumnWidth = 40 
 sheet.Columns(4).ColumnWidth = 20 
 sheet.Columns(5).ColumnWidth = 20 
 sheet.Columns(6).ColumnWidth = 15 
 sheet.Columns(1).WrapText =true
 sheet.Columns(2).WrapText =true
 sheet.Columns(4).WrapText =true
 End If
'-----------------------------------------------------------------------------
' Show properties of tables
'-----------------------------------------------------------------------------
Sub ShowProperties(mdl, sheet)
   ' Show tables of the current model/package
   rowsNum=0
   beginrow = rowsNum+1
   ' For each table
   output "begin"
   Dim tab
   For Each tab In mdl.tables
      ShowTable tab,sheet
   Next
   if mdl.tables.count > 0 then
        sheet.Range("A" & beginrow + 1 & ":A" & rowsNum).Rows.Group
   end if
   output "end"
End Sub
'-----------------------------------------------------------------------------
' Show table properties
'-----------------------------------------------------------------------------
Sub ShowTable(tab, sheet)
   If IsObject(tab) Then
     Dim rangFlag
     rowsNum = rowsNum + 1
      ' Show properties
      Output "================================"
      sheet.cells(rowsNum, 1) = "实体名"
      sheet.cells(rowsNum, 2) =tab.name
      sheet.cells(rowsNum, 3) = ""
      sheet.cells(rowsNum, 4) = "表名"
      sheet.cells(rowsNum, 5) = tab.code
      sheet.Range(sheet.cells(rowsNum, 5),sheet.cells(rowsNum, 6)).Merge
      rowsNum = rowsNum + 1
      sheet.cells(rowsNum, 1) = "属性名"
      sheet.cells(rowsNum, 2) = "说明"
      sheet.cells(rowsNum, 3) = ""
      sheet.cells(rowsNum, 4) = "字段中文名"
      sheet.cells(rowsNum, 5) = "字段名"
      sheet.cells(rowsNum, 6) = "字段类型"
      '设置边框
      sheet.Range(sheet.cells(rowsNum-1, 1),sheet.cells(rowsNum, 2)).Borders.LineStyle = "1"
      sheet.Range(sheet.cells(rowsNum-1, 4),sheet.cells(rowsNum, 6)).Borders.LineStyle = "1"
Dim col ' running column
Dim colsNum
colsNum = 0
      for each col in tab.columns
        rowsNum = rowsNum + 1
        colsNum = colsNum + 1
      sheet.cells(rowsNum, 1) = col.name
      sheet.cells(rowsNum, 2) = col.comment
        sheet.cells(rowsNum, 3) = ""
      sheet.cells(rowsNum, 4) = col.name
      sheet.cells(rowsNum, 5) = col.code
      sheet.cells(rowsNum, 6) = col.datatype
      next
      sheet.Range(sheet.cells(rowsNum-colsNum+1,1),sheet.cells(rowsNum,2)).Borders.LineStyle = "2"       
      sheet.Range(sheet.cells(rowsNum-colsNum+1,4),sheet.cells(rowsNum,6)).Borders.LineStyle = "2"
      rowsNum = rowsNum + 1

      Output "FullDescription: "       + tab.Name
   End If
End Sub

原文链接http://www.cnblogs.com/luxiaoxun/p/3280146.html

一、使用线程的理由

1、可以使用线程将代码同其他代码隔离,提高应用程序的可靠性。

2、可以使用线程来简化编码。

3、可以使用线程来实现并发执行。

二、基本知识

1、进程与线程:进程作为操作系统执行程序的基本单位,拥有应用程序的资源,进程包含线程,进程的资源被线程共享,线程不拥有资源。

2、前台线程和后台线程:通过Thread类新建线程默认为前台线程。当所有前台线程关闭时,所有的后台线程也会被直接终止,不会抛出异常。

3、挂起(Suspend)和唤醒(Resume):由于线程的执行顺序和程序的执行情况不可预知,所以使用挂起和唤醒容易发生死锁的情况,在实际应用中应该尽量少用。

4、阻塞线程:Join,阻塞调用线程,直到该线程终止。

5、终止线程:Abort:抛出 ThreadAbortException 异常让线程终止,终止后的线程不可唤醒。Interrupt:抛出 ThreadInterruptException 异常让线程终止,通过捕获异常可以继续执行。

6、线程优先级:AboveNormal BelowNormal Highest Lowest Normal,默认为Normal。

三、线程的使用

线程函数通过委托传递,可以不带参数,也可以带参数(只能有一个参数),可以用一个类或结构体封装参数。

复制代码
namespace Test
{
class Program
{
static void Main(string[] args)
{
Thread t1 = new Thread(new ThreadStart(TestMethod));
Thread t2 = new Thread(new ParameterizedThreadStart(TestMethod));
t1.IsBackground = true;
t2.IsBackground = true;
t1.Start();
t2.Start(“hello”);
Console.ReadKey();
}

    public static void TestMethod()
    {
        Console.WriteLine("不带参数的线程函数");
    }

    public static void TestMethod(object data)
    {
        string datastr = data as string;
        Console.WriteLine("带参数的线程函数,参数为:{0}", datastr);
    }
} 

}
复制代码
四、线程池

由于线程的创建和销毁需要耗费一定的开销,过多的使用线程会造成内存资源的浪费,出于对性能的考虑,于是引入了线程池的概念。线程池维护一个请求队列,线程池的代码从队列提取任务,然后委派给线程池的一个线程执行,线程执行完不会被立即销毁,这样既可以在后台执行任务,又可以减少线程创建和销毁所带来的开销。

线程池线程默认为后台线程(IsBackground)。

复制代码
namespace Test
{
class Program
{
static void Main(string[] args)
{
//将工作项加入到线程池队列中,这里可以传递一个线程参数
ThreadPool.QueueUserWorkItem(TestMethod, “Hello”);
Console.ReadKey();
}

    public static void TestMethod(object data)
    {
        string datastr = data as string;
        Console.WriteLine(datastr);
    }
}

}
复制代码
五、Task类

使用ThreadPool的QueueUserWorkItem()方法发起一次异步的线程执行很简单,但是该方法最大的问题是没有一个内建的机制让你知道操作什么时候完成,有没有一个内建的机制在操作完成后获得一个返回值。为此,可以使用System.Threading.Tasks中的Task类。

构造一个Task对象,并为泛型TResult参数传递一个操作的返回类型。

复制代码
namespace Test
{
class Program
{
static void Main(string[] args)
{
Task t = new Task(n => Sum((Int32)n), 1000);
t.Start();
t.Wait();
Console.WriteLine(t.Result);
Console.ReadKey();
}

    private static Int32 Sum(Int32 n)
    {
        Int32 sum = 0;
        for (; n > 0; --n)
            checked{ sum += n;} //结果太大,抛出异常
        return sum;
    }
}

}
复制代码
一个任务完成时,自动启动一个新任务。
一个任务完成后,它可以启动另一个任务,下面重写了前面的代码,不阻塞任何线程。

复制代码
namespace Test
{
class Program
{
static void Main(string[] args)
{
Task t = new Task(n => Sum((Int32)n), 1000);
t.Start();
//t.Wait();
Task cwt = t.ContinueWith(task => Console.WriteLine(“The result is {0}”,t.Result));
Console.ReadKey();
}

    private static Int32 Sum(Int32 n)
    {
        Int32 sum = 0;
        for (; n > 0; --n)
            checked{ sum += n;} //结果溢出,抛出异常
        return sum;
    }
}

}
复制代码
六、委托异步执行

委托的异步调用:BeginInvoke() 和 EndInvoke()

复制代码
namespace Test
{
public delegate string MyDelegate(object data);
class Program
{
static void Main(string[] args)
{
MyDelegate mydelegate = new MyDelegate(TestMethod);
IAsyncResult result = mydelegate.BeginInvoke(“Thread Param”, TestCallback, “Callback Param”);

        //异步执行完成
        string resultstr = mydelegate.EndInvoke(result);
    }

    //线程函数
    public static string TestMethod(object data)
    {
        string datastr = data as string;
        return datastr;
    }

    //异步回调函数
    public static void TestCallback(IAsyncResult data)
    {
        Console.WriteLine(data.AsyncState);
    }
}

}
复制代码
七、线程同步

  1)原子操作(Interlocked):所有方法都是执行一次原子读取或一次写入操作。

  2)lock()语句:避免锁定public类型,否则实例将超出代码控制的范围,定义private对象来锁定。

  3)Monitor实现线程同步

    通过Monitor.Enter() 和 Monitor.Exit()实现排它锁的获取和释放,获取之后独占资源,不允许其他线程访问。

    还有一个TryEnter方法,请求不到资源时不会阻塞等待,可以设置超时时间,获取不到直接返回false。

  4)ReaderWriterLock

    当对资源操作读多写少的时候,为了提高资源的利用率,让读操作锁为共享锁,多个线程可以并发读取资源,而写操作为独占锁,只允许一个线程操作。

  5)事件(Event)类实现同步

    事件类有两种状态,终止状态和非终止状态,终止状态时调用WaitOne可以请求成功,通过Set将时间状态设置为终止状态。

    1)AutoResetEvent(自动重置事件)

    2)ManualResetEvent(手动重置事件)

  6)信号量(Semaphore)

      信号量是由内核对象维护的int变量,为0时,线程阻塞,大于0时解除阻塞,当一个信号量上的等待线程解除阻塞后,信号量计数+1。

      线程通过WaitOne将信号量减1,通过Release将信号量加1,使用很简单。

  7)互斥体(Mutex)

      独占资源,用法与Semaphore相似。

  8)跨进程间的同步

      通过设置同步对象的名称就可以实现系统级的同步,不同应用程序通过同步对象的名称识别不同同步对象。