ASP.NET Core MVC 路由是建立在ASP.NET Core 路由的,一项强大的URL映射组件,它可以构建具有理解和搜索网址的应用程序。这使得我们可以自定义应用程序的URL命名形式,使得它在搜索引擎优化(SEO)和链接生成中运行良好,而不用关心Web服务器上的文件是怎么组织的。我们可以方便的使用路由模板语法定义路由,路由模板语法支持路由值约束,默认值和可选值。

  基于约束的路由允许全局定义应用支持的URL格式,以及这些格式是怎样各自在给定的控制器中映射到指定的操作方法(Action)。当接受到一个请求时,路由引擎解析URL并将其匹配至一个定义URL格式,然后调用相关的控制器操作方法。 

routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");

  特性路由(Attribute Routing) 允许以在控制器和方法使用添加特性的方式指定路由信息来定义应用程序的路由。这意味着路由定义紧邻它们所关联的控制器和方法。

  ASP.NET Core MVC 使用路由中间件来匹配传入请求的URL,并将它们映射到操作方法。路由在启动代码或属性中定义,它描述了网址路径应如何与操作方法匹配,还用于响应中生成链接并发送。

1.设置路由中间件

  创建一个ASP.NET Core Web应用程序,在Startup类的Configure方法中有:

app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});

  在对UseMvc的调用过程中,MapRoute用于创建单个路由,即默认路由。大多数MVC应用程序都使用与默认路由模板类似的路由。

  路由模板{controller=Home}/{action=Index}/{id?} 可以匹配类似 Blog/Details/5 的URL路径,并且提取路由值 {controller=Blog,action=Details,id=5}。MVC将尝试查找名为BlogController的控制器,并运行操作方法。

    {controller=Home}将Home定义为默认控制器

    {action=Index}将Index定义为默认操作

    {id?}将id定义为可选

    默认路径参数和可选路径参数可以不出现在需要匹配的URL路径中。

  使用{controller=Home}/{action=Index}/{id?}模板,可以对以下URL路径都执行HomeController.Index:

    /Home/Index/7

    /Home/Index

    /Home

    /

  有个简单方法 app.UseMvcWithDefaultRoute() 可以替换掉上面的方法。

  UseMvc 和 UseMvcWithDefaultRoute 都是将RouteMiddleware的实例添加到中间件管道。MVC不直接与中间件交互,而是使用路由来处理请求。MVC通过MvcRouteHandler的实例链接到路由。下面的代码与UseMvc类似: 

var route = new RouteBuilder(app);
//添加连接到MVC,通过调用MapRoute来回调
route.DefaultHandler = new MvcRouteHandler(...);
//执行回调以注册路由
route.MapRoute("default", "{controller=Home}/{action=Index}/{id?}");
//创建路由集合并添加至中间件
app.UseRouter(route.Build());

  UseMvc 不直接定义任何路由,它为属性路由的路由集合添加一个占位符。重载UseMvc 使得我们可以添加自己的路由,并且还支持属性路由。UseMvc 及其所有变体为属性路由添加了占位符,这使得属性路由始终可用。UseMvcWithDefaultRoute定义默认路由并且支持属性路由。

2.常规路由

   routes.MapRoute(name: "default",template: "{controller=Home}/{action=Index}/{id?}");  这是一个常规路由,因为它建立了一个约定的URL路径:

    第一路径段映射到控制器名称

    第二路径映射到操作名称

    第三区段是可选id,用于映射到模型实体

  使用default路由,URL 路径 /Blog/Index 将映射到BlogController.Index 操作。该映射是基于控制器和操作名称,而不是基于命名空间,源文件位置等。

  使用常规路由的默认路由可以快速构建应用程序,而无需定义每一个操作的路由。对于CRUD 操作风格的应用程序,整个控制器的URL具有一致性。

3.多路由

  可以在UseMvc 里面通过添加MapRoute 来添加多个路由。这样可以定义多个约定,或添加专用于特定操作的常规路由: 

app.UseMvc(routes =>
{
routes.MapRoute("blog", "blog/{*article}",
defaults: new { Controller = "Blog", Action = "Index" });
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});

  这里的blog 路由是专用常规路由,这意味着它不采用常规路由系统,而是专用于一个特定地的动作。这个路由始终映射到BlogController.Index。

  路由集合中的路由是有序的,并且会按照它们被添加的顺序进行处理。

  

  1.回退

  作为请求处理的一部分,MVC将验证路由值是否可以用来查找应用程序中的控制器和操作。如果路由值不匹配操作,那么该路由被认为是不匹配的,将尝试下一个路由。这一过程称为回退,因为常规路由有重叠的情况。

  

  2.行动歧义

  当两个一致的操作通过路由时,MVC必须消除歧义,选择最佳操作,否则会抛出异常。例如:

