上传文件至「/」
This commit is contained in:
@@ -0,0 +1,943 @@
|
||||
using System;
|
||||
using System.Configuration;
|
||||
using System.Web;
|
||||
using System.Web.Security;
|
||||
using System.Web.UI;
|
||||
using System.Web.UI.WebControls;
|
||||
using System.Web.UI.WebControls.WebParts;
|
||||
using System.Web.UI.HtmlControls;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Xml.XPath;
|
||||
using GThinking.N_MISPROAS.Web.AjaxServices;
|
||||
using GThinking.N_MISPRO.Data;
|
||||
|
||||
namespace GThinking.S_XLXSBJ
|
||||
{
|
||||
/// <summary>
|
||||
/// 服务方法管理相关服务。
|
||||
/// </summary>
|
||||
public class ServiceMethod
|
||||
{
|
||||
/// <summary>
|
||||
/// 根据传入的 DLL 文件地址,反射获取其中标记了 AjaxMethod 的服务方法信息,
|
||||
/// 并写入数据库表:SRCMD、SRCMETHOD、SRCMETHODPARAMS、SRCTYPE、SRCPROP。
|
||||
/// </summary>
|
||||
/// <param name="filePath">DLL 文件地址。</param>
|
||||
/// <returns>操作结果。</returns>
|
||||
[AjaxMethod(AuthRequried = false)]
|
||||
public static Dictionary<string, object> SaveServiceMethodInfo(string filePath)
|
||||
{
|
||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
||||
TDatabase dberp = null;
|
||||
|
||||
if (string.IsNullOrEmpty(filePath) || !File.Exists(filePath))
|
||||
{
|
||||
result["success"] = false;
|
||||
result["msg"] = "文件地址不能为空或文件不存在";
|
||||
return result;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
dberp = TContextDatabases.GetDatabase("DBERP");
|
||||
dberp.BeginTrans();
|
||||
|
||||
Assembly assembly = Assembly.LoadFrom(filePath);
|
||||
string macId = Truncate(assembly.GetName().Name, 20);
|
||||
|
||||
// 先删除该部件旧数据
|
||||
DeleteOldModuleData(dberp, macId);
|
||||
|
||||
XmlDocHelper xmlDoc = new XmlDocHelper(filePath);
|
||||
int mdIndex = 0;
|
||||
Dictionary<string, string> visitedTypes = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
Type[] types = null;
|
||||
try
|
||||
{
|
||||
types = assembly.GetTypes();
|
||||
}
|
||||
catch (ReflectionTypeLoadException ex)
|
||||
{
|
||||
types = ex.Types;
|
||||
}
|
||||
|
||||
if (types == null)
|
||||
{
|
||||
dberp.CommitTrans();
|
||||
result["success"] = true;
|
||||
result["msg"] = "未找到可扫描的类型";
|
||||
result["macId"] = macId;
|
||||
return result;
|
||||
}
|
||||
|
||||
foreach (Type type in types)
|
||||
{
|
||||
if (type == null)
|
||||
continue;
|
||||
if (!type.IsClass)
|
||||
continue;
|
||||
|
||||
Dictionary<string, ServiceMethodInfo> methods = GetServiceMethods(type);
|
||||
if (methods == null || methods.Count == 0)
|
||||
continue;
|
||||
|
||||
mdIndex++;
|
||||
double mdId = (double)mdIndex;
|
||||
|
||||
InsertSRCMD(dberp, macId, mdId, Truncate(type.FullName, 40));
|
||||
|
||||
foreach (ServiceMethodInfo smi in methods.Values)
|
||||
{
|
||||
string methodDesc = xmlDoc.GetMethodSummary(smi.MethodInfo);
|
||||
string retDesc = xmlDoc.GetMethodReturns(smi.MethodInfo);
|
||||
|
||||
InsertSRCMETHOD(
|
||||
dberp,
|
||||
macId,
|
||||
mdId,
|
||||
Truncate(smi.MethodName, 32),
|
||||
Truncate(GetMethodModifiers(smi.MethodInfo), 80),
|
||||
smi.AuthRequried ? "Y" : "N",
|
||||
smi.UseHttpGet ? "Y" : "N",
|
||||
Truncate(methodDesc, 4000),
|
||||
Truncate(GetTypeDisplayName(smi.ReturnType), 80),
|
||||
Truncate(retDesc, 1000));
|
||||
|
||||
if (smi.ParameterList != null)
|
||||
{
|
||||
int paramXh = 0;
|
||||
foreach (ServiceParameterInfo spi in smi.ParameterList)
|
||||
{
|
||||
string paramDesc = xmlDoc.GetParameterSummary(smi.MethodInfo, spi.Name);
|
||||
|
||||
InsertSRCMETHODPARAMS(
|
||||
dberp,
|
||||
macId,
|
||||
mdId,
|
||||
Truncate(smi.MethodName, 32),
|
||||
(double)paramXh,
|
||||
Truncate(spi.Name, 32),
|
||||
Truncate(GetTypeDisplayName(spi.ParameterType), 80),
|
||||
Truncate(paramDesc, 1000));
|
||||
|
||||
ReflectType(spi.ParameterType, dberp, visitedTypes, xmlDoc);
|
||||
paramXh++;
|
||||
}
|
||||
}
|
||||
|
||||
ReflectType(smi.ReturnType, dberp, visitedTypes, xmlDoc);
|
||||
}
|
||||
}
|
||||
|
||||
dberp.CommitTrans();
|
||||
result["success"] = true;
|
||||
result["msg"] = "扫描完成";
|
||||
result["macId"] = macId;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (dberp != null && dberp.InTransaction)
|
||||
dberp.RollbackTrans();
|
||||
|
||||
result["success"] = false;
|
||||
result["msg"] = ex.Message;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据 MACID 查询已扫描的服务方法数据。
|
||||
/// </summary>
|
||||
/// <param name="macId">服务部件ID(程序集名称)。</param>
|
||||
/// <returns>包含各表数据的结果。</returns>
|
||||
[AjaxMethod(AuthRequried = false)]
|
||||
public static Dictionary<string, object> GetServiceMethodData(string macId)
|
||||
{
|
||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
||||
TDatabase dberp = null;
|
||||
|
||||
try
|
||||
{
|
||||
dberp = TContextDatabases.GetDatabase("DBERP");
|
||||
|
||||
result["SRCMD"] = QueryTableByMacId(dberp, "SRCMD", macId);
|
||||
result["SRCMETHOD"] = QueryTableByMacId(dberp, "SRCMETHOD", macId);
|
||||
result["SRCMETHODPARAMS"] = QueryTableByMacId(dberp, "SRCMETHODPARAMS", macId);
|
||||
result["SRCTYPE"] = QueryAll(dberp, "SRCTYPE");
|
||||
result["SRCPROP"] = QueryAll(dberp, "SRCPROP");
|
||||
result["success"] = true;
|
||||
result["msg"] = "";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
result["success"] = false;
|
||||
result["msg"] = ex.Message;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#region 数据库操作
|
||||
|
||||
private static void DeleteOldModuleData(TDatabase dberp, string macId)
|
||||
{
|
||||
string[] tables = new string[] { "SRCMETHODPARAMS", "SRCMETHOD", "SRCMD" };
|
||||
TSQL sql = new TSQL(dberp);
|
||||
foreach (string table in tables)
|
||||
{
|
||||
sql.Clear();
|
||||
sql.Add("delete from " + table + " where MACID=:pMACID");
|
||||
sql.ParamByName("pMACID").Value = macId;
|
||||
dberp.ExecSQL(sql);
|
||||
}
|
||||
}
|
||||
|
||||
private static void DeleteTypeData(TDatabase dberp, string typeFullName)
|
||||
{
|
||||
TSQL sql = new TSQL(dberp);
|
||||
sql.Clear();
|
||||
sql.Add("delete from SRCPROP where TYPEFULLNAME=:pTYPEFULLNAME");
|
||||
sql.ParamByName("pTYPEFULLNAME").Value = typeFullName;
|
||||
dberp.ExecSQL(sql);
|
||||
|
||||
sql.Clear();
|
||||
sql.Add("delete from SRCTYPE where TYPEFULLNAME=:pTYPEFULLNAME");
|
||||
sql.ParamByName("pTYPEFULLNAME").Value = typeFullName;
|
||||
dberp.ExecSQL(sql);
|
||||
}
|
||||
|
||||
private static List<Dictionary<string, object>> QueryTableByMacId(TDatabase dberp, string tableName, string macId)
|
||||
{
|
||||
TSQL sql = new TSQL(dberp);
|
||||
sql.Add("select " + GetTableColumns(tableName) + " from " + tableName + " where MACID=:pMACID");
|
||||
sql.ParamByName("pMACID").Value = macId;
|
||||
DataSet ds = dberp.OpenDataSet(sql);
|
||||
return DataTableToList(ds.Tables[0]);
|
||||
}
|
||||
|
||||
private static List<Dictionary<string, object>> QueryAll(TDatabase dberp, string tableName)
|
||||
{
|
||||
TSQL sql = new TSQL(dberp);
|
||||
sql.Add("select " + GetTableColumns(tableName) + " from " + tableName);
|
||||
DataSet ds = dberp.OpenDataSet(sql);
|
||||
return DataTableToList(ds.Tables[0]);
|
||||
}
|
||||
|
||||
private static string GetTableColumns(string tableName)
|
||||
{
|
||||
switch (tableName)
|
||||
{
|
||||
case "SRCMD":
|
||||
return "MACID, MDID, MDNAME";
|
||||
case "SRCMETHOD":
|
||||
return "MACID, MDID, METHODNAME, MODIFIERS, AUTHREQUIRED, USEHTTPGET, METHODDESC, RETTYPE, RETDESC";
|
||||
case "SRCMETHODPARAMS":
|
||||
return "MACID, MDID, METHODNAME, PARAMXH, PARAMNAME, PARAMTYPE, PARAMDESC";
|
||||
case "SRCTYPE":
|
||||
return "TYPEFULLNAME, NAMESPACE, TYPENAME, TYPEDESC";
|
||||
case "SRCPROP":
|
||||
return "TYPEFULLNAME, PROPNAME, PROPTYPEFULLNAME, NAMESPACE, PROPTYPE, PROPDESC";
|
||||
default:
|
||||
return "*";
|
||||
}
|
||||
}
|
||||
|
||||
private static List<Dictionary<string, object>> DataTableToList(DataTable dt)
|
||||
{
|
||||
List<Dictionary<string, object>> list = new List<Dictionary<string, object>>();
|
||||
foreach (DataRow row in dt.Rows)
|
||||
{
|
||||
Dictionary<string, object> item = new Dictionary<string, object>();
|
||||
foreach (DataColumn col in dt.Columns)
|
||||
{
|
||||
object val = row[col];
|
||||
item[col.ColumnName] = val == DBNull.Value ? null : val;
|
||||
}
|
||||
list.Add(item);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private static void InsertSRCMD(TDatabase dberp, string macId, double mdId, string mdName)
|
||||
{
|
||||
TSQL sql = new TSQL(dberp);
|
||||
sql.Clear();
|
||||
sql.Add("insert into SRCMD(MACID, MDID, MDNAME) values(:pMACID, :pMDID, :pMDNAME)");
|
||||
sql.ParamByName("pMACID").Value = macId;
|
||||
sql.ParamByName("pMDID").Value = mdId;
|
||||
sql.ParamByName("pMDNAME").Value = mdName;
|
||||
dberp.ExecSQL(sql);
|
||||
}
|
||||
|
||||
private static void InsertSRCMETHOD(TDatabase dberp, string macId, double mdId, string methodName,
|
||||
string modifiers, string authRequired, string useHttpGet, string methodDesc,
|
||||
string retType, string retDesc)
|
||||
{
|
||||
TSQL sql = new TSQL(dberp);
|
||||
sql.Clear();
|
||||
sql.Add("insert into SRCMETHOD(MACID, MDID, METHODNAME, MODIFIERS, AUTHREQUIRED, USEHTTPGET, METHODDESC, RETTYPE, RETDESC) ");
|
||||
sql.Add("values(:pMACID, :pMDID, :pMETHODNAME, :pMODIFIERS, :pAUTHREQUIRED, :pUSEHTTPGET, :pMETHODDESC, :pRETTYPE, :pRETDESC)");
|
||||
sql.ParamByName("pMACID").Value = macId;
|
||||
sql.ParamByName("pMDID").Value = mdId;
|
||||
sql.ParamByName("pMETHODNAME").Value = methodName;
|
||||
sql.ParamByName("pMODIFIERS").Value = modifiers;
|
||||
sql.ParamByName("pAUTHREQUIRED").Value = authRequired;
|
||||
sql.ParamByName("pUSEHTTPGET").Value = useHttpGet;
|
||||
sql.ParamByName("pMETHODDESC").Value = methodDesc;
|
||||
sql.ParamByName("pRETTYPE").Value = retType;
|
||||
sql.ParamByName("pRETDESC").Value = retDesc;
|
||||
dberp.ExecSQL(sql);
|
||||
}
|
||||
|
||||
private static void InsertSRCMETHODPARAMS(TDatabase dberp, string macId, double mdId, string methodName,
|
||||
double paramXh, string paramName, string paramType, string paramDesc)
|
||||
{
|
||||
TSQL sql = new TSQL(dberp);
|
||||
sql.Clear();
|
||||
sql.Add("insert into SRCMETHODPARAMS(MACID, MDID, METHODNAME, PARAMXH, PARAMNAME, PARAMTYPE, PARAMDESC) ");
|
||||
sql.Add("values(:pMACID, :pMDID, :pMETHODNAME, :pPARAMXH, :pPARAMNAME, :pPARAMTYPE, :pPARAMDESC)");
|
||||
sql.ParamByName("pMACID").Value = macId;
|
||||
sql.ParamByName("pMDID").Value = mdId;
|
||||
sql.ParamByName("pMETHODNAME").Value = methodName;
|
||||
sql.ParamByName("pPARAMXH").Value = paramXh;
|
||||
sql.ParamByName("pPARAMNAME").Value = paramName;
|
||||
sql.ParamByName("pPARAMTYPE").Value = paramType;
|
||||
sql.ParamByName("pPARAMDESC").Value = paramDesc;
|
||||
dberp.ExecSQL(sql);
|
||||
}
|
||||
|
||||
private static void InsertSRCTYPE(TDatabase dberp, string typeFullName, string nameSpace,
|
||||
string typeName, string typeDesc)
|
||||
{
|
||||
TSQL sql = new TSQL(dberp);
|
||||
sql.Clear();
|
||||
sql.Add("insert into SRCTYPE(TYPEFULLNAME, NAMESPACE, TYPENAME, TYPEDESC) ");
|
||||
sql.Add("values(:pTYPEFULLNAME, :pNAMESPACE, :pTYPENAME, :pTYPEDESC)");
|
||||
sql.ParamByName("pTYPEFULLNAME").Value = typeFullName;
|
||||
sql.ParamByName("pNAMESPACE").Value = nameSpace;
|
||||
sql.ParamByName("pTYPENAME").Value = typeName;
|
||||
sql.ParamByName("pTYPEDESC").Value = typeDesc;
|
||||
dberp.ExecSQL(sql);
|
||||
}
|
||||
|
||||
private static void InsertSRCPROP(TDatabase dberp, string typeFullName, string propName,
|
||||
string propTypeFullName, string nameSpace, string propType, string propDesc)
|
||||
{
|
||||
TSQL sql = new TSQL(dberp);
|
||||
sql.Clear();
|
||||
sql.Add("insert into SRCPROP(TYPEFULLNAME, PROPNAME, PROPTYPEFULLNAME, NAMESPACE, PROPTYPE, PROPDESC) ");
|
||||
sql.Add("values(:pTYPEFULLNAME, :pPROPNAME, :pPROPTYPEFULLNAME, :pNAMESPACE, :pPROPTYPE, :pPROPDESC)");
|
||||
sql.ParamByName("pTYPEFULLNAME").Value = typeFullName;
|
||||
sql.ParamByName("pPROPNAME").Value = propName;
|
||||
sql.ParamByName("pPROPTYPEFULLNAME").Value = propTypeFullName;
|
||||
sql.ParamByName("pNAMESPACE").Value = nameSpace;
|
||||
sql.ParamByName("pPROPTYPE").Value = propType;
|
||||
sql.ParamByName("pPROPDESC").Value = propDesc;
|
||||
dberp.ExecSQL(sql);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 反射与类型辅助
|
||||
|
||||
private static Dictionary<string, ServiceMethodInfo> GetServiceMethods(Type classType)
|
||||
{
|
||||
if (classType == null)
|
||||
return null;
|
||||
|
||||
List<Type> typeList = new List<Type>();
|
||||
Type current = classType;
|
||||
typeList.Add(current);
|
||||
while (current.BaseType != null)
|
||||
{
|
||||
current = current.BaseType;
|
||||
if (current != typeof(object))
|
||||
typeList.Add(current);
|
||||
}
|
||||
|
||||
Dictionary<string, ServiceMethodInfo> methods = new Dictionary<string, ServiceMethodInfo>(StringComparer.OrdinalIgnoreCase);
|
||||
BindingFlags flags = BindingFlags.Public | BindingFlags.DeclaredOnly |
|
||||
BindingFlags.Static | BindingFlags.Instance;
|
||||
|
||||
for (int i = typeList.Count - 1; i >= 0; --i)
|
||||
{
|
||||
MethodInfo[] methodInfos = typeList[i].GetMethods(flags);
|
||||
foreach (MethodInfo method in methodInfos)
|
||||
{
|
||||
object[] attribs = method.GetCustomAttributes(typeof(AjaxMethodAttribute), true);
|
||||
if (attribs.Length > 0)
|
||||
{
|
||||
AjaxMethodAttribute ajaxAttr = (AjaxMethodAttribute)attribs[0];
|
||||
ServiceMethodInfo smi = new ServiceMethodInfo(method, ajaxAttr);
|
||||
smi.LoadMethodParameters();
|
||||
methods[smi.MethodName] = smi;
|
||||
}
|
||||
}
|
||||
}
|
||||
return methods;
|
||||
}
|
||||
|
||||
private static string GetMethodModifiers(MethodInfo method)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (method.IsPublic)
|
||||
sb.Append("public ");
|
||||
else if (method.IsPrivate)
|
||||
sb.Append("private ");
|
||||
else if (method.IsFamily)
|
||||
sb.Append("protected ");
|
||||
else if (method.IsAssembly)
|
||||
sb.Append("internal ");
|
||||
|
||||
if (method.IsStatic)
|
||||
sb.Append("static ");
|
||||
|
||||
return sb.ToString().Trim();
|
||||
}
|
||||
|
||||
private static void ReflectType(Type type, TDatabase dberp,
|
||||
Dictionary<string, string> visitedTypes, XmlDocHelper xmlDoc)
|
||||
{
|
||||
if (type == null)
|
||||
return;
|
||||
|
||||
if (type.IsByRef || type.IsPointer)
|
||||
{
|
||||
ReflectType(type.GetElementType(), dberp, visitedTypes, xmlDoc);
|
||||
return;
|
||||
}
|
||||
|
||||
if (type.IsArray)
|
||||
{
|
||||
ReflectType(type.GetElementType(), dberp, visitedTypes, xmlDoc);
|
||||
return;
|
||||
}
|
||||
|
||||
Type underlying = Nullable.GetUnderlyingType(type);
|
||||
if (underlying != null)
|
||||
{
|
||||
ReflectType(underlying, dberp, visitedTypes, xmlDoc);
|
||||
return;
|
||||
}
|
||||
|
||||
if (type.IsGenericType)
|
||||
{
|
||||
Type[] args = type.GetGenericArguments();
|
||||
foreach (Type arg in args)
|
||||
ReflectType(arg, dberp, visitedTypes, xmlDoc);
|
||||
|
||||
Type def = type.GetGenericTypeDefinition();
|
||||
if (!IsCustomType(def))
|
||||
return;
|
||||
|
||||
type = def;
|
||||
}
|
||||
|
||||
if (!IsCustomType(type))
|
||||
return;
|
||||
|
||||
string key = type.FullName;
|
||||
if (string.IsNullOrEmpty(key))
|
||||
return;
|
||||
if (visitedTypes.ContainsKey(key))
|
||||
return;
|
||||
visitedTypes[key] = key;
|
||||
|
||||
string typeFullName = type.FullName.Replace('+', '.');
|
||||
|
||||
// 先清理该类型旧数据,再重新写入
|
||||
DeleteTypeData(dberp, typeFullName);
|
||||
|
||||
InsertSRCTYPE(
|
||||
dberp,
|
||||
Truncate(typeFullName, 80),
|
||||
Truncate(type.Namespace, 80),
|
||||
Truncate(GetTypeShortName(type), 80),
|
||||
Truncate(xmlDoc.GetSummary(type), 1000));
|
||||
|
||||
List<MemberInfo> members = new List<MemberInfo>();
|
||||
members.AddRange(type.GetProperties(BindingFlags.Public | BindingFlags.Instance));
|
||||
members.AddRange(type.GetFields(BindingFlags.Public | BindingFlags.Instance));
|
||||
members.Sort(new MemberNameComparer());
|
||||
|
||||
foreach (MemberInfo mi in members)
|
||||
{
|
||||
Type memberType = null;
|
||||
if (mi is PropertyInfo)
|
||||
memberType = ((PropertyInfo)mi).PropertyType;
|
||||
else if (mi is FieldInfo)
|
||||
memberType = ((FieldInfo)mi).FieldType;
|
||||
else
|
||||
continue;
|
||||
|
||||
string propTypeFullName = memberType.FullName == null ? memberType.Name : memberType.FullName.Replace('+', '.');
|
||||
|
||||
InsertSRCPROP(
|
||||
dberp,
|
||||
Truncate(typeFullName, 80),
|
||||
Truncate(mi.Name, 32),
|
||||
Truncate(propTypeFullName, 80),
|
||||
Truncate(memberType.Namespace, 80),
|
||||
Truncate(GetTypeDisplayName(memberType), 80),
|
||||
Truncate(xmlDoc.GetSummary(mi), 250));
|
||||
|
||||
ReflectType(memberType, dberp, visitedTypes, xmlDoc);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsCustomType(Type type)
|
||||
{
|
||||
if (type == null)
|
||||
return false;
|
||||
if (type.IsGenericParameter)
|
||||
return false;
|
||||
if (type.IsPrimitive)
|
||||
return false;
|
||||
if (type == typeof(string) || type == typeof(object) || type == typeof(decimal)
|
||||
|| type == typeof(DateTime) || type == typeof(TimeSpan) || type == typeof(Guid))
|
||||
return false;
|
||||
if (type.Namespace != null &&
|
||||
(type.Namespace.StartsWith("System") || type.Namespace.StartsWith("Microsoft")))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
private static string GetTypeDisplayName(Type type)
|
||||
{
|
||||
if (type == null)
|
||||
return "";
|
||||
|
||||
if (type.IsByRef)
|
||||
return GetTypeDisplayName(type.GetElementType()) + "&";
|
||||
if (type.IsPointer)
|
||||
return GetTypeDisplayName(type.GetElementType()) + "*";
|
||||
if (type.IsArray)
|
||||
return GetTypeDisplayName(type.GetElementType()) + "[]";
|
||||
|
||||
Type underlying = Nullable.GetUnderlyingType(type);
|
||||
if (underlying != null)
|
||||
return GetTypeDisplayName(underlying) + "?";
|
||||
|
||||
if (type.IsGenericType)
|
||||
{
|
||||
Type def = type.GetGenericTypeDefinition();
|
||||
string baseName = def.FullName;
|
||||
if (string.IsNullOrEmpty(baseName))
|
||||
baseName = type.Name;
|
||||
baseName = baseName.Replace('+', '.');
|
||||
int backtick = baseName.IndexOf('`');
|
||||
string cleanName = backtick > 0 ? baseName.Substring(0, backtick) : baseName;
|
||||
|
||||
Type[] genericArgs = type.GetGenericArguments();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.Append(cleanName);
|
||||
sb.Append("<");
|
||||
for (int i = 0; i < genericArgs.Length; i++)
|
||||
{
|
||||
sb.Append(GetTypeDisplayName(genericArgs[i]));
|
||||
if (i < genericArgs.Length - 1)
|
||||
sb.Append(", ");
|
||||
}
|
||||
sb.Append(">");
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
if (type.FullName == null)
|
||||
return type.Name;
|
||||
return type.FullName.Replace('+', '.');
|
||||
}
|
||||
|
||||
private static string GetTypeShortName(Type type)
|
||||
{
|
||||
if (type == null)
|
||||
return "";
|
||||
string name = type.Name;
|
||||
int backtick = name.IndexOf('`');
|
||||
if (backtick > 0)
|
||||
name = name.Substring(0, backtick);
|
||||
return name;
|
||||
}
|
||||
|
||||
private static string Truncate(string value, int maxLength)
|
||||
{
|
||||
if (string.IsNullOrEmpty(value))
|
||||
return string.Empty;
|
||||
if (value.Length > maxLength)
|
||||
return value.Substring(0, maxLength);
|
||||
return value;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 嵌套辅助类
|
||||
|
||||
/// <summary>
|
||||
/// 服务方法信息。
|
||||
/// </summary>
|
||||
private class ServiceMethodInfo
|
||||
{
|
||||
internal ServiceMethodInfo(MethodInfo methodInfo, AjaxMethodAttribute methodAttribute)
|
||||
{
|
||||
_methodInfo = methodInfo;
|
||||
_methodName = methodInfo.Name;
|
||||
_isPublic = methodInfo.IsPublic;
|
||||
_isStatic = methodInfo.IsStatic;
|
||||
_returnType = methodInfo.ReturnType;
|
||||
_authRequried = methodAttribute.AuthRequried;
|
||||
_useHttpGet = methodAttribute.UseHttpGet;
|
||||
}
|
||||
|
||||
private MethodInfo _methodInfo;
|
||||
internal MethodInfo MethodInfo
|
||||
{
|
||||
get { return _methodInfo; }
|
||||
}
|
||||
|
||||
private string _methodName;
|
||||
public string MethodName
|
||||
{
|
||||
get { return _methodName == null ? string.Empty : _methodName; }
|
||||
set { _methodName = value; }
|
||||
}
|
||||
|
||||
private bool _isPublic;
|
||||
public bool IsPublic
|
||||
{
|
||||
get { return _isPublic; }
|
||||
set { _isPublic = value; }
|
||||
}
|
||||
|
||||
private bool _isStatic;
|
||||
public bool IsStatic
|
||||
{
|
||||
get { return _isStatic; }
|
||||
set { _isStatic = value; }
|
||||
}
|
||||
|
||||
private Type _returnType;
|
||||
public Type ReturnType
|
||||
{
|
||||
get { return _returnType; }
|
||||
set { _returnType = value; }
|
||||
}
|
||||
|
||||
private bool _authRequried;
|
||||
public bool AuthRequried
|
||||
{
|
||||
get { return _authRequried; }
|
||||
set { _authRequried = value; }
|
||||
}
|
||||
|
||||
private bool _useHttpGet;
|
||||
public bool UseHttpGet
|
||||
{
|
||||
get { return _useHttpGet; }
|
||||
set { _useHttpGet = value; }
|
||||
}
|
||||
|
||||
private List<ServiceParameterInfo> _parameterList;
|
||||
public List<ServiceParameterInfo> ParameterList
|
||||
{
|
||||
get { return _parameterList; }
|
||||
set { _parameterList = value; }
|
||||
}
|
||||
|
||||
internal void LoadMethodParameters()
|
||||
{
|
||||
if (_methodInfo == null)
|
||||
return;
|
||||
|
||||
List<ServiceParameterInfo> list = new List<ServiceParameterInfo>();
|
||||
int index = 0;
|
||||
foreach (ParameterInfo param in _methodInfo.GetParameters())
|
||||
{
|
||||
list.Add(new ServiceParameterInfo(param, index));
|
||||
index++;
|
||||
}
|
||||
_parameterList = list;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 服务方法参数信息。
|
||||
/// </summary>
|
||||
private class ServiceParameterInfo
|
||||
{
|
||||
private ParameterInfo _param;
|
||||
private int _index;
|
||||
|
||||
internal ServiceParameterInfo(ParameterInfo param, int index)
|
||||
{
|
||||
_param = param;
|
||||
_index = index;
|
||||
}
|
||||
|
||||
internal ParameterInfo ParameterInfo
|
||||
{
|
||||
get { return _param; }
|
||||
}
|
||||
|
||||
internal int Index
|
||||
{
|
||||
get { return _index; }
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return _param.Name; }
|
||||
}
|
||||
|
||||
public Type ParameterType
|
||||
{
|
||||
get { return _param.ParameterType; }
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// XML 文档注释读取辅助类。
|
||||
/// </summary>
|
||||
private class XmlDocHelper
|
||||
{
|
||||
private XPathDocument _doc;
|
||||
private XPathNavigator _nav;
|
||||
|
||||
public XmlDocHelper(string dllPath)
|
||||
{
|
||||
if (string.IsNullOrEmpty(dllPath))
|
||||
return;
|
||||
|
||||
string fullPath = Path.GetFullPath(dllPath);
|
||||
string dir = Path.GetDirectoryName(fullPath);
|
||||
string xmlPath = Path.Combine(dir, Path.GetFileNameWithoutExtension(fullPath) + ".xml");
|
||||
if (!File.Exists(xmlPath))
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
_doc = new XPathDocument(xmlPath);
|
||||
_nav = _doc.CreateNavigator();
|
||||
}
|
||||
catch
|
||||
{
|
||||
_doc = null;
|
||||
_nav = null;
|
||||
}
|
||||
}
|
||||
|
||||
public string GetSummary(Type type)
|
||||
{
|
||||
if (_nav == null || type == null)
|
||||
return "";
|
||||
string id = GetTypeDocId(type);
|
||||
return GetChildText("T", id, "summary");
|
||||
}
|
||||
|
||||
public string GetSummary(MemberInfo member)
|
||||
{
|
||||
if (_nav == null || member == null)
|
||||
return "";
|
||||
string prefix = "P";
|
||||
if (member is FieldInfo)
|
||||
prefix = "F";
|
||||
else if (member is PropertyInfo)
|
||||
prefix = "P";
|
||||
else if (member is MethodInfo)
|
||||
prefix = "M";
|
||||
string id = GetMemberDocId(member);
|
||||
return GetChildText(prefix, id, "summary");
|
||||
}
|
||||
|
||||
public string GetMethodSummary(MethodInfo method)
|
||||
{
|
||||
XPathNavigator node = FindMethodNode(method);
|
||||
if (node == null)
|
||||
return "";
|
||||
XPathNavigator sum = node.SelectSingleNode("summary");
|
||||
return sum == null ? "" : sum.Value.Trim();
|
||||
}
|
||||
|
||||
public string GetMethodReturns(MethodInfo method)
|
||||
{
|
||||
XPathNavigator node = FindMethodNode(method);
|
||||
if (node == null)
|
||||
return "";
|
||||
XPathNavigator ret = node.SelectSingleNode("returns");
|
||||
return ret == null ? "" : ret.Value.Trim();
|
||||
}
|
||||
|
||||
public string GetParameterSummary(MethodInfo method, string paramName)
|
||||
{
|
||||
XPathNavigator node = FindMethodNode(method);
|
||||
if (node == null || string.IsNullOrEmpty(paramName))
|
||||
return "";
|
||||
string expr = "param[@name='" + Escape(paramName) + "']";
|
||||
XPathNavigator pn = node.SelectSingleNode(expr);
|
||||
return pn == null ? "" : pn.Value.Trim();
|
||||
}
|
||||
|
||||
private string GetChildText(string prefix, string id, string childName)
|
||||
{
|
||||
if (_nav == null)
|
||||
return "";
|
||||
string expr = "//member[@name='" + prefix + ":" + Escape(id) + "']";
|
||||
XPathNavigator node = _nav.SelectSingleNode(expr);
|
||||
if (node == null)
|
||||
return "";
|
||||
XPathNavigator child = node.SelectSingleNode(childName);
|
||||
return child == null ? "" : child.Value.Trim();
|
||||
}
|
||||
|
||||
private XPathNavigator FindMethodNode(MethodInfo method)
|
||||
{
|
||||
if (_nav == null || method == null)
|
||||
return null;
|
||||
|
||||
string exactId = GetMethodDocId(method);
|
||||
string expr = "//member[@name='M:" + Escape(exactId) + "']";
|
||||
XPathNavigator node = _nav.SelectSingleNode(expr);
|
||||
if (node != null)
|
||||
return node;
|
||||
|
||||
string typeId = GetTypeDocId(method.DeclaringType);
|
||||
string prefix = "M:" + Escape(typeId) + "." + method.Name;
|
||||
XPathNodeIterator iter = _nav.Select("//member[starts-with(@name,'" + prefix + "')]");
|
||||
int pCount = method.GetParameters().Length;
|
||||
|
||||
while (iter.MoveNext())
|
||||
{
|
||||
string name = iter.Current.GetAttribute("name", "");
|
||||
int open = name.IndexOf('(');
|
||||
int close = name.LastIndexOf(')');
|
||||
if (open > 0 && close > open)
|
||||
{
|
||||
string sig = name.Substring(open + 1, close - open - 1);
|
||||
int count = string.IsNullOrEmpty(sig) ? 0 : CountChar(sig, ',') + 1;
|
||||
if (count == pCount)
|
||||
return iter.Current.Clone();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static string GetTypeDocId(Type type)
|
||||
{
|
||||
if (type == null)
|
||||
return "";
|
||||
string fullName = type.FullName;
|
||||
if (string.IsNullOrEmpty(fullName))
|
||||
return type.Name;
|
||||
return fullName.Replace('+', '.');
|
||||
}
|
||||
|
||||
private static string GetMemberDocId(MemberInfo member)
|
||||
{
|
||||
Type type = member.DeclaringType;
|
||||
string typeId = GetTypeDocId(type);
|
||||
if (member is MethodInfo)
|
||||
return GetMethodDocId((MethodInfo)member);
|
||||
return typeId + "." + member.Name;
|
||||
}
|
||||
|
||||
private static string GetMethodDocId(MethodInfo method)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.Append(GetTypeDocId(method.DeclaringType));
|
||||
sb.Append(".");
|
||||
sb.Append(method.Name);
|
||||
if (method.IsGenericMethod)
|
||||
sb.Append("``").Append(method.GetGenericArguments().Length);
|
||||
sb.Append("(");
|
||||
ParameterInfo[] ps = method.GetParameters();
|
||||
for (int i = 0; i < ps.Length; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
sb.Append(",");
|
||||
sb.Append(GetParameterDocTypeName(ps[i].ParameterType));
|
||||
}
|
||||
sb.Append(")");
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string GetParameterDocTypeName(Type type)
|
||||
{
|
||||
if (type == null)
|
||||
return "";
|
||||
if (type.IsGenericParameter)
|
||||
return type.Name;
|
||||
if (type.IsByRef)
|
||||
return GetParameterDocTypeName(type.GetElementType()) + "@";
|
||||
if (type.IsPointer)
|
||||
return GetParameterDocTypeName(type.GetElementType()) + "*";
|
||||
if (type.IsArray)
|
||||
return GetParameterDocTypeName(type.GetElementType()) + "[]";
|
||||
|
||||
Type underlying = Nullable.GetUnderlyingType(type);
|
||||
if (underlying != null)
|
||||
return GetParameterDocTypeName(underlying) + "?";
|
||||
|
||||
if (type.IsGenericType)
|
||||
{
|
||||
Type def = type.GetGenericTypeDefinition();
|
||||
string baseName = def.FullName;
|
||||
if (string.IsNullOrEmpty(baseName))
|
||||
baseName = type.Name;
|
||||
baseName = baseName.Replace('+', '.');
|
||||
Type[] args = type.GetGenericArguments();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.Append(baseName);
|
||||
sb.Append("{");
|
||||
for (int i = 0; i < args.Length; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
sb.Append(",");
|
||||
sb.Append(GetParameterDocTypeName(args[i]));
|
||||
}
|
||||
sb.Append("}");
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
string name = type.FullName;
|
||||
if (string.IsNullOrEmpty(name))
|
||||
name = type.Name;
|
||||
return name.Replace('+', '.');
|
||||
}
|
||||
|
||||
private static string Escape(string s)
|
||||
{
|
||||
if (s == null)
|
||||
return "";
|
||||
return s.Replace("'", "''");
|
||||
}
|
||||
|
||||
private static int CountChar(string s, char c)
|
||||
{
|
||||
int count = 0;
|
||||
for (int i = 0; i < s.Length; i++)
|
||||
{
|
||||
if (s[i] == c)
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 按成员名称排序的比较器。
|
||||
/// </summary>
|
||||
private class MemberNameComparer : IComparer<MemberInfo>
|
||||
{
|
||||
public int Compare(MemberInfo x, MemberInfo y)
|
||||
{
|
||||
return string.Compare(x.Name, y.Name, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user