好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

基于JQuery、WebApi的ASP.NET MVC插件的代码生成项目主要技术解析

基于JQuery、WebApi的ASP.NET MVC插件的代码生成项目主要技术解析

基于JQuery、WebApi的ASP.NET MVC插件的代码生成项目主要技术解析

 YbSoftwareFactory目前已可快速生成ASP.NET  WebForm、MVC、WinForm和WPF的解决方案源代码,所生成的源代码可直接在VS中打开并运行。终端用户还可自行二次开发自己所需的插件。本章将对ASP.NET MVC代码生成插件所生成项目的主要特点和技术进行解析,其Demo地址: http://mvcdemo.yellbuy测试数据/ 。

主要技术特点:

一、数据字典的排序

    有童鞋问到数据字典的排序是如何实现的,其实数据字典的排序比较简单。首先,需要定义一个排序字段,并根据这个字段升序排列。如果要优先显示某个字典项,则需减小该排序字段的值。如果该排序字段再首位,则无需操作,第二位,则为第一位的排序值小1000,其他设置为前面两项的值的平均数。反之亦然~

    在所生成的解决方案中,使用了通用的Api组件,你只需配置好主代码即可。

二、数据分页和动态查询

    现在很多童鞋使用Linq查询,确实是非常方便,并且是强类型的,这样编写代码也不容易出错;但最大的缺点就是灵活性差,例如无法把查询语法写到一个统一的基类中。在本解决方案中,设计比较巧妙之处就是把过滤查询的实现写到了一个泛型基类中,仅需在具体实现类中定义查询的方式字符串即可,代码不仅更加简洁,而且修改、维护也更加方便。使用动态Linq技术可以在泛型基类中统一以如下的方式进行数据查询、分页和排序,而无需在具体类中总是写重复的代码:

 ///   <summary> 
         ///   分页查询
          ///   </summary> 
         ///   <param name="filter">  查询条件  </param> 
         ///   <param name="page">  页号  </param> 
         ///   <param name="rows">  记录数  </param> 
         ///   <param name="sort">  排序字段名称  </param> 
         ///   <param name="order">  排序方式  </param> 
         ///   <returns></returns> 
         public  ResponseResult<M> Get( string  filter,  int  page,  int  rows,  string  sort,  string   order)
        {

              var  table =  Table;
              if  (! string  .IsNullOrWhiteSpace(filter))
            {
                  var  str =  GetFilterFormat();
                  //  有过滤条件,进行过滤查询 
                 if  (! string  .IsNullOrWhiteSpace(str))
                    table  =  table.Where(str, filter);
            }
              var  total =  table.LongCount();
            table  = table.OrderBy( string .Format( "  {0} {1}  " , sort, order)).Skip((page -  1 ) *  rows).Take(rows);
              var  items =  table.ToList();
              var  models =  InjectFrom(items);
              return   new  ResponseResult<M> (total, models);
        } 

    如果感兴趣,可以在 前一章 中下载DynamicLinq的实现源码。

三、授权和身份认证

    授权和验证关系到系统的安全,普通的授权验证方式无法实现本系统所要求的灵活性以及细粒度的权限控制,因此需对授权方式进行扩展,这主要需从AuthorizeAttribute继承,本解决方案中新增了一个PermissionKey属性,更据所设置的PermissionKey名称进行相应的授权处理,通过添加“EveryOne”角色名甚至能设置匿名用户的操作权限,不可谓不灵活。主要代码如下:

