然后在界面的拖放事件结束时通过js发送ajax请求来得到界面要呈现的html:
$(".jq-draggable-outcontainer").draggable({
helper: "clone",
scroll: true,
drag: function (event, ui) {
//   debugger;
}
});
$("#content").droppable({
drop: function (event, ui) {
//  debugger;
if (ui.draggable[0].className.indexOf("jq-draggable-outcontainer") > 0) {
var text = ui.draggable[0].innerText.trim();
$(this).append('<div class="window jq-draggable-incontainer" onclick="GetPropertiesByType('1',this)" style="position:absolute;left:' +(event.clientX-20) + 'px;top:' + (event.clientY-20) + 'px" id="window' + iIndex + '"><strong>' + text + '</strong></div>');
$("#content2").html("");
cur_selector = $("#window"+iIndex);
$.Ewin.AjaxPost("/Home/GetModelByType", { strType: "Factory" }, function (data, status) {
var element = $.parseJSON(data.Json);
var arrProp = element.element.property;
//0.构造html
var strHtml = "<div style='float:right;padding-top:0px;width:300px;height:auto;'><table cellpadding='5' border='1'>";
//1.拼html构造属性
strHtml += "</table></div>";
$("#content2").append(strHtml);
}, function () {
}, null);
iIndex++;
}
}
});
  对应的C#方法:
public JsonResult GetModelByType(string strType)
{
//strType传过来的是Factory或者FactoryDetail
var assembly = Assembly.Load("Ewin.Client.Web");
//参数为程序集的名称
var oType = assembly.GetType("Ewin.Client.Web.Controllers." + strType);
//得到类的所有属性
var lstProperties = oType.GetProperties();
foreach (var oProperty in lstProperties)
{
//得到每一个属性的特性类集合
IList<CustomAttributeData> lstAttr = oProperty.GetCustomAttributesData();
foreach (var oAttr in lstAttr)
{
//得到每一个特性类的全称
Console.WriteLine("特性类的名称" + oAttr.AttributeType.FullName);
Console.WriteLine("特性类成员如下:");
//得到特性类的所有参数
var lstAttrArgu = oAttr.NamedArguments;
foreach (var oAttrAru in lstAttrArgu)
{
//取每个特性类参数的键值对
Console.WriteLine(oAttrAru.MemberName + "=" + oAttrAru.TypedValue.Value);
}
//Console.WriteLine(oAttr.AttributeType+"——"+oAttr.NamedArguments);
}
}
return Json(new { }, JsonRequestBehavior.AllowGet);
}
  GetModelByType方法结果简单构造下然后将属性的键值对返回给js方法,然后再由js追加到界面上面。这样通过特性和反射的结合能很快完成这个小功能的设计。
  (2)类的方法上面特性的用法:
  这个用法.Net framework里面很多,如果MVC里面Filter过滤器的用法:
public class SuperLogStat : ActionFilterAttribute
{
//模块名称
private EnumModuleName moduleEnum = EnumModuleName.ModuleOther;
//功能名称
private string functionName = string.Empty;
//用户Id
private string userId = string.Empty;
public string Version
{
get { return ConfigurationManager.AppSettings["UploatStatVersion"]; }
}
public EnumModuleName ModuleEnum
{
get { return this.moduleEnum; }
set { this.moduleEnum = value; }
}
public string FunctionName
{
get { return this.functionName; }
set { this.functionName = value; }
}
//这两个方法都是父类的virtual方法,一个再return View()之前执行,一个再之后执行
//
// 摘要:
//     在执行操作方法之前由 MVC 框架调用。
//
// 参数:
//   filterContext:
//     筛选器上下文。
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
try
{
string userName = filterContext.HttpContext.User.Identity.Name;
this.userId = userName.Replace("china\", "");
}
catch (Exception)
{
this.userId = string.Empty;
}
}
//
// 摘要:
//     在执行操作结果之前由 MVC 框架调用。
//
// 参数:
//   filterContext:
//     筛选器上下文。
public override void OnResultExecuting(ResultExecutingContext filterContext)
{
UserLogUtils.LogUserStatic(this.userId, this.Version,
EnumUtils.getEnumDescByValue((int)this.moduleEnum, typeof(EnumModuleName)),
this.functionName);
}
}
在Controller里面方法上面加上特性:
1
2
3
4
5
6
//调用
[SuperLogStat(ModuleEnum = EnumModuleName.ModuleHome, FunctionName = "待审核")]
public ActionResult MyApplyToAuditing()
{
return View();
}
  这个ActionFilterAttribute这个特性用法里面有异常的拦截机制,和前面说的自定义的异常拦截是相同的。
  (3)类上面特性的用法:
  类上面特性的用法其实.Net里面也很多。比如为了避免new一个对象而使用的MEF是一个很有说服力的例子:
  在定义个类实现一个接口时:
  [Export("Impc_TB_Test", typeof(Ifc_TB_Test))]
  public class Impc_TB_Test : Ifc_TB_Test
  {
  ......
  }
  定义接口没有任何特殊:
  public interface Ifc_TB_Test
  {
  ......
  }
  然后在使用时只需要加一个[Import]标签,这个变量会在编译时自动new一个Impc_TB_Test变量:
  [Import("Impc_TB_Test")]
  Ifc_TB_Test service { get; set; }
  在使用service变量时,可以直接把它当做一个Impc_TB_Test对象来使用。是不是很方便。
  这几种常见用法都是博主用过的觉得比较好的场景,当然特性的用法肯定远不止如此,欢迎大侠们指正拍砖~~