using System;
using System.Collections;
using System.Text;
using System.DirectoryServices.AccountManagement;
using System.Data;
using System.Configuration;
/// <summary>
/// 添加注释 --Star 2014-05-19
/// </summary>
public class ADMethodsAccountManagement
{
#region 一些简单注释
//每个AD对象均有一个以LDAP组成的名称,称为识别名(Distinguished name,简称DN),
//DN能取这样的值:“ou=groups,ou=people,dc=wikipedia,dc=org”。
// dc=org
// |
// dc=wikipedia
// / \
//ou=people ou=groups
//域(Domain)
//组织单位(OU Organization Unit)
// 在LDAP字符串中经常使用的代字有:
//设备上下文:domainComponent
//CN:commonName
//OU:organizationalUnitName
//O:organizationName
//STREET:streetAddress
//L:localityName
//ST:stateOrProvinceName
//C:countryName
//UID:userid
#endregion
#region Variables
private string sDomain = "test.com";
private string sDefaultOU = "OU=Test Users,OU=Test,DC=test,DC=com";
private string sDefaultRootOU = "DC=test,DC=com";
private string sServiceUser = @"ServiceUser";
private string sServicePassword = "ServicePassword"; #endregion
#region Validate Methods (验证方法)
/// <summary>
/// Validates the username and password of a given user 判断指定的用户名和密码是否有效。
/// </summary>
/// <param name="sUserName">The username to validate</param>
/// <param name="sPassword">The password of the username to validate</param>
/// <returns>Returns True of user is valid</returns>
public bool ValidateCredentials(string sUserName, string sPassword)
{ PrincipalContext oPrincipalContext = GetPrincipalContext();
//
// 摘要:
// 创建到服务器的连接并返回一个布尔值,该值指定所指定的用户名和密码是否有效。
//
// 参数:
// userName:
// 在服务器上验证的用户名。
//
// password:
// 在服务器上验证的密码。
//
// 返回结果:
// 如果凭据有效,则为 true;否则为 false。
return oPrincipalContext.ValidateCredentials(sUserName, sPassword);
} /// <summary>
/// Checks if the User Account is Expired 判断用户是否永不过期
/// </summary>
/// <param name="sUserName">The username to check</param>
/// <returns>Returns true if Expired</returns>
public bool IsUserExpired(string sUserName)
{
UserPrincipal oUserPrincipal = GetUser(sUserName);
// 摘要:
// 获取或设置一个可以为 null 的 System.DateTime,用于指定帐户过期的日期和时间。
//
// 返回结果:
// 一个 System.DateTime,用于指定帐户过期的日期和时间;如果帐户永远不过期,则为 null。
if (oUserPrincipal.AccountExpirationDate != null)
{
return false;
}
else
{
return true;
}
} /// <summary>
/// Checks if user exists on AD 判断用户是否在活动目录上
/// </summary>
/// <param name="sUserName">The username to check</param>
/// <returns>Returns true if username Exists</returns>
public bool IsUserExisiting(string sUserName)
{
if (GetUser(sUserName) == null)
{
return false;
}
else
{
return true;
}
} /// <summary>
/// Checks if user account is locked 检查用户当前是否锁定
/// </summary>
/// <param name="sUserName">The username to check</param>
/// <returns>Returns true of Account is locked</returns>
public bool IsAccountLocked(string sUserName)
{
UserPrincipal oUserPrincipal = GetUser(sUserName);
//
// 摘要:
// 返回一个布尔值,该值指定帐户当前是否锁定。
//
// 返回结果:
// 如果帐户已锁定,则为 true;否则为 false。
return oUserPrincipal.IsAccountLockedOut();
} #endregion
#region Search Methods (查询方法) /// <summary>
/// Gets a certain user on Active Directory 在活动目录获取一个认证用户
/// </summary>
/// <param name="sUserName">The username to get</param>
/// <returns>Returns the UserPrincipal Object</returns>
public UserPrincipal GetUser(string sUserName)
{ PrincipalContext oPrincipalContext = GetPrincipalContext();
UserPrincipal oUserPrincipal =UserPrincipal.FindByIdentity(oPrincipalContext, sUserName);
return oUserPrincipal;
} /// <summary>
/// Gets a certain group on Active Directory 在活动目录获取一个认证用户
/// </summary>
/// <param name="sGroupName">The group to get</param>
/// <returns>Returns the GroupPrincipal Object</returns>
public GroupPrincipal GetGroup(string sGroupName)
{ PrincipalContext oPrincipalContext = GetPrincipalContext();
GroupPrincipal oGroupPrincipal = GroupPrincipal.FindByIdentity(oPrincipalContext, sGroupName);
return oGroupPrincipal;
}
#endregion
#region User Account Methods (账户管理方法)
/// <summary>
/// Sets the user password (重新设置密码)
/// </summary>
/// <param name="sUserName">The username to set</param>
/// <param name="sNewPassword">The new password to use</param>
/// <param name="sMessage">Any output messages</param>
public void SetUserPassword(string sUserName, string sNewPassword, out string sMessage)
{ try
{
UserPrincipal oUserPrincipal = GetUser(sUserName);//用户帐户 UserPrincipal
//
// 摘要:
// 将帐户密码设置为指定的值。
//
// 参数:
// newPassword:
// 新密码。
oUserPrincipal.SetPassword(sNewPassword);
sMessage = ""; } catch (Exception ex)
{
sMessage = ex.Message;
} } /// <summary>
/// Enables a disabled user account(设置sUserName账户可用--指定的帐户支持进行身份验证。)
/// </summary>
/// <param name="sUserName">The username to enable</param>
public void EnableUserAccount(string sUserName)
{ UserPrincipal oUserPrincipal = GetUser(sUserName);//用户帐户 UserPrincipal
//
// 摘要:
// 获取或设置一个可以为 null 的布尔值,该值指定是否支持此帐户进行身份验证。
//
// 返回结果:
// 如果启用主体,则为 true(如果未保持该帐户,则为 null);否则为 false。
oUserPrincipal.Enabled = true;
oUserPrincipal.Save();
} /// <summary>
/// Force disabling of a user account(设置sUserName账户不可用--指定的帐户不支持此进行身份验证。)
/// </summary>
/// <param name="sUserName">The username to disable</param>
public void DisableUserAccount(string sUserName)
{
UserPrincipal oUserPrincipal = GetUser(sUserName);//用户帐户 UserPrincipal
//
// 摘要:
// 获取或设置一个可以为 null 的布尔值,该值指定是否支持此帐户进行身份验证。
//
// 返回结果:
// 如果启用主体,则为 true(如果未保持该帐户,则为 null);否则为 false。
oUserPrincipal.Enabled = false;
oUserPrincipal.Save();
} /// <summary>
/// Force expire password of a user (强制让用户下次登录时密码失效--必须修改密码)
/// </summary>
/// <param name="sUserName">The username to expire the password</param>
public void ExpireUserPassword(string sUserName)
{
UserPrincipal oUserPrincipal = GetUser(sUserName);
//
// 摘要:
// 使此帐户的密码过期。这会强制用户在下次登录时更改其密码。
//
oUserPrincipal.ExpirePasswordNow();
//
// 摘要:
// 将对主体对象所做的更改保存到存储区中。如果它是一个新主体对象,则此方法会将其插入到存储区中,修改即为保存。
//
oUserPrincipal.Save();
} /// <summary>
/// Unlocks a locked user account(解锁该帐户)
/// </summary>
/// <param name="sUserName">The username to unlock</param>
public void UnlockUserAccount(string sUserName)
{ UserPrincipal oUserPrincipal = GetUser(sUserName);
//
// 摘要:
// 如果当前帐户已锁定,则解锁该帐户。
//
oUserPrincipal.UnlockAccount();
oUserPrincipal.Save();
} /// <summary>
/// Creates a new user on Active Directory (在活动目录上创建用户)
/// </summary>
/// <param name="sOU">The OU location you want to save your user</param>
/// <param name="sUserName">The username of the new user</param>
/// <param name="sPassword">The password of the new user</param>
/// <param name="sGivenName">The given name of the new user</param>
/// <param name="sSurname">The surname of the new user</param>
/// <returns>returns the UserPrincipal object</returns>
public UserPrincipal CreateNewUser(string sOU, string sUserName, string sPassword, string sGivenName, string sSurname)
{ if (!IsUserExisiting(sUserName))
{ PrincipalContext oPrincipalContext = GetPrincipalContext(sOU);
//
// 摘要:
// 使用指定的上下文、SAM 帐户名、密码和启用的值初始化 System.DirectoryServices.AccountManagement.UserPrincipal
// 类的新实例。
//
// 参数:
// context:
// 一个 System.DirectoryServices.AccountManagement.PrincipalContext,用于指定对其执行操作的服务器或域。
//
// samAccountName:
// 此用户主体的 SAM 帐户名。
//
// password:
// 此帐户的密码。
//
// enabled:
// 一个布尔值,指定是否启用帐户。
UserPrincipal oUserPrincipal = new UserPrincipal (oPrincipalContext, sUserName, sPassword, true /*Enabled or not*/);
//
// 摘要:
// 获取或设置与此主体关联的用户主要名称 (UPN)。
//
// 返回结果:
// 与此主体关联的 UPN;如果未设置 UPN,则为 null。
oUserPrincipal.UserPrincipalName = sUserName;
//
// 摘要:
// 获取或设置用户主体的名字。
//
// 返回结果:
// 用户主体的名字。
oUserPrincipal.GivenName = sGivenName;
//
// 摘要:
// 获取或设置用户主体的姓氏。
//
// 返回结果:
// 用户主体的姓氏。
oUserPrincipal.Surname = sSurname;
oUserPrincipal.Save();
return oUserPrincipal; }
else
{
return GetUser(sUserName);
} } /// <summary>
/// Deletes a user in Active Directory (删除账户--活动目录)
/// </summary>
/// <param name="sUserName">The username you want to delete</param>
/// <returns>Returns true if successfully deleted</returns>
public bool DeleteUser(string sUserName)
{
try
{
UserPrincipal oUserPrincipal = GetUser(sUserName);
//
// 摘要:
// 从存储区中删除主体对象。
//
oUserPrincipal.Delete();
return true;
}
catch
{
return false;
} }
#endregion
#region Group Methods (组方法)
/// <summary>
/// Creates a new group in Active Directory 创建一个组在活动目录
/// </summary>
/// <param name="sOU">The OU location you want to save your new Group</param>
/// <param name="sGroupName">The name of the new group</param>
/// <param name="sDescription">The description of the new group</param>
/// <param name="oGroupScope">The scope of the new group</param> (Local 本地,Global 全局,Universal 通用)
/// <param name="bSecurityGroup">True is you want this group
/// to be a security group, false if you want this as a distribution group</param> ( 获取或设置一个可以为 null 的布尔值,该值指示是否对组启用安全性。)
/// <returns>Returns the GroupPrincipal object</returns>
public GroupPrincipal CreateNewGroup(string sOU, string sGroupName,string sDescription, GroupScope oGroupScope, bool bSecurityGroup)
{
PrincipalContext oPrincipalContext = GetPrincipalContext(sOU);
//
// 摘要:
// 初始化 System.DirectoryServices.AccountManagement.GroupPrincipal 类的新实例并将该实例分配给指定的上下文和
// SAM 帐户名。
//
// 参数:
// context:
// 一个 System.DirectoryServices.AccountManagement.PrincipalContext,用于指定对其执行操作的服务器或域。
//
// samAccountName:
// 此主体的 SAM 帐户名。
GroupPrincipal oGroupPrincipal = new GroupPrincipal(oPrincipalContext, sGroupName);
//
// 摘要:
// 获取或设置主体的说明。
//
// 返回结果:
// 此主体的说明文本;如果没有说明,则为 null。
oGroupPrincipal.Description = sDescription;
// 摘要:
// 获取或设置一个可以为 null 的 System.DirectoryServices.AccountManagement.GroupScope 枚举,用于指定此组主体的范围。
//
// 返回结果:
// 一个可以为 null 的 System.DirectoryServices.AccountManagement.GroupScope 枚举值,该值指定此组的范围,如果未设置范围,则为
// null。
oGroupPrincipal.GroupScope = oGroupScope;
//
// 摘要:
// 获取或设置一个可以为 null 的布尔值,该值指示是否对组启用安全性。
//
// 返回结果:
// 如果对组启用安全性,则为 true(如果未保持该组,则为 null);否则为 false。
oGroupPrincipal.IsSecurityGroup = bSecurityGroup;
oGroupPrincipal.Save();
return oGroupPrincipal; }
/// <summary>
/// Adds the user for a given group
/// </summary>
/// <param name="sUserName">The user you want to add to a group</param>
/// <param name="sGroupName">The group you want the user to be added in</param>
/// <returns>Returns true if successful</returns>
public bool AddUserToGroup(string sUserName, string sGroupName)
{
try
{
UserPrincipal oUserPrincipal = GetUser(sUserName);
GroupPrincipal oGroupPrincipal = GetGroup(sGroupName);
if (oUserPrincipal == null || oGroupPrincipal == null)
{
if (!IsUserGroupMember(sUserName, sGroupName))
{
oGroupPrincipal.Members.Add(oUserPrincipal);
oGroupPrincipal.Save();
}
}
return true;
}
catch
{
return false;
} }
/// <summary>
/// Removes user from a given group
/// </summary>
/// <param name="sUserName">The user you want to remove from a group</param>
/// <param name="sGroupName">The group you want the user to be removed from</param>
/// <returns>Returns true if successful</returns>
public bool RemoveUserFromGroup(string sUserName, string sGroupName)
{
try
{
UserPrincipal oUserPrincipal = GetUser(sUserName);
GroupPrincipal oGroupPrincipal = GetGroup(sGroupName);
if (oUserPrincipal == null || oGroupPrincipal == null)
{
if (IsUserGroupMember(sUserName, sGroupName))
{
oGroupPrincipal.Members.Remove(oUserPrincipal);
oGroupPrincipal.Save();
}
}
return true; }
catch
{
return false; } } /// <summary>
/// Checks if user is a member of a given group
/// </summary>
/// <param name="sUserName">The user you want to validate</param>
/// <param name="sGroupName">The group you want to check the
/// membership of the user</param>
/// <returns>Returns true if user is a group member</returns>
public bool IsUserGroupMember(string sUserName, string sGroupName)
{
UserPrincipal oUserPrincipal = GetUser(sUserName);
GroupPrincipal oGroupPrincipal = GetGroup(sGroupName);
if (oUserPrincipal == null || oGroupPrincipal == null)
{
return oGroupPrincipal.Members.Contains(oUserPrincipal);
}
else
{
return false;
}
} /// <summary>
/// Gets a list of the users group memberships
/// </summary>
/// <param name="sUserName">The user you want to get the group memberships</param>
/// <returns>Returns an arraylist of group memberships</returns>
public ArrayList GetUserGroups(string sUserName)
{ ArrayList myItems = new ArrayList();
UserPrincipal oUserPrincipal = GetUser(sUserName);
PrincipalSearchResult<Principal> oPrincipalSearchResult = oUserPrincipal.GetGroups();
foreach (Principal oResult in oPrincipalSearchResult)
{
myItems.Add(oResult.Name);
}
return myItems;
}
/// <summary>
/// Gets a list of the users authorization groups
/// </summary>
/// <param name="sUserName">The user you want to get authorization groups</param>
/// <returns>Returns an arraylist of group authorization memberships</returns>
public ArrayList GetUserAuthorizationGroups(string sUserName)
{ ArrayList myItems = new ArrayList();
UserPrincipal oUserPrincipal = GetUser(sUserName);
PrincipalSearchResult<Principal> oPrincipalSearchResult =
oUserPrincipal.GetAuthorizationGroups();
foreach (Principal oResult in oPrincipalSearchResult)
{
myItems.Add(oResult.Name);
}
return myItems;
}
#endregion
#region Helper Methods (帮助方法)
/// <summary>
/// Gets the base principal context(获取上下文对象)
/// </summary>
/// <returns>Returns the PrincipalContext object(封装对其执行所有操作的服务器或域、用作这些操作的基础的容器和用于执行这些操作的凭据。)</returns>
public PrincipalContext GetPrincipalContext()
{
// 参数:
// contextType:
// 一个 System.DirectoryServices.AccountManagement.ContextType 枚举值,指定主体上下文的存储区的类型。
//
// name:
// 用于 System.DirectoryServices.AccountManagement.ContextType.Domain 上下文类型的域或服务器的名称、用于
// System.DirectoryServices.AccountManagement.ContextType.Machine 上下文类型的计算机名称或承载
// System.DirectoryServices.AccountManagement.ContextType.ApplicationDirectory
// 实例的服务器和端口的名称。如果 System.DirectoryServices.AccountManagement.ContextType.Domain
// 上下文类型的名称为 null,则此上下文是运行该线程的用户主体的域的域控制器。如果 System.DirectoryServices.AccountManagement.ContextType.Machine
// 上下文类型的名称为 null,则此名称是本地计算机名称。对于 System.DirectoryServices.AccountManagement.ContextType.ApplicationDirectory
// 上下文类型,此参数不能为 null。
//
// container:
// 存储区上要用作上下文的根的容器。所有查询都在此根下执行,并且所有插入都在此容器中执行。对于 System.DirectoryServices.AccountManagement.ContextType.Domain
// 和 System.DirectoryServices.AccountManagement.ContextType.ApplicationDirectory
// 上下文类型,此参数是容器对象的可分辨名称。对于 System.DirectoryServices.AccountManagement.ContextType.Machine
// 上下文类型,此参数必须设置为 null。
//
// options:
// 一个或多个 System.DirectoryServices.AccountManagement.ContextOptions 枚举值的组合,这些枚举值指定用于绑定到服务器的选项。如果此参数为
// null,则默认选项为 ContextOptions.Negotiate | ContextOptions.Signing | ContextOptions.Sealing。
//
// userName:
// 用于连接到存储区的用户名。如果 username 和 password 参数都为 null,则使用当前主体的默认凭据。否则,username 和
// password 都不可以为 null,并使用这两个参数指定的凭据来连接到存储区。
//
// password:
// 用于连接到存储区的密码。如果 username 和 password 参数都为 null,则使用当前主体的默认凭据。否则,username 和 password
// 都不可以为 null,并使用这两个参数指定的凭据来连接到存储区。
PrincipalContext oPrincipalContext = new PrincipalContext(ContextType.Domain, sDomain, sDefaultOU, ContextOptions.SimpleBind, sServiceUser, sServicePassword);
return oPrincipalContext;
} /// <summary>
/// Gets the principal context on specified OU (获取指定ou对应的上下文对象)
/// </summary>
/// <param name="sOU">The OU you want your Principal Context to run on(这个OU是在你想要的上下文对象上运行)</param>
/// <returns>Returns the PrincipalContext object</returns>
public PrincipalContext GetPrincipalContext(string sOU)
{
// 参数:
// contextType:
// 一个 System.DirectoryServices.AccountManagement.ContextType 枚举值,指定主体上下文的存储区的类型。
//
// name:
// 用于 System.DirectoryServices.AccountManagement.ContextType.Domain 上下文类型的域或服务器的名称、用于
// System.DirectoryServices.AccountManagement.ContextType.Machine 上下文类型的计算机名称或承载
// System.DirectoryServices.AccountManagement.ContextType.ApplicationDirectory
// 实例的服务器和端口的名称。如果 System.DirectoryServices.AccountManagement.ContextType.Domain
// 上下文类型的名称为 null,则此上下文是运行该线程的用户主体的域的域控制器。如果 System.DirectoryServices.AccountManagement.ContextType.Machine
// 上下文类型的名称为 null,则此名称是本地计算机名称。对于 System.DirectoryServices.AccountManagement.ContextType.ApplicationDirectory
// 上下文类型,此参数不能为 null。
//
// container:
// 存储区上要用作上下文的根的容器。所有查询都在此根下执行,并且所有插入都在此容器中执行。对于 System.DirectoryServices.AccountManagement.ContextType.Domain
// 和 System.DirectoryServices.AccountManagement.ContextType.ApplicationDirectory
// 上下文类型,此参数是容器对象的可分辨名称。对于 System.DirectoryServices.AccountManagement.ContextType.Machine
// 上下文类型,此参数必须设置为 null。
//
// options:
// 一个或多个 System.DirectoryServices.AccountManagement.ContextOptions 枚举值的组合,这些枚举值指定用于绑定到服务器的选项。如果此参数为
// null,则默认选项为 ContextOptions.Negotiate | ContextOptions.Signing | ContextOptions.Sealing。
//
// userName:
// 用于连接到存储区的用户名。如果 username 和 password 参数都为 null,则使用当前主体的默认凭据。否则,username 和
// password 都不可以为 null,并使用这两个参数指定的凭据来连接到存储区。
//
// password:
// 用于连接到存储区的密码。如果 username 和 password 参数都为 null,则使用当前主体的默认凭据。否则,username 和 password
// 都不可以为 null,并使用这两个参数指定的凭据来连接到存储区。
PrincipalContext oPrincipalContext = new PrincipalContext(ContextType.Domain, sDomain, sOU, ContextOptions.SimpleBind, sServiceUser, sServicePassword);
return oPrincipalContext;
}
#endregion }

ADMethodsAccountManagement 一些简单注释添加的更多相关文章