YbApiAuthorizeAttribute

  1   public   class   YbApiAuthorizeAttribute : System.Web.Http.AuthorizeAttribute
    2       {
    3           private   const   string  BasicAuthResponseHeader =  "  WWW-Authenticate  "  ;
    4           private   const   string  BasicAuthResponseHeaderValue =  "  Basic  "  ;
    5           public   string  PermissionKey {  get ;  set  ; }
    6           public   override   void   OnAuthorization(HttpActionContext actionContext)
    7           {
    8               if  (actionContext ==  null  )
    9                   throw   new  ArgumentNullException( "  actionContext  "  );
   10               if  (AuthorizationDisabled(actionContext) ||  AuthorizeRequest(actionContext.ControllerContext.Request))
   11                   return  ;
   12               this  .HandleUnauthorizedRequest(actionContext);
   13           }
   14  
  15           protected   override   void   HandleUnauthorizedRequest(HttpActionContext actionContext)
   16           {
   17               if  (actionContext ==  null  )
   18                   throw   new  ArgumentNullException( "  actionContext  "  );
   19              actionContext.Response =  CreateUnauthorizedResponse(actionContext.ControllerContext.Request);
   20           }
   21  
  22           private   HttpResponseMessage CreateUnauthorizedResponse(HttpRequestMessage request)
   23           {
   24               var  result =  new   HttpResponseMessage()
   25                   {
   26                      StatusCode =  HttpStatusCode.Unauthorized,
   27                      RequestMessage =  request
   28                   };
   29               //  we need to include WWW-Authenticate header in our response,        
   30               //  so our client knows we are using HTTP authentication         
  31               result.Headers.Add(BasicAuthResponseHeader, BasicAuthResponseHeaderValue);
   32               return   result;
   33           }
   34  
  35           private   static   bool   AuthorizationDisabled(HttpActionContext actionContext)
   36           {
   37               //  support new AllowAnonymousAttribute         
  38               if  (!actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute> ().Any())
   39                   return  actionContext.ControllerContext.ControllerDescriptor.GetCustomAttributes<AllowAnonymousAttribute> ().Any();
   40               return   true  ;
   41           }
   42  
  43           private   bool   AuthorizeRequest(HttpRequestMessage request)
   44           {
   45               //  匿名用户的权限验证 
  46               if  (! HttpContext.Current.User.Identity.IsAuthenticated)
   47               {
   48                   var  permissionsOfEveryOne = Permissions.GetPermissionsInRole( "  EveryOne  "  );
   49                   return   CheckPermission(request, permissionsOfEveryOne);
   50               }
   51               //  未设置权限Key,则任何用户均可访问 
  52               if  ( string .IsNullOrWhiteSpace(PermissionKey))  return   true  ;
   53  
  54               //  登录用户的权限验证 
  55               var  allowPermissions =  Permissions.GetPermissionsForUser();
   56               return   CheckPermission(request, allowPermissions);
   57           }
   58  
  59           private   bool   CheckPermission(HttpRequestMessage request, Permission[] permissionsOfEveryOne)
   60           {
   61               if  (permissionsOfEveryOne ==  null  || permissionsOfEveryOne.Length ==  0  )
   62                   return   false  ;
   63               var  permissionKeys = permissionsOfEveryOne.Select(c =>  c.PermissionKey);
   64               if  (request.Method.Method.Equals( "  GET  "  , StringComparison.OrdinalIgnoreCase))
   65                   return   permissionKeys.Contains(PermissionKey.ToLower());
   66               if  (request.Method.Method.Equals( "  PUT  "  , StringComparison.OrdinalIgnoreCase))
   67                   return  permissionKeys.Contains( string .Format( "  {0}.add  "  , PermissionKey.ToLower()));
   68               if  (request.Method.Method.Equals( "  POST  "  , StringComparison.OrdinalIgnoreCase))
   69                   return  permissionKeys.Contains( string .Format( "  {0}.edit  "  , PermissionKey.ToLower()));
   70               if  (request.Method.Method.Equals( "  DELETE  "  , StringComparison.OrdinalIgnoreCase))
   71                   return  permissionKeys.Contains( string .Format( "  {0}.delete  "  , PermissionKey.ToLower()));
   72               return   false  ;
   73           }
   74  
  75           protected   string  [] RolesSplit
   76           {
   77               get  {  return   SplitStrings(Roles); }
   78           }
   79  
  80           protected   string  [] UsersSplit
   81           {
   82               get  {  return   SplitStrings(Users); }
   83           }
   84  
  85           protected   static   string [] SplitStrings( string   input)
   86           {
   87               if  ( string .IsNullOrWhiteSpace(input))  return   new   string [ 0  ];
   88               var  result = input.Split( '  ,  ' ).Where(s => ! String.IsNullOrWhiteSpace(s.Trim()));
   89               return  result.Select(s =>  s.Trim()).ToArray();
   90           }
   91  
  92          ///   <summary> 
  93           ///   Implement to include authentication logic and create IPrincipal    
   94          ///   </summary> 
  95           protected   bool  TryCreatePrincipal( string  user,  string  password,  out   IPrincipal principal)
   96           {
   97              principal =  null  ;
   98               if  (! Membership.ValidateUser(user, password))
   99                   return   false  ;
  100               string [] roles =  System.Web.Security.Roles.Provider.GetRolesForUser(user);
  101              principal =  new  GenericPrincipal( new   GenericIdentity(user), roles);
  102               return   true  ;
  103           }
  104      }

      当然,你也需要在具体的Controller上添加相应的Attribute标记,例如:[YbApiAuthorize(PermissionKey = "Categories")]