public class BlogController : Controller
{
public ActionResult Edit(int id)
{
return View();
} [HttpPost]
public ActionResult Edit(int id, IFormCollection collection)
{
try
{
// TODO: Add update logic here return RedirectToAction(nameof(Index));
}
catch
{
return View();
}
} }

  URL /Blog/Edit/7 可以匹配这两个操作,这是MVC控制器的典型模式,其中Edit(int)用于显示编辑的表单,Edit(int,IFormCollection)用于 处理已提交的表单。为了达到这个目的,MVC需要在HTTP POST时选择Edit(int,IFormCollection),在其他HTTP动词时选择Edit(int)。

  HttpPostAttribute 是IActionConstraint 的一个实现,它只允许在HTTP动词为POST时选择动作。IActionConstraint的存在使得Edit(int,IFormCollection)比Edit(int)更好匹配。

  如果有多个路由匹配,并且MVC无法找到一个最佳路由,则会抛出AmbiguousActionException异常。

  3.路由名称

  上面的例子中"blog"和"default"字符串是路由名称,路由名称为路由提供了一个逻辑名称,以便命名的路由可用于生成URL。在应用程序范围内路由必须名称必须是唯一的。

  路由名称对URL匹配或请求的处理没有影响,仅用于URL生成。

4.路由特性

  特性路由使用一组特性直接将操作映射到路由模板。下面在Configure中调用 app.UseMvc(); 没有传递路由。

public class HomeController : Controller
{
[Route("")]
[Route("Home")]
[Route("Home/Index")]
public IActionResult Index()
{
return View();
} [Route("Home/About")]
public IActionResult About()
{
ViewData["Message"] = "Your application description page."; return View();
}
}

  HomeController.Index操作将会对 /,/Home 或者/Home/Index 任一URL访问执行。

  特性路由需要有更多的输入来指定一个路由,而常规路由处理路由时更加简洁。然而,特性路由允许精准控制每个操作的路由模板。

  上面的模板中没有定义针对 action,area ,controller的路由参数。实际上,这些参数不允许出现在特性路由中,因为路由模板已经关联了一个操作,解析URL中的操作名是没有意义的。

  特性路由也可以使用HTTP[Verb]特性,如HTTPPost:

        [HttpGet("/Blog")]
public ActionResult Index()
{
return View();
}

  由于特性路由适用于特定操作,因此很容易使参数作为模板定义中必须的一部分。下面的例子,id是URL中必须的一部分:

[HttpGet("Blog/Edit/{id}")]
public ActionResult Edit(int id)
{
return View();
}

  常规的默认路由定义id参数作为可选项({id?}),而特性路由的是必须参数,这种可以精准指定,比如包/Blog/Get 和 /Blog/Get/{id} 分配到不同的操作。

5.组合路由

  为了减少特性路由的重复部分,控制器上的路由特性会和各个操作上的路由特性进行结合。任何定义在控制器上的路由模板都会作为操作路由模板的前缀。

[Route("blog")]
public class BlogController : Controller
{
[HttpGet]
public ActionResult GetAll()
{
return View();
}
[HttpGet("{id}")]
public ActionResult GetById(int id)
{
return View();
}
}

  /blog 匹配GetAll方法, /blog/1 匹配 GetById方法。

  注意,如果操作上路由模板以 / 开头时不会结合控制器上的路由模板。

6.特性路由的顺序

  常规路由会根据定义顺序来执行,与之相比,特性路由会构建一个树形结构,同时匹配所有路由。这种看起来像路由条目被放置在一个理想的顺序中,最具体的路由会在一般的路由之前执行。比如,路由blog/Edit/4 比 blog/{*article} 更加具体。

  特性路由使用所有框架提供的路由特有的Order属性来配置顺序,并根据Order属性升序处理路由。默认是0,设置为-1时会在没有设置的路由之前执行。

7.路由模板中的标记替换( [controller] , [action] , [area])

  为了方便,特性路由支持标记替换,即通过在在方括号中封闭一个标记([, ])来替换对应的名称。标记[action],[area],[controller]会被替换成操作所对应的操作名,区域名,控制器名。

    [Route("[controller]/[action]")]