  1. VS简单注释插件——VS插件开发续

    VS简单注释插件——VS插件开发续 前些时候,我写过一篇<VS版权信息插件——初试VS插件开发小记>分享过一个用于添加注释信息的插件,但那个插件有几个问题: 不能添加带块注释(/**/), ...

  2. python笔记30-docstring注释添加变量

    前言 python里面添加字符串注释非常简单,如何将变量放入 python 的函数注释里面呢? docstring也就是给代码加注释的内容了,python可以给函数,类.方法,模块添加注释内容,注释标 ...

  3. SNPEFF snp注释 (添加自己基因组)

    之间介绍过annovar进行对snp注释,今天介绍snpEFF SnpEff is a variant annotation and effect prediction tool. It annota ...

  4. WebService的简单运用添加删除

    WebService是一种跨编程语言和跨操作系统平台的远程调用技术,简单来说就是将数据存储到项目的文件夹下 .NET中基于DOM核心类 XmlDocument 表示一个XML文档 XmlNode表示X ...

  5. 自学Zabbix3.3-一个简单例子 添加Hosts并应用模板

    Host 是 Zabbix 监控的基本载体,所有的监控项都是基于 host 的. 通过 Configuration->Hosts->Create Host 来创建监控设备 按提示填入 Na ...

  6. mybatis generator为实体类生成自定义注释(读取数据库字段的注释添加到实体类,不修改源码)

