[转载]Xml中SelectSingleNode方法中的xpath用法

mikel阅读(1079)

[转载]Xml中SelectSingleNode方法中的xpath用法 – wf520pb的专栏 – CSDN博客.

  1. 最常见的XML数据类型 有:Element, Attribute,Comment, Text.
  2. Element, 指形如<Name>Tom<Name>的节点。它可以包 括:Element, Text, Comment, ProcessingInstruction, CDATA, and EntityReference.
  3. Attribute, 指在<Employee >中的粗体部分。
  4. Comment,指形如:<!– my comment –> 的 节点。
  5. Text, 指在<Name>Tom<Name>的粗体部分。
  6. 在XML中,可以用XmlNode对象 来参照各种XML数据类型。
  7. 2.1 查询已知绝对路径的节点(集)
  8. objNodeList = objDoc.SelectNodes(“Company/Department/Employees/Employee”)
  9. 或者
  10. objNodeobjNodeList = objNode.SelectNodes(“/Company/Department/Employees/Employee”)
  11. 以上两种方法可返回一个 NodeList对象,如果要返回单个节点可使用SelectSingleNode方法,该方法如果查询到一个或多个节点,返回第一个节点;如果没有查询 的任何节点返回 Nothing。例如:
  12. objNodeobjNode = objNode.SelectSingleNode(“/Company/Department/Employees/Employee”)
  13. If Not (objNode is Nothing) then
  14. ‘- Do process
  15. End If
  16. 2.2 查询已知相对路径的节点 (集)
  17. 可 使用类似于文件路径的相对路径的方式来查询XML的数据
  18. objNode = objDoc.SelectSingleNode(“Company/Department”)
  19. objNodeobjNodeList = objNode.SelectNodes(“../Department)
  20. objNodeobjNode = objNode.SelectNode(“Employees/Employee”)
  21. 2.3 查询已知元素名的节点 (集)
  22. 在 使用不规则的层次文档时,由于不知道中间层次的元素名,可使用//符号来越过中间的节点,查询其子,孙或多层次下的其他所有元素。例如:
  23. objNodeList = objDoc.SelectNodes(“Company//Employee”)
  24. 2.4 查询属性 (attribute)节点
  25. 以上的各种方法都返回元素(element)节点(集),返回属性(attribute),只需要采用相应的方 法,在属性名前加一个@符号即可,例如:
  26. objNodeList = objDoc.SelectNodes(“Company/Department/Employees/Employee/@id”)
  27. objNodeList = objDoc.SelectNodes(“Company//@id”)
  28. 2.5 查询Text节点
  29. 使用text()来获取Text节 点。
  30. objNode = objDoc.SelectSingleNode(“Company/Department/Deparmt_Name/text()”)
  31. 2.6 查询特定条件的节点
  32. 使用[]符号来查询特定条件的节点。例 如:
  33. a. 返 回id号为 10102的Employee节点
  34. objNode = objDoc.SelectSingleNode(“Company/Department/Employees/Employee[@id=’10102’]”)
  35. b. 返回Name为Zhang Qi 的Name 节点
  36. objNode = objDoc.SelectSingleNode(“Company/Department/Employees/Employee/Name[text()=’Zhang Qi’]”)
  37. c. 返回部门含有职员22345的 部门名称节点
  38. objNode = objDoc.SelectSingleNode(“Company/Department[Employees/Employee/@id=‘22345’]/Department_Name”)
  39. 2.7 查询多重模式的节点
  40. 使用 | 符号可以获得多重模式的节 点。例如:
  41. objNodeList = objDoc.SelectNodes(“Company/Department/Department_Name | Company/Department/Manager”)
  42. 2.8 查询任意子节点
  43. 使用*符号可以返回当前节点的所有子节 点。
  44. objNodeList = objDoc.SelectNodes(“Company/*/Manager)
  45. 或者
  46. objNodeobjNodeList = objNode.ChildNodes
  47. 3 XML数据的编辑
  48. 3.1 增加一个元素的属性 (attribute)节点
  49. Dim objNodeAttr As XmlNode
  50. objNodeAttr = objDoc.CreateAttribute(“id”, Nothing)
  51. objNodeAttr.InnerXml = “101”
  52. objNode.Attributes.Append(objNodeAttr)
  53. 3.2 删除一个元素的属性
  54. objNode.Attributes.Remove(objNodeAttr)
  55. 3.3 增加一个子元素 (Element)
  56. Dim objNodeChild As XmlNode
  57. objNodeChild = objDoc.CreateElement(Nothing, “ID”, Nothing)
  58. objNodeChild.InnerXml = “101”
  59. objNode.AppendChild(objNodeChild)
  60. 3.4 删除一个子元素
  61. objNode.RemoveChild(objNodeChild)
  62. 3.5 替换一个子元素
  63. objNOde.ReplaceChild(newChild,oldChild)
  64. 4 参考数据
  65. <?xml version=“1.0” encoding=“UTF-8”?>
  66. <Company>
  67. <Department >
  68. <Department_Name>Cai WuBu</Department_Name>
  69. <Manager>Zhang Bin</Manager>
  70. <Employees>
  71. <Employee >
  72. <Employee_ID>12345</Employee_ID>
  73. <Name>Zhang Bin</Name>
  74. <Gender>male</Gender>
  75. </Employee>
  76. <Employee >
  77. <Employee_ID>10101</Employee_ID>
  78. <Name>Zhang QI</Name>
  79. <Gender>female</Gender>
  80. </Employee>
  81. <Employee >
  82. <Employee_ID>10102</Employee_ID>
  83. <Name>Zhang Xia</Name>
  84. <Gender>male</Gender>
  85. </Employee>
  86. <Employee >
  87. <Employee_ID>10201</Employee_ID>
  88. <Name>ZhangChuang</Name>
  89. <Gender>male</Gender>
  90. </Employee>
  91. <Employee >
  92. <Employee_ID>10202</Employee_ID>
  93. <Name>Zhang Jun</Name>
  94. <Gender>male</Gender>
  95. </Employee>
  96. </Employees>
  97. </Department>
  98. <Department >
  99. <Department_Name>KaiFa Bu</Department_Name>
  100. <Manager>Wang Bin</Manager>
  101. <Employees>
  102. <Employee >
  103. <Employee_ID>22345</Employee_ID>
  104. <Name>Wang Bin</Name>
  105. <Gender>male</Gender>
  106. </Employee>
  107. <Employee >
  108. <Employee_ID>20101</Employee_ID>
  109. <Name>Wang QI</Name>
  110. <Gender>female</Gender>
  111. </Employee>
  112. <Employee >
  113. <Employee_ID>20102</Employee_ID>
  114. <Name>Wang Xia</Name>
  115. <Gender>male</Gender>
  116. </Employee>
  117. <Employee >
  118. <Employee_ID>20201</Employee_ID>
  119. <Name>Wang Chuang</Name>
  120. <Gender>male</Gender>
  121. </Employee>
  122. <Employee >
  123. <Employee_ID>20201</Employee_ID>
  124. <Name>Wang Jun</Name>
  125. <Gender>male</Gender>
  126. </Employee>
  127. </Employees>
  128. </Department>
  129. </Company>

[转载]C#:XML操作类

mikel阅读(1017)

[转载]XML操作类(转) – rob_2010 – 博客园.

using System;
using System.Data;
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.Xml;

namespace PuTianCheng
{
/// <summary>
/// XmlHelper 的摘要说明
/// </summary>
public class XmlHelper
{
public XmlHelper()
{
}

/// <summary>
/// 读取数据
/// </summary>
/// <param name=”path“> 路径</param>
/// <param name=”node”>节点</param>
/// <param name=”attribute”>属性名,非空时返回该属性值,否则返回串联值</param>
/// <returns>string</returns>
/**************************************************
* 使用示列:
* XmlHelper.Read(path, “/Node”, “”)
* XmlHelper.Read(path, “/Node/Element[@Attribute=’Name’]”, “Attribute”)
************************************************/
public static string Read(string path, string node, string attribute)
{
string value = “”;
try
{
XmlDocument doc = new XmlDocument();
doc.Load(path);
XmlNode xn = doc.SelectSingleNode(node);
value = (attribute.Equals(“”) ? xn.InnerText : xn.Attributes[attribute].Value);
}
catch { }
return value;
}

/// <summary>
/// 插入数据
/// </summary>
/// <param name=”path“> 路径</param>
/// <param name=”node”>节点</param>
/// <param name=”element”>元素名,非空时插入新元素,否则在该元素中插入属性</param>
/// <param name=”attribute”>属性名,非空时插入该元素属性值,否则插入元素值</param>
/// <param name=”value”>值</param>
/// <returns></returns>
/**************************************************
* 使用示列:
* XmlHelper.Insert(path, “/Node”, “Element”, “”, “Value”)
* XmlHelper.Insert(path, “/Node”, “Element”, “Attribute”, “Value”)
* XmlHelper.Insert(path, “/Node”, “”, “Attribute”, “Value”)
************************************************/
public static void Insert(string path, string node, string element, string attribute, string value)
{
try
{
XmlDocument doc = new XmlDocument();
doc.Load(path);
XmlNode xn = doc.SelectSingleNode(node);
if (element.Equals(“”))
{
if (!attribute.Equals(“”))
{
XmlElement xe = (XmlElement)xn;
xe.SetAttribute(attribute, value);
}
}
else
{
XmlElement xe = doc.CreateElement(element);
if (attribute.Equals(“”))
xe.InnerText = value;
else
xe.SetAttribute(attribute, value);
xn.AppendChild(xe);
}
doc.Save(path);
}
catch { }
}

/// <summary>
/// 修改数据
/// </summary>
/// <param name=”path“> 路径</param>
/// <param name=”node”>节点</param>
/// <param name=”attribute”>属性名,非空时修改该节点属性值,否则修改节点值</param>
/// <param name=”value”>值</param>
/// <returns></returns>
/**************************************************
* 使用示列:
* XmlHelper.Insert(path, “/Node”, “”, “Value”)
* XmlHelper.Insert(path, “/Node”, “Attribute”, “Value”)
************************************************/
public static void Update(string path, string node, string attribute, string value)
{
try
{
XmlDocument doc = new XmlDocument();
doc.Load(path);
XmlNode xn = doc.SelectSingleNode(node);
XmlElement xe = (XmlElement)xn;
if (attribute.Equals(“”))
xe.InnerText = value;
else
xe.SetAttribute(attribute, value);
doc.Save(path);
}
catch { }
}

/// <summary>
/// 删除数据
/// </summary>
/// <param name=”path“> 路径</param>
/// <param name=”node”>节点</param>
/// <param name=”attribute”>属性名,非空时删除该节点属性值,否则删除节点值</param>
/// <param name=”value”>值</param>
/// <returns></returns>
/**************************************************
* 使用示列:
* XmlHelper.Delete(path, “/Node”, “”)
* XmlHelper.Delete(path, “/Node”, “Attribute”)
************************************************/
public static void Delete(string path, string node, string attribute)
{
try
{
XmlDocument doc = new XmlDocument();
doc.Load(path);
XmlNode xn = doc.SelectSingleNode(node);
XmlElement xe = (XmlElement)xn;
if (attribute.Equals(“”))
xn.ParentNode.RemoveChild(xn);
else
xe.RemoveAttribute(attribute);
doc.Save(path);
}
catch { }
}
}
}

==================================================

XmlFile.xml:
<?xml version=”1.0″ encoding=”utf-8″?>
<Root />

==================================================

使用方法:

string xml = Server.MapPath(“XmlFile.xml”);
//插入元素
//XmlHelper.Insert(xml, “/Root”, “Studio”, “”, “”);
//插入元素/属性
//XmlHelper.Insert(xml, “/Root/Studio”, “Site”, “Name”, “小路工作室”);
//XmlHelper.Insert(xml, “/Root/Studio”, “Site”, “Name”, “丁香鱼工作室”);
//XmlHelper.Insert(xml, “/Root/Studio”, “Site”, “Name”, “谱天城工作室”);
//XmlHelper.Insert(xml, “/Root/Studio/Site[@Name=’谱天城工作室’]”, “Master”, “”, “红尘静思”);
//插入属性
//XmlHelper.Insert(xml, “/Root/Studio/Site[@Name=’小路工作室’]”, “”, “Url”, “http://www.wzlu.com/“);
//XmlHelper.Insert(xml, “/Root/Studio/Site[@Name=’丁香鱼工作室’]”, “”, “Url”, “http://www.luckfish.net/“);
//XmlHelper.Insert(xml, “/Root/Studio/Site[@Name=’谱天城工作室’]”, “”, “Url”, “http://www.putiancheng.com/“);
//修改元素值
//XmlHelper.Update(xml, “/Root/Studio/Site[@Name=’谱天城工作室’]/Master”, “”, “RedDust”);
//修改属性值
//XmlHelper.Update(xml, “/Root/Studio/Site[@Name=’谱天城工作室’]”, “Url”, “http://www.putiancheng.net/“);
//XmlHelper.Update(xml, “/Root/Studio/Site[@Name=’谱天城工作室’]”, “Name”, “PuTianCheng Studio”);
// 读取元素值
//Response.Write(“<div>” + XmlHelper.Read(xml, “/Root/Studio/Site/Master”, “”) + “</div>”);
//读取属性值
//Response.Write(“<div>” + XmlHelper.Read(xml, “/Root/Studio/Site”, “Url”) + “</div>”);
// 读取特定属性值
//Response.Write(“<div>” + XmlHelper.Read(xml, “/Root/Studio/Site[@Name=’丁香鱼工作室’]”, “Url”) + “</div>”);
//删除属性
//XmlHelper.Delete(xml, “/Root/Studio/Site[@Name=’小路工作室’]”, “Url”);
//删除元素
//XmlHelper.Delete(xml, “/Root/Studio”, “”);

[转载]Flex全屏方法介绍

mikel阅读(1232)

[转载]Flex全屏方法介绍 – 镜涛的家 JT – 博客园.

最近在做工作流的流程设计工具相关的内容,web应用使用了比较标准的分布方式,即上、左、右的布局方式,这样做的结果就是设计工具的设计界面相对 较小,当遇到比较复杂的流程时就感觉设计的流程比较紧凑,设计工具的易用性不够好。为了解决这个问题,需要支持Flex的全屏模式。

想了下,可以通过以下方式实现Flex的全屏:

  1. 使用Flex的 FullScreen模式,具体实现方式为:
    1. 修改html- template文件夹下的index.template.html文件,在AC_FL_RunContent中增加:“allowFullScreen”, “true”;在embed中增加:allowFullScreen=”true”
    2. 通过设置stage.displayState 的值为 StageDisplayState.FULL_SCREEN来切换到全屏模式。

    缺点

    使用这种方式虽然能够将Flex切换到全屏模式,但是Flex中的InputText等 控件是无法编辑的,而且在Flex的中央会出现”Press Esc To Exist Full Screen”。因而这种方式无法满足设计需求。

    当然,中央出现的字幕还是有办法去掉的,虽然去掉之后并不能改变结果。去掉中央 的”Press Esc To Exist Full Screen”字幕的方法请见:

    http://stackoverflow.com/questions/1415436/flex-fullscreen-translate-edit-press-esc-to-exit-fullscreen-mode

    该文章讲解了去掉IE,Firefox中Flex全屏后字幕的方法。

  2. 通过showModalDialog来模拟Flex的全屏模式,showModalDialog中去掉工具栏、菜单栏、地址栏,同时将宽度 和高度设置成屏幕的宽度和高度。但是这种方式实现起来比较复杂,因为涉及到数据同步的问题,同步的方式根据项目的复杂程度和需求要求不同而不同。比较简单 的方式是在关闭showModalDialog时将数据同步主页面。因为这种方式实现复杂,容易出错,所以没有进行实现,有兴趣的朋友可以自己试试。
  3. 模拟IE的F11的全屏模式。当用户选择全屏模式的时候,模拟IE的F11 Press Down事件,隐藏掉IE的地址栏、菜单栏、工具栏等,同时将上部和左部的Frame隐藏掉,让右边的Frame全屏显示,达到预期的效果。

    IE的F11 PressDown 事件模拟方式实现如下:

    var shell = new ActiveXObject(‘WScript.Shell’)
    shell.SendKeys(‘{F11}’);

    Frame的隐藏方 法当然有很多,就不详细介绍了。

    缺 点

    这种方式需要用户修 改IE的安全选项,具体方法为:

    1. Tools > Internet options > Security > Custom Level
    2. ActiveX controls and plug-ins>Initializing and Script ActiveX controls not marked as safe>Enable

    如果没有将上面选项设置成Enable,那么会报:automation server can’t create object 错误。

[转载]从事ASP.NET开发两年多,谈谈对两三年工作经验的ASP.NET程序员的基本见解

mikel阅读(1011)

[转载]从事ASP.NET开发两年多,谈谈对两三年工作经验的ASP.NET程序员的基本见解 – 问题最终都是时间问题,烦恼其实都是自寻烦恼。 – 博客园.

粗略算来,自己从事.NET开发工作2年有余,也来谈谈自己对两三年工作经验的.NET程序员的基本见解。

我想众所周知,Microsoft的东西入门都是比较简单的,但是提高并不容易,这也就导致了很多培训机构借此良机,忽悠了大批的 甚至对编程压根不知所以然的人加入.NET的开发阵营,然后告诉他们包教,包会,包就业的三包政策。当然也有另一部分人是受过高等教育,之后出来从 事.NET开发工作,但是他们或者也是受到了一些环境的影响,在WEBFORM的开发模式中,很喜欢托拉控件,编辑模板之类的操作,甚至不知道这些控件最 终被解析成什么东西,只知道我实现了,而不问其所以然,或者是效率如何,等等。

下面谈谈几点个人愚见,希望能对两三年工作经验的.NET开发人员一点提醒:

1、Gridview之错,错,错

我想从事ASP.NET开发工作的应当有相当一部分人是做基于信息管理系统类软件开发的,这样一来可能就会经常与数据报表打交道,Gridview这个东 西可能就是在熟悉不过了。但是我想不通的是为什么有这么多的人喜欢用它呢?我总结了这种控件的缺点,如下:

(1)糟糕的编辑环境,看不见TR,TD,写样式也变得异常麻烦

代码

<asp:GridView ID=gvList runat=server CssClass=GridViewCSS Width=100% AutoGenerateColumns=False EmptyDataText=No Data>
<Columns>
<asp:TemplateField HeaderText=行号>
<ItemTemplate>
<asp:Label ID=lblRowId runat=server Text=<%# Container.DataItemIndex +1%>></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField=XXX1 HeaderText=XXX1 />
<asp:BoundField DataField=XXX2 HeaderText=XXX2 />
<asp:BoundField DataField=XXX3 HeaderText=XXX3 />
<asp:BoundField DataField=XXX4 HeaderText=XXX4 />
<asp:BoundField DataField=XXX5 HeaderText=XXX5 />
<asp:BoundField DataField=XXX6 HeaderText=XXX6 />
<asp:BoundField DataField=XXX7 HeaderText=XXX7 />
<asp:BoundField DataField=XXX8 HeaderText=XXX8 />
</Columns>
</asp:GridView>

(2)有人甚至喜欢在模板列里面编辑,我看着就一个字晕

(3)生成糟糕的HTML标签

(4)Gridview操作起来很不灵活

这句话的意思是我想要方便的控制Table的TR,TD,譬如在合并单元格,等等很多问题的处理上很不方便,以下是我用Repeater在处理合并单元格 的问题的实例:

HTML部分:

代码

<asp:Repeater ID=rpList runat=server EnableViewState=false>
<HeaderTemplate>
<%
if (rpList.Items.Count == 0)
{
%><div id=dNoData>No Data</div><%
}
else {
%>
<table>
<tr>
<th>XXX1</th>
<th>XXX2</th>
<th>XXX3</th>
<th>XXX4</th>
<th>XXX5</th>
<th>XXX6</th>
<th>XXX7</th>
</tr>
<%
}
%>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td id=tdContainerNo runat=server ><%#Eval(ContainerNo)%></td>
<td><%#Eval(X1)%></td>
<td><%#Eval(X2)%></td>
<td><%#Eval(X3)%></td>
<td><%#Eval(X4)%></td>
<td><%#Eval(X5)%></td>
<td id=tdtotal runat=server><%#Eval(X6)%></td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>

CS部分:

代码

for (int i = rpList.Items.Count 1; i > 0; i)
{
HtmlTableCell tdContainerNo_previous
= this.rpList.Items[i 1].FindControl(tdContainerNo) as HtmlTableCell;
HtmlTableCell tdContainerNo
= this.rpList.Items[i].FindControl(tdContainerNo) as HtmlTableCell;

HtmlTableCell tdtotal_previous = this.rpList.Items[i 1].FindControl(tdtotal) as HtmlTableCell;
HtmlTableCell tdtotal
= this.rpList.Items[i].FindControl(tdtotal) as HtmlTableCell;

tdContainerNo.RowSpan = (tdContainerNo.RowSpan == 1) ? 1 : tdContainerNo.RowSpan;
tdContainerNo_previous.RowSpan
= (tdContainerNo_previous.RowSpan == 1) ? 1 : tdContainerNo_previous.RowSpan;

if (tdContainerNo.InnerText == tdContainerNo_previous.InnerText)
{
tdContainerNo.Visible
= false;
tdContainerNo_previous.RowSpan
+= tdContainerNo.RowSpan;
}

tdtotal.RowSpan = (tdtotal.RowSpan == 1) ? 1 : tdtotal.RowSpan;
tdtotal_previous.RowSpan
= (tdtotal_previous.RowSpan == 1) ? 1 : tdtotal_previous.RowSpan;

if (tdContainerNo.InnerText == tdContainerNo_previous.InnerText && tdtotal.InnerText == tdtotal_previous.InnerText)
{
tdtotal.Visible
= false;
tdtotal_previous.RowSpan
+= tdtotal.RowSpan;
}
}

(5)Gridview生成的效率问题

Gridview集成了这么多的东西,我想在效率上,应该也好不到哪里去吧。

最后:当然Gridview还有诸多其他问题,这里就不一一列举了,这里只列举几个最常见得问题,让我想不通的是,有些人像Repeater这么简 单易用的控件,为什么不用,而去用Gridview这种不易掌控的控件呢?

2、为啥还有人用FormView

有些人喜欢在设计界面的时候托一个FormView控件,然后在里面放一些Textbox、Button、Label之类的服务器端控件,这样在后台操作 的时候可以统一绑定,而后呢如果会经常有一些方法,要操作FormView中的服务器端控件,那么经常有些程序员会声明很多局部变量,先从 FormView去Findcontrol这些服务器端控件赋给这些全局变量,而后去再操作这些全局变量,如下CODE:

//声明部分

private TextBox X1;
private TextBox X2;
private DropDownList X3;
private TextBox X4;
private TextBox X5;
private TextBox X6;

//赋值部分

看到这样的CODE真是让人无语,而且更让人无语的是,这些人仿佛很喜欢在模板列里面编辑内容。

3、疯狂的SQL 代码拼接

虽然说在在MS SQL 2005以后的版本中,对很长的SQL代码的执行效率,比执行由这段SQL生成的存储过程的时间多的有限,但是我们知道,存储过程是预先编译好的存放在数 据库中的,你要调用它,只需要传一个很短的字符串,加N个参数而已。而超长的SQL代码呢,你需要预先将其拼接成要执行的SQL 代码(SQL代码很长,要分为很多行写),然后传到数据库中,数据库要将其编译(可能会编译出错,你这个时候才知道),然后在执行这段SQL代码。你别说 我还真见到过很多人是这样写的,为什么不一句存储过程了事呢,改起来也很方便。

4、恐怖的viewstate

有些.NET程序员压根对viewstate不知其所以然,甚至在用webform的过程中,对其开发生成的HTML源码视而不见,下面我们来看看 viewstate产生的乱码:

这还是算小的了,数据控件在显示数量大的时候,你如果将这些东西拷贝到TXT文件中,然后看看他们的大小,是很恐怖的,虽然在开发webform过 程中,很多情况下viewstate确实帮我们节省了不少开发时间,也方便我很多,但是我要说的是,根据实际情况决定你的viewstate,能禁掉就禁 掉吧。

5、很喜欢到服务器端做验证(修正:应该 client/Server同时验证)

在开发过程中,我们会经常遇到这样的问题,验证用户输入内容的格式正不正确,例如,用户输入个EMail,我们就需要判 断输入的格式正不正确,然后有很多程序员就喜欢在CS文件中取this.txtXX.Text的内容作验证,然后弄个弹出框提示用户,殊不知这个简单的验 证,还要跑到Server上做,为什么不写个JS提示一下呢,不是很简单吗?

6、不知其所以然

很多两三经验的.NET程序在开发过程中托控件托习惯了,都不知道最后控件被解析什么样子,甚至不知道自己开发的 ASP.NET程序的工作流程,原理,完全被Microsoft傻瓜化了,只知道我这样做就实现了功能,却不知道你这样做为什么能实现。这是一个很恐怖的 信号,希望活跃在.NET的兄弟们在开发程序的时候能知其然,知其所以然。

7、吃老本,不学习新的技术

众所周知,Microsoft的技术是更新很快的,有些人会抱怨跟不上节奏,索性不问,老是沉迷于过去式中,认为老的 技术成熟,而且自己很熟悉,殊不知,这是一种退化的表现。我们应该明白,新事物的出 现,肯定是为了补充旧事物的所缺少的地方,是为了更完美,更便捷的处理实际问题,我们不能一概的去否定它,而应该去了解他,学习他。Linq不是很好用 吗,但是到现在还发现很多人对Linq是一知半解。

今天就写到这里吧,以上内容是我经常见到的,所以写在这里,希望给两三工作经验的程序员朋友提个醒!

作者:Tonny Yang
出处:http://www.cnblogs.com/yangtongnet/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

[转载]SaaS数据存储解决方案

mikel阅读(1047)

[转载]SaaS数据存储解决方案 – hushouqi – 博客园.

引言:

本文提出了一个SaaS数据存储解决方案。为方便理解请花几分钟时间浏览上一篇《SaaS平台概要设计》http://www.cnblogs.com/hushouqi/archive/2010/06/10/1755371.html 上一篇是对层次与对象的定义,很简单。

概要:

针对于不同的用 户,建立独立的数据区域是比较理想的方式。独立的数据区域有几个好处:不影响检索速度;简化开发难度;易扩展;增强数据安全性。在这里,只提供数据库的方 式,对不同的用户建立不同的数据库。数据库种类不限制,SQLServer,oracle,mySQL等等。

数据存储分层:

图示很直观。简单概括一下数据分为两类,平台数据用 户数据。平台数据包括群组,用户,角色等信息。用户数据是应用系统的数据。每个企业拥有自己的数据库。

DataProvider组 件:

接上篇介绍的类,详细设计DataProvider组件。

要实现用户各自存储数据,最关键的是要为各用户提供数据源(DataSource)配置。

数据源接口定义如下

public interface IDataSource {

string OrganizationID { get;set;}

string ConnString {get;set;}

string DBType { get;set;}

}

此接口定义了数据库连接字符,数据库类型和组织ID.

为每个组织定义默认的DataSource.

组织对数据源的接口定义

public class Organization {

public IDataSource GetDefaultDataSource{ get;}

}

组织拥有默认的IDataSource

DataProvider的定义

public interface IDataProvider

{

public DbConnection DbConncetion { get;}

public DbCommand DbCommand { get;}

public DbDataAdapter DbDataAdaper { get;}

}

此类是对数据库执行类的封装。可以使用抽象工厂模式对 其进行扩展,实现对不同种类数据库的封装。在这里不详细介绍了,因为这部分的内容类似文章很多,微软也做过对其封装。

public class DataProviderFactory

{

public static IDataProvider CreateDataProvider(IDataSource ds)

}

此类是个工具类,提供了一个静态方法,根据IDataSource创建IDataProvider实例。

到这里,接口大体上就清晰了。要对用户自身数据进行操 作,只要获取到当前用户的IDataProvider即可。而创建一个IDataProvider需要依赖于一个IDataSource实 例。IDataSource实例可以通过Organization对象获取到。

IDataSource对象构造顺序:

1. 用户成功登录,通过User查找Organization.

2. 通过Organization查找自身的IDataSource

3. IDataSource保存至Session

总结:

以上对象的数据都在公共数据层保存,在登录后,获取到 用户自身的IDataProvider

应用层就使用IDataProvider进行各项应用存储了。

[转载]JQuery另类视角-动态执行脚本的BUG

mikel阅读(1185)

[转载]JQuery另类视角-动态执行脚本的BUG – Kevin-moon – 博客园.

最近再用JQuery写一些东西,昨天突然出了个很奇怪的问题:

我通过Ajax请求服务器上的数据(包括html和script),然后将请求的数据动态加载到页面的一个div中,这其实是个很简单的程序, 首次执行是很顺利,但是当你执行这个相同动作两次之后,html元素依然可以顺利加载,不过script脚本就失效了!

使用的是JQuery的1.4.1版本,加载的程序是用JQuery中的$(…).append()方法。类试代码如下:

$(#testdiv).append(<script type=’text/JavaScript’> a = 1 ;alert(a); + < + /script>);

你执行后会发现,前两次能很成功的弹出提示框,但是从第三次开始就失效了!

为什么?JavaScript本身不可能不支持这种程序的,难道是jQuery程序的BUG吗?!是的,该BUG已经在1.4.2版本中进行了 修复,你可以换成jQuery-1.4.2版本来试下。真是郁闷,这个问题害的我查了一个晚上才发现…..

下面让我们分析下这个BUG的原因:

首先看下append函数中主要的执行流程,

执行script脚本的程序是在domManip函数中,大概的逻辑如下:

导致该问题的函数是buildFragment函数,对比下该函数在这两个版本的代码,

jQuery-1.4.1

function buildFragment( args, nodes, scripts ) {
var fragment, cacheable, cacheresults, doc;

// webkit does not clone ‘checked’ attribute of radio inputs on cloneNode, so don’t cache if string has a checked
if (args.length === 1 && typeof args[0] === string && args[0].length < 512 && args[0].indexOf(<option) < 0
&& (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {
cacheable
= true;
cacheresults
= jQuery.fragments[ args[0] ];
if ( cacheresults ) {
if ( cacheresults !== 1 ) {
fragment
= cacheresults;
}
}
}

if ( !fragment ) {
doc
= (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document);
fragment
= doc.createDocumentFragment();
jQuery.clean( args, doc, fragment, scripts );
}

if ( cacheable ) {
jQuery.fragments[ args[
0] ] = cacheresults ? fragment : 1;
}

return { fragment: fragment, cacheable: cacheable };
}

jquery-1.4.2

function buildFragment( args, nodes, scripts ) {
var fragment, cacheable, cacheresults,
doc
= (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document);

// Only cache “small” (1/2 KB) strings that are associated with the main document
// Cloning options loses the selected state, so don’t cache them
// IE 6 doesn’t like it when you put <object> or <embed> elements in a fragment
// Also, WebKit does not clone ‘checked’ attributes on cloneNode, so don’t cache
if ( args.length === 1 && typeof args[0] === string && args[0].length < 512 && doc === document &&
!rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {

cacheable = true;
cacheresults
= jQuery.fragments[ args[0] ];
if ( cacheresults ) {
if ( cacheresults !== 1 ) {
fragment
= cacheresults;
}
}
}

if ( !fragment ) {
fragment
= doc.createDocumentFragment();
jQuery.clean( args, doc, fragment, scripts );
}

if ( cacheable ) {
jQuery.fragments[ args[
0] ] = cacheresults ? fragment : 1;
}

return { fragment: fragment, cacheable: cacheable };
}

仔细看完这两段代码后,会发现这个函数内设置scripts的程序是jQuery.clean( args, doc, fragment, scripts ),这行代码在执行之前有个判断:如果该传入的脚本数据允许支持缓存,并且数据在缓存jQuery.fragments中存在,那么这行代码是跳过的!否 则,该行代码执行,设置scripts数据。

现在把关注点放到”允许支持缓存”这句话上,比较这两个版本对于该程序的不同。!rnocache.test( args[0] ),这是1.4.2版本中多加的一行代码。终于找到它,它是这个BUG解决的关键所在。让我们看下这个rnocache 的正则表达式:

rnocache = /<script|<object|<embed|<option|<style/i,

看了这么多发现原因了吗!原来1.4.1版本会对script脚本进行缓存,一旦script缓存在脚本后,该脚本中的程序是不会执行的,而 1.4.2多加了上面的正则,目的就是对script等这些数据不进行缓存,只要存在就会去执行!

[转载]C#通用的序列化方法

mikel阅读(1081)

[转载]通用的序列化方法 – 邹泽栋 – 博客园.

01 /// <summary>
02 /// 序列化数据
03 /// </summary>
04 /// <param name="obj">对象</param>
05 /// <returns>二进制流</returns>
06 private byte[] GetBinaryFormatSerialize(object obj)
07 {
08 //创建支持存储 区为内存的流
09 MemoryStream Memory = new MemoryStream();
10 //以二进制格式将整个连接对象图形序列化和反序列化
11 BinaryFormatter formatter = new BinaryFormatter();
12 //将对象序列化为附加所提供标题的给定流
13 formatter.Serialize(Memory, obj);
14 byte[] buff = Memory.ToArray();
15 Memory.Close();
16 Memory.Dispose();
17 return buff;
18 }
19
20 /// <summary>
21 /// 反序列化对象
22 /// </summary>
23 /// <typeparam name="T">类型</typeparam>
24 /// <param name="buff">二进制数据</param>
25 /// <returns>反序列后结果</returns>
26 private T RetrieveDeserialize<T>(byte[] buff)
27 {
28 //创建支持存储 区为内存的流
29 MemoryStream Memory = new MemoryStream();
30 //以二进制格式将整个连接对象图形序列化和反序列化。
31 BinaryFormatter formatter = new BinaryFormatter();
32 return (T)formatter.Deserialize(new MemoryStream(buff));
33 }
34 <pre class="brush:csharp"> //调用
35 DataTable dt = new DataTable();
36 #region 序列化
37 byte[] buff = GetBinaryFormatSerialize(dt);
38 #endregion
39
40 #region  反序列化
41 dt = RetrieveDeserialize<DataTable>(buff);
42 #endregion
43 </pre>

[转载]mysql “group by ”与"order by"的研究--分类中最新的内容

mikel阅读(1018)

[转载]mysql “group by ”与”order by”的研究--分类中最新的内容 – 中山php – 博客园.

这两天让一个数据查询难了。主要是对group by 理解的不够深入。才出现这样的情况
这种需求,我想很多人都遇到过。下面是我模拟我的内容表

我现在需要取出每个分类中最新的内容

select * from test group by category_id order by `date`

结果如下

明显。这不是我想要的数据,原因是msyql已经的执行顺序是

引用
写的顺序:select … from… where…. group by… having… order by..
执行顺序:from… where…group by… having…. select … order by…

所以在order by拿到的结果里已经是分组的完的最后结果。
由from到where的结果如下的内容。

到group by时就得到了根据category_id分出来的多个小组


到了select的时候,只从上面的每个组里取第一条信息结果 会如下

即使order by也只是从上面的结果里进行排序。并不是每个分类的最新信息。
回 到我的目的上 --分类中最新的信息
根据上面的分析,group by到select时只取到分组里的第一条信息。有两个解决方法
1,where+group by(对小组进行排序)
2,从form返回的数据下手脚(即用子查询)

由where+group by的解决方法
对group by里的小组进行排序的函数我只查到group_concat()可以进行排序,但group_concat的作用是将小组里的字段里的值进行串联起来。

select group_concat(id order by `date` desc) from `test` group by category_id


再改进一下

select * from `test` where id in(select SUBSTRING_INDEX(group_concat(id order by `date` desc),’,’,1) from `test` group by category_id ) order by `date` desc

子查询解决方案

select * from (select * from `test` order by `date` desc) `temp`  group by category_id order by `date` desc

原文地址

http://atim.cn/read.php/620.htm

[转载]asp.net mvc 2被遗忘的Html.AntiForgeryToken()

mikel阅读(1101)

[转载]asp.net mvc 2被遗忘的 – ZilchWei-专注asp.net mvc – 博客园.

<%:Html.AntiForgeryToken() %>

我们可以称作令牌认证.

操作系统:windows server 2008 r2

本文来自zilchwei.转载请注明出处!

开发软件:visual studio 2010中文版+ASP.NET mvc 2.0中文版.

浏览器信息:IE8

我们在学习ASP.NET mvc的时候往往在考虑

Index的view输入数据 然后POST到AboutController做处理

我们做一个简单的数据输入页面

index的html代码如下:

<%:Html.BeginForm("About","Home")%> 用户名:<input type="text" name="Zilhwei" /> <%Html.EndForm(); %>
 本文来自zilchwei.转载请注明出处!

很简单 我们输入一个用户名然后Post到About这个Controller去做一个处理

当然 我们这里会生成HTML代码 如果代码被修改会怎么样呢?这个不做对的探讨.

我们对代码进行修改

<%:Html.BeginForm("About","Home")%> <%:Html.AntiForgeryToken() %> 用户名:<input type="text" name="Zilchwei" /> <%Html.EndForm(); %>

我们的view生成了这样的html代码

代码

<form action="/Home/About" method="post"><input name="__RequestVerificationToken" type="hidden" value="YUqLzBScUslwvdrKa50t4TEy3qyPXWFUH96MruwL6Uf10PcoM3kEi2cgAFBISRRE" /> 用户名:<input type="text" name="Zilchwei" /> </form>

当然 我们接收的AboutConrtoller也要做出相应的修改.

[HttpPost] [ValidateAntiForgeryToken] public ActionResult About() { return View(); }

这里需要说明的是ValidateAntiForgeryToken其实就是一个actionfilter

用户验证是否为指定页面提交的值.

本文来自zilchwei.转载请注明出处!

这样测试肯定是没问题的

那么我们测试下如果未生成令牌会怎么样,修改index的代码

<%:Html.BeginForm("About","Home")%> 用户名:<input type="text" name="Zilchwei" /> <%Html.EndForm(); %>

我们验证结果如图

就这样  欢迎大家和我一起交流.端午节快乐!

本文来自zilchwei.转载请注明出处!

[转载]使用ASP.NET MVC 2编程时遇到的两个小问题

mikel阅读(923)

[转载]使用ASP.NET MVC 2编程时遇到的两个小问题 – 今天你开心么,朋友? – 博客园.

使用MVC2开发一个web应用的时候,遇到两个小问题,这里做下记录:

1 通过ADO.NET Entity Data Model设计数据库结构的时候,一般情况下,如果想使我们新添加或修改 的内容生效的话,需要首先自动生成数据库脚本,并连接数据库进行执行,以保证数据库的同步,同步时,没有必要去删除原有数据库内容,直接更新即可,但是此 时如果想通过controller来自动创建一个view的话,在强类型下拉框中,是没有我们新添加的类的,这个时候我们可以编译或调试一下,新添加的类就会出现了,否则就 没办法去生成自动的前台代码啦~

2 通过ADO.NET Entity Data Model设计数据库表结构的时候,如果涉及到修改表字段的约束属性的 话,可能会引发虽然我们的修改已经更新到数据库,而且代码页已经保证正确,但是,每次执行XXXRepostory.Save()的时候,都会引发异常,提示内容大概就是说某某字段不符合某某约束,我遇到的是不能插入Null到某某字段,昨晚尝试了N次,但依旧出现相同问题,今天我重新编写了一个一模一样的类, 然后更新,并做排除性验证,奇怪的是昨天的问题自己解决了……真汗,根据第一条的经验来看,可能就是因为MVC架构中某某地方没有完全按照我的更新进行处理,于是导致了不一致的问题,重启,重编译后可能就一致了……

有的时候,有些问题还是挺奇怪的,不过就这次的经历来讲,自己 也更加明白了一个道理:架构让开发变得简单,但是通过牺牲自由性作为代价的,同时我们还要对架构是否正常工作保有一份责任!这也说明我们在享受架构带给我 们的便利的同时,一定要时刻保持怀疑的态度,尽可能多地去了解架构的细节,否则我们的麻烦亦会很多~

希望能对你有所帮助~