public class BlogController : Controller
{
[HttpGet]//匹配Blog/GetAll
public ActionResult GetAll()
{
return View();
}
}

  标记替换发生在构建特性路由的最后一步。与上面结果相同的写法:

    public class BlogController : Controller
{
[HttpGet("[controller]/[action]")]//匹配Blog/GetAll
public ActionResult GetAll()
{
return View();
}
}

  特性路由也可以与继承相结合,即继承父类的路由标记。

  特性路由支持单个操作定义路由。如果用IActionConstarint实现的多个路由特性定义在一个操作上时,每个操作约束与特性定义的路由相结合:

    [Route("Store")]
[Route("[controller]")]
public class BlogController : Controller
{
[HttpGet("GetAll")]//匹配 Get Blog/GetAll和 Store/GetAll
[HttpPost("Set")]//匹配 Post Blog/Set和 Store/Set
public ActionResult GetAll()
{
return View();
}
}

  虽然使用多个路由到一个操作看起来很强大,但最好还是保持URL的空间简单和定义明确。使用多个路由到操作上仅仅在特殊需要的时候,比如支持多个客户端。

8.使用IRouteTemplateProvider自定义路由特性

  所有框架提供的路由特性([Route(...) ] ,[HttpGet(...)]等)都实现了 IRouteTemplateProvider 接口。当程序启动时,MVC查找控制器类和操作方法上都实现 IRouteTemplateProvider 接口的特性来构建储时路由集合。

  可以通过实现 IRouteTemplateProvider 来定义自己的路由特性。每个 IRouteTemplateProvider 都允许定义使用自定义路由模板,顺序以及名称的单一路由:

public class MyApiControllerAttribute:Attribute, IRouteTemplateProvider
{
public string Template => "api/[controller]";
public int? Order { get; set; }
public string Name { get; set; }
}

  当 [MyApiController] 特性被应用时,会自动设置Template 为 api/[controller] 。

9.使用应用程序模型来自定义特性路由

  应用程序模型时启动时创建的对象模型,其中包含MVC用于路由和执行操作的所有元数据。应用程序模型包括从路由特性收集的所有数据(通过 IRouteTemplateProvider)。我们可以编写约定以在启动时修改应用程序模型为自定义路由行为。

public class NamespaceRoutingConvention:IControllerModelConvention
{
private readonly string _baseNamespace;
public NamespaceRoutingConvention(string baseNamespace)
{
_baseNamespace = baseNamespace;
} public void Apply(ControllerModel controller)
{
var hasRouteAttributes = controller.Selectors.Any(selector =>
selector.AttributeRouteModel != null);
if (hasRouteAttributes)
{
//此控制器自定义了一些路由,因此将其视为覆盖
return;
} // 使用命名空间和控制器来推断控制器的路由
//
// Example:
//
// controller.ControllerTypeInfo -> "My.Application.Admin.UsersController"
// baseNamespace -> "My.Application"
//
// template => "Admin/[controller]"
//
// 这使得你的路由大致与你的项目结构一致
//
var namespc = controller.ControllerType.Namespace;
var template = new StringBuilder();
template.Append(namespc,_baseNamespace.Length+,namespc.Length- _baseNamespace.Length-);
template.Replace('.','/');
template.Append("/[controller]"); foreach (var selector in controller.Selectors)
{
selector.AttributeRouteModel = new AttributeRouteModel()
{
Template = template.ToString()
};
}
}
}

  这部分怎么使用,个人还是不是很清楚,这里只是记录了官方文档,有哪位知道可以告诉以下小弟。

10.URL生成

  MVC应用程序可以使用路由URL的生成特性来生成URL链接到操作。生成URL可以消除硬编码URL,使代码更加健壮和易维护。IUrlHelper 接口是MVC与生成URL路由之间基础设施的基本块。可以通过控制器,视图以及视图组件中的URL属性找到一个可用的IUrlHelper实例:

    public class HomeController : Controller
{
public IActionResult Index()
{
//生成/Home/Contact
var url = Url.Action("Contact");
return View();
} public IActionResult Contact()
{
ViewData["Message"] = "Your application description page."; return View();
}
}

  这个URL路径是由路由值与当前请求相结合而成的路由创建,并将值传递给Url.Action,替换路由模板中对应的值。

  上面Url.Action(的例子是常规路由,但是URL的生成工作与特性路由类似,尽管概念不同。在常规路由中,路由值被用来扩展模板,并且关于controller和action的路由值通常出现在那个模板,因为路由匹配的URL坚持了一个约定。在特性路由中,关于controller和action的路由值不允许出现在模板中--它们用来查找应该使用哪个模板,例如:

//修改Configure
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseMvc(); } public class HomeController : Controller
{
[HttpGet("/")]
public IActionResult Index()
{
//生成/Home/To/About
var url = Url.Action("About");
return View();
} [HttpGet("Home/To/About")]
public IActionResult About()
{
ViewData["Message"] = "Your application description page."; return View();
}
}

  MVC构建了一个所有特性路由操作的查找表,并且会匹配controller和action值来选择路由模板用于生成URL。