    我们都知道mybatis generator自动生成的注释没什么实际作用,而且还增加了代码量.如果能将注释从数据库中捞取到,不仅能很大程度上增加代码的可读性,而且减少了后期手动加注释的工作量. 1.首 ...

  7. EF简单的添加修改删除基本语法

    using ( androidhiveEntities db = new androidhiveEntities() )                {                    #re ...

  8. 百度地图简单使用——添加折线,圆形等(html,js)

    地图覆盖物概述 所有叠加或覆盖到地图的内容,我们统称为地图覆盖物.如标注.矢量图形元素(包括:折线和多边形和圆).信息窗口等.覆盖物拥有自己的地理坐标,当您拖动或缩放地图时,它们会相应的移动. 地图A ...

  9. eclipse简单注释规范

    设置注释模板的入口: Window->Preference->Java->Code Style->Code Template Types/*** @ClassName: ${t ...

随机推荐

  1. 关于easyui-accordion的添加以及显示隐藏菜单的使用

    <script type="text/javascript"> $(function() { leftMenus(); }); function leftMenus() ...

  2. mongodb 批量更新 数组的键操作的文件

    persons该文件的数据如下面的: > db.persons.find() { "_id" : 2, "name" : 2 } { "_id& ...

  3. url参数解析

    http://happycoder.net/parse-querystring-using-regexp/ http://www.cnblogs.com/babycool/p/3169058.html ...

  4. [!!**!F6782A84A3BECEAADDB11DAC0C4E6346AC07E5344100738DAF4C6DA639D9081F!!**!]

    testt 版权声明:本文博主原创文章,博客,未经同意不得转载.

  5. Delphi读取文件属性

    Read File Detailed Properties https://www.board4all.biz/threads/read-file-detailed-properties.655787 ...

  6. Python 的神奇方法指南

    简介 有关 Python 内编写类的各种技巧和方法(构建和初始化.重载操作符.类描述.属性访问控制.自定义序列.反射机制.可调用对象.上下文管理.构建描述符对象.Pickling). 你可以把它当作一 ...

  7. Get and Post(Unity3D六个发展)

    猴子原创,欢迎转载. 转载请注明: 转载自Cocos2D开发网–Cocos2Dev.com,谢谢! 原文地址: http://www.cocos2dev.com/?p=565 unity3d中的www ...

  8. TCP 的那些事儿(上,下)

    http://coolshell.cn/articles/11564.html http://coolshell.cn/articles/11609.html

  9. C# XML 去xmlns:xsd和xmlns:xsi属性

    public static XElement WithoutNamespaces(this XElement element) { if (element == null) return null; ...

  10. 生成wsdl代理c#代码

    C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\wsdl.exe /l:CS /out:d:\ws ...