四、实体对象的验证

    实体对象的验证使用Fluent Validator组件进行验证,YbSoftWareFactory自动生成基本的客户端和服务器端的验证代码(如非空检查,字符串长度检查等),所生成的服务器端的验证代码示例如下:

 public   class  CustomersValidator : AbstractValidator<Customers> 
    {
          public   CustomersValidator()
        {
              //  此处添加验证逻辑 
            RuleFor(x => x.CustomerID).NotEmpty().WithMessage( "  必须输入标识  "  );
            RuleFor(x  => x.CompanyName).NotEmpty().WithMessage( "  必须输入公司名  "  );
            RuleFor(x  => x.ContactName).Length( 30 ).WithMessage( "  联系人最多只能输入30个字符  "  );
            RuleFor(x  => x.ContactTitle).Length( 30 ).WithMessage( "  职务最多只能输入30个字符  "  );
            RuleFor(x  => x.Address).Length( 60 ).WithMessage( "  地址最多只能输入60个字符  "  );
            RuleFor(x  => x.City).Length( 15 ).WithMessage( "  市最多只能输入15个字符  "  );
            RuleFor(x  => x.Region).Length( 15 ).WithMessage( "  省/自治区最多只能输入15个字符  "  );
            RuleFor(x  => x.PostalCode).Length( 10 ).WithMessage( "  邮编最多只能输入10个字符  "  );
            RuleFor(x  => x.Country).Length( 15 ).WithMessage( "  国家最多只能输入15个字符  "  );
            RuleFor(x  => x.Phone).Length( 24 ).WithMessage( "  电话最多只能输入24个字符  "  );
            RuleFor(x  => x.Fax).Length( 24 ).WithMessage( "  传真最多只能输入24个字符  "  );
        }
    } 

五、日志

    为方便调试和错误诊断,系统集成long4net日志组件,所有异常信息均输出至相应的日志文件中。

有童鞋问YbSoftwareFactory怎么使用,好用不?(见过很多人是一根筋,自己把自己搞得太累~)其实使用YbSoftwareFactory生成ASP.NET MVC项目的源代码超级简单,仅需三步:

     第一步:运行YbSoftwareFactory并连接数据库

     第二步:编辑元数据信息,以便生成的界面更加友好

     第三步:点击“解决方案”按钮生成源代码

    短暂的等待后,在VS中打开所生成的源码解决方案,然后就是运行它....

注:本插件已正式发布,需要插件和代码的请和我联系。

YbSoftwareFactory

 

分类:  YbSoftwareFactory

标签:  ASP.NET ,  YbSoftwareFactory ,  YbRapidSolution ,  MVC ,  JQuery ,  JQuery EasyUI ,  EF ,  Web Api

作者: Leo_wl

    

出处: http://HdhCmsTestcnblogs测试数据/Leo_wl/

    

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

版权信息

查看更多关于基于JQuery、WebApi的ASP.NET MVC插件的代码生成项目主要技术解析的详细内容...

  阅读:52次