11.通过操作名生成URL

    Url.Action(this IUrlHelper helper, string action) 以及所有相关的重载都是基于指定控制器名称和操作名来指定要链接的内容。

  当使用Url.Action时,controller 和 action 的当前路由值是指定的 -- controller 和 action 的值同时是环境值和值的一部分。Url.Action 方法总是使用 controller 和 action 的当前值,并且生成路由到当前操作的URL路径。

  路由尝试使用环境值中的值来填充信息,同时我们也可以指定路由参数:

    public class HomeController : Controller
{
public IActionResult Index()
{
//生成/Blog/Edit/1
var url = Url.Action("Edit", "Blog",new { id=});
//生成/Blog/Edit/1?color=red
var url1 = Url.Action("Edit", "Blog", new { id = ,color="red"});
return View();
}
}

  如果像创建一个绝对URL,可以使用一个接受protocol的重载: Url.Action("Edit", "Blog",new { id=1},protocol:Request.Scheme);

  

12.通过路由名生成URL

  IUrlHelper也提供了 Url.RouteUrl 的系列方法,最常见的是指定一个路由名来使用具体的路由生成URL,通常没有指定控制器名或操作名:

    public class HomeController : Controller
{
public IActionResult Index()
{
//生成customer/to/url
var url = Url.RouteUrl("AboutRoute");
return View();
} [HttpGet("customer/to/url",Name = "AboutRoute")]
public IActionResult About()
{
ViewData["Message"] = "Your application description page."; return View();
}
}

  在HTML 中生成的URLHtmlHelper,提供了 HtmlHelper 方法 Html.BeginForm 和 Html.ActionLink 来分别生成<form>和<a>元素。这些方法使用Url.Action方法来生成一个URL,并且它们接受类似的参数。Url.RouteLink ,它们有类似的功能。TagHelper通过form和<a> TagHelper生成URL。这些都使用了IUrlHelper 作为它们的实现。在内部视图中,IUrlHelper 通过Url 属性生成任何不包含上述的特定URL。

13.在操作结果中生成URL

  在控制器中常见的一个用法是生成一个URL作为操作结果的一部分。Controller和ControllerBase 基类为引用其他操作的操作结果提供了简单方法。一个典型的方法:

public class HomeController : Controller
{
public IActionResult Index()
{
//生成customer/to/url
var url = Url.RouteUrl("AboutRoute");
return Redirect(url);
//或者
//return RedirectToAction("Contact");
} [HttpGet("customer/to/url",Name = "AboutRoute")]
public IActionResult About()
{
ViewData["Message"] = "Your application description page."; return View();
} public IActionResult Contact()
{
ViewData["Message"] = "Your contact page."; return View();
}
}

  RedirectToAction方法有多个重载可以使用。

14.专用常规路由的特殊情况

  有一种特殊的路由被称为专用常规路由,下面被命名为blog的路由就是:

app.UseMvc(routes =>
{
routes.MapRoute("blog", "blog/{*article}",
defaults: new { Controller = "Blog", Action = "Index" });
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});

  Url.Action("Index", "Home") 会使用默认路由生成URL。

  专用常规路由是依靠默认路由的一个特殊行为,没有相应的路由参数,以防止路由生成URL“太贪婪”。当路由执行URL生成时,提供的值必须与默认值匹配:否则使用blog的URL生成失败,因为值 {controller=Home,action=Index}不匹配{controller=Blog,action=Index}。然后路由回退尝试default,并成功。

15.区域

  Areas 是一种MVC功能,用来将相关功能组织为一个组,作为单独的路由命名空间(用于控制器操作)和文件夹结构(用于视图)。使用区域允许应用程序拥有多个相同名称的控制器——只要它们具有不同的区域。使用区域通过向控制器和操作添加另一个路由参数,区域可创建用于路由目的的层次结构。

  使用默认常规路由配置MVC,命名一个OMS区域的路由:

app.UseMvc(routes =>
{
routes.MapAreaRoute("oms", "OMS", "OManage/{controller}/{action}/{id?}",
defaults: new { Controller = "Order", Action = "Index" });
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
namespace Blog.Areas.OMS.Controllers
{
[Area("OMS")]
public class OrderController : Controller
{
// GET: Order
public ActionResult Index()
{
return View();
}
}

  当URL为 /OManage/Order/Edit 时,会匹配路由值 {area = OMS,controller = Order , action = Edit}。area路由值是通过area默认值产生的。使用MapRoute方法也可以实现:

routes.MapRoute("oms", "OManage/{controller}/{action}/{id?}",
defaults:new {area="OMS" },constraints:new { area = "OMS" });

  MapAreaRoute创建一个路由,同时使用默认路由和area 约束,约束使用提供的区域名 OMS。默认值保证路由总是处理 {area = OMS},约束要求值{area = OMS} 来进行URL生成。

  常规路由是顺序依赖。一般区域路由放置在前面,因为区域路由更具体。

  AreaAttribute表示控制器属于一个区域的一部分,即这个控制器是在 OMS 区域。控制器不带[Area] 特性则不属于任何区域。

  当在区域内执行操作时,区域的路由值将作为环境值以用于URL生成,这意味着,在默认情况下,区域对URL生成具有黏性:

namespace Blog.Areas.OMS.Controllers
{
[Area("OMS")]
public class OrderController : Controller
{
// GET: Order
public ActionResult Index()
{
//生成/OManage/Home/Create
var url = Url.Action("Create","Home");
//生成/Home/Create
var url1 = Url.Action("Create", "Home",new { area=""});
return View();
}
}
}

16.IActionConstraint

  通常应用程序不需要自定义 IActionConstraint,[HttpGet] 特性以及类似的特性实现 IActionConstraint 接口,以限制方法的执行。

  当两个操作一模一样,其中一个操作使用 IActionConstraint,总是认为比没有使用的操作更好,因为它被视为更加具体,并且两个操作都可以在匹配是被选中。(没有使用的操作会匹配任何HTTP谓词)

  概念上,IActionConstraint 是重载的一种形式,但不是使用相同名称的重载,它是匹配相同URL操作的重载。特性路由也使用 IActionConstraint ,并且可以导致不同控制器的操作都被视为候选操作。

  实现 IActionConstraint 最简单的方式是创建一个类派生自 System.Attribute ,并且将它放置到操作和控制器上。MVC会自动发现任何作为特性被应用的 IActionConstraint。你可以使用程序模型来应用约束,可能是最灵活的方法,因为它允许对它们如何被应用进行元编程。

  一个例子,一个约束选择一个基于来自路由数据的 country code 操作:

public class CountrySpecificAttribute:Attribute,IActionConstraint
{
private readonly string _countryCode;
public CountrySpecificAttribute(string countryCode)
{
_countryCode = countryCode;
} public int Order { get { return ; } } public bool Accept(ActionConstraintContext context)
{
return string.Equals(
context.RouteContext.RouteData.Values["country"].ToString(),
_countryCode,StringComparison.OrdinalIgnoreCase);
}
}

  Accept 方法返回true,表示当country路由值匹配时操作时匹配的。这个和 RouteValueAttribute 不同,因为它允许回退到一个非特性操作。这个例子展示了如果定义一个 en-US 操作,然后国家代码是 fr-FR,则会回退到一个更通用的控制器,这个控制器没有应用 [CountrySpecific(...)] 。

  Order属性和 [HttpGet] 特性中的Order属性一样,用来决定运行顺序。

ASP.NET Core MVC 之路由(Routing)的更多相关文章

  1. ASP.NET Core MVC的路由参数中:exists后缀有什么作用,顺便谈谈路由匹配机制

    我们在ASP.NET Core MVC中如果要启用Area功能,那么会看到在Startup类的Configure方法中是这么定义Area的路由的: app.UseMvc(routes => { ...

  2. ASP.NET Core MVC 之区域(Area)

    区域(Area)是一个 ASP.NET MVC 功能,用于将相关功能组织为一个单独的命名空间(用于路由)和文件结构(用于视图).使用区域通过向控制器和操作添加 一个路由参数(area)来创建用于路由目 ...

  3. ASP.NET Core MVC/WebAPi如何构建路由?

    前言 本节我们来讲讲ASP.NET Core中的路由,在讲路由之前我们首先回顾下之前所讲在ASP.NET Core中的模型绑定这其中有一个问题是我在项目当中遇见的,我们下面首先来看看这个问题. 回顾A ...

  4. asp.net core mvc中如何把二级域名绑定到特定的控制器上

    由于公司的工作安排,一直在研究其他技术,所以一直没时间更新博客,今天终于可以停下手头的事情,写一些新内容了. 应用场景:企业门户网站会根据内容不同,设置不同的板块,如新浪有体育,娱乐频道,等等.有的情 ...

  5. ASP.NET Core MVC 源码学习:Routing 路由

    前言 最近打算抽时间看一下 ASP.NET Core MVC 的源码,特此把自己学习到的内容记录下来,也算是做个笔记吧. 路由作为 MVC 的基本部分,所以在学习 MVC 的其他源码之前还是先学习一下 ...

  6. ASP.NET Core 入门教程 3、ASP.NET Core MVC路由入门

    一.前言 1.本文主要内容 ASP.NET Core MVC路由工作原理概述 ASP.NET Core MVC带路径参数的路由示例 ASP.NET Core MVC固定前/后缀的路由示例 ASP.NE ...

  7. 如何在ASP.NET Core中构造UrlHelper,及ASP.NET Core MVC路由讲解

    参考文章: Unable to utilize UrlHelper 除了上面参考文章中介绍的方法,其实在ASP.NET Core MVC的Filter拦截器中要使用UrlHelper非常简单.如下代码 ...

  8. ASP.NET Core 入门笔记4,ASP.NET Core MVC路由入门

    敲了一部分,懒得全部敲完,直接复制大佬的博客了,如有侵权,请通知我尽快删除修改 摘抄自https://www.cnblogs.com/ken-io/p/aspnet-core-tutorial-mvc ...

  9. ASP.NET Core MVC 配置全局路由前缀

    前言 大家好,今天给大家介绍一个 ASP.NET Core MVC 的一个新特性,给全局路由添加统一前缀.严格说其实不算是新特性,不过是Core MVC特有的. 应用背景 不知道大家在做 Web Ap ...

随机推荐

  1. 写一个去除AI2XAML注释及多余数字位数的WPF窗体程序

    原文:写一个去除AI2XAML注释及多余数字位数的WPF窗体程序 使用正则表达式去除多余注释及冗余数字位,关键代码:            string pattern = @"/b(/d+ ...

  2. latex 矩阵分块(block matrix)

    Lesson 12: Making Block Matrices in LATEX 按列分块: [AAb⋯An−1b] $$ \left[ \begin{array}{c|c|c|c} A & ...

  3. WPF中StringFormat的用法--显示特定位数的数字

    原文:WPF中StringFormat的用法--显示特定位数的数字 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/huangli321456/art ...

  4. DataSet 互相转换 List

    /// <summary> /// List <-> DataSet /// </summary> public class IListDataSet { /// ...

  5. win32Helper

    点击别的winform窗口的按钮 #region 点击别的窗口的按钮 [DllImport("user32.dll", EntryPoint = "FindWindowA ...

  6. C# WinForm TreeView选择父节点子节点全选

    //设置标志,防止死循环 bool check = false; public void TV_AfterCheck(object sender, TreeViewEventArgs e) { if ...

  7. 程序异常崩溃后用windbg辅助调试解决的经验 以及 堆栈问题调试经验

    1,程序异常崩溃后用windbg辅助调试解决的经验  状况:我的程序调用别人的库做 文件写入工作. 在这一过程中出现异常,程序崩溃. 经反复检查,认为自己的程序没有错,但无法判断在别人库里哪里有错. ...

  8. 问题记录,Release模式和Debug运行效果不一样,Release必须加延时

    这个程序大体是这样一个逻辑,通过win32程序与设备交互,主线程先向设备发送命令要求 循环验证 然后一个线程专门负责接收设备返回信息 两边通过全局变量的变化来交流,主线程通过接收线程收到的信息设置界面 ...

  9. 搭建svn服务器&服务器客户端使用笔记

    参考借鉴文章:http://www.cnblogs.com/vijayfly/p/5711962.html 之前尝试着用git管理公司代码,但被一个问题困惑了很久无法解决,那就是git该如何只pull ...

  10. Android零基础入门第62节:搜索框组件SearchView

    原文:Android零基础入门第62节:搜索框组件SearchView 一.SearchView概述 SearchView是搜索框组件,它可以让用户在文本框内输入文字,并允许通过监听器监控用户输入,当 ...