• ASP.NET 5探险(7):使用混合型控制器方便实现单页应用


    (此文章同时发表在本人微信公众号“dotNET每日精华文章”,欢迎右边二维码来关注。)

    题记:由于在ASP.NET 5中,MVC和WEB API的技术栈合并了,所以开发混合型Controller也成为可能。

    众所周知,在ASP.NET MVC 5和WEB API 2时代,两者的技术栈是独立的(开发团队也是独立的)。虽然后来两者都可以融合到OWIN中运行在一起,但是两者的控制器(Controller)代码是不能写在一起的(因为两者的基类不一致)。诚然,MVC控制器也可以通过返回Json数据来实现类似WEB API控制器的效果,但是所体现的设计效果并不是纯粹的REST API。

    可能微软也意识到并行提供两套技术栈,不仅给自己的开发带来维护难度,也给用户的学习和开发带来困难。所以,在ASP.NET 5中,两者在技术栈上进行了统一,也就是在MVC中可以开发WEB API。这样的技术融合最大的体现的就是路由映射的机制。关于ASP.NET 5中的路由机制,我就不赘述了,大家可以参考其他资料,比如《解读ASP.NET 5 & MVC6系列(11):Routing路由》(http://www.cnblogs.com/TomXu/p/4496462.html)。

    为了做一个SPA的示例,我尝试使用了混合型控制器来同时支持视图的处理和REST数据接口的处理,这样带来的好处是不需要为了MVC和REST API分别创建两个控制器,且能同时符合MVC和REST API的Action和路由风格。可能用文字很难描述出混合型控制器的特点,还是直接来看代码吧。

    public class UserController : Controller
    {
        private AccountManager _accountManager;
    
        public UserController(AccountManager accountManager)
        {
            _accountManager = accountManager;
        }
        
        //下面是mvc的action
        
        // GET: /<controller>/
        public IActionResult Index()
        {
            return View();
        }
    
        public IActionResult Edit(string id)
        {
            ViewBag.Id = id;
            return View();
        }
    
        //下面是api的action
    
        [HttpGet("[controller]/api")]
        public async Task<BasePagingListDto<UserDto>> GetAll(int page = 1, int pageSize = 10)
        {
            var query = _accountManager.UserManager.Users;
            var total = await query.CountAsync();
            var users = await query.Skip((page - 1) * pageSize).Take(pageSize).ToListAsync();
            var dto = new BasePagingListDto<UserDto>();
            dto.Items = users.ConvertAll(user => Mapper.Map<UserDto>(user));
            dto.Total = total;
            return dto;
        }
    
        [HttpGet("[controller]/api/{id}")]
        public async Task<IActionResult> GetById(string id)
        {
            var user = await _accountManager.UserManager.FindByIdAsync(id);
            if (user == null) return HttpNotFound();
            var dto = Mapper.Map<UserDto>(user);
            return new ObjectResult(dto);
        }
    
        [HttpPut("[controller]/api/{id}")]
        public async Task<IActionResult> EditById(string id, UserDto dto)
        {
            if (ModelState.IsValid)
            {
                var user = await _accountManager.UserManager.FindByIdAsync(id);
                if (user == null) return HttpNotFound();
                dto.SetValue(user);
                await _accountManager.UserManager.UpdateAsync(user);
                return new HttpStatusCodeResult((int)HttpStatusCode.Accepted);
            }
            return new HttpStatusCodeResult((int)HttpStatusCode.BadRequest);
        }
    }

    在上面的代码中,Index这个Action会返回一个视图(Index.cshtml)给用户。在这个cshtml文件中,主要是利用Layout.cshtml来获得统一的母版,只包含很少的Razor代码,而使用jQuery和Knockout来加载和动态展示数据。其中加载数据是通过GetAll这个Action,获取地址还是利用"@Url.Action("GetAll")"来得到,而实际访问是GET“/User/api”。

    同样,Edit这个Action会返回一个视图(Edit.cshtml)用于编辑用户的信息。加载用户的单条数据是通过GetById这个Action,实际访问是GET“/User/api/[userid]”。当需要修改数据的时候,是使用EditById这个Action,实际访问地址是PUT “/User/api/[userid]”。

    这个控制器的代码也可以通过代码片段来查看:http://git.oschina.net/ike/codes/8avtl3u2p6g1ik09c5snz

  • 相关阅读:
    badblocks 检查硬盘是否有坏道
    IE兼容性开发的笔记
    Linux下设置ip和主机名进行绑定
    netty httpserver
    netty websocket协议开发
    OAuth2.0和SSO授权的区别
    window.location.href跳转问题2
    修改密码,验证两次输入是否相同,相同才能提交
    (2)集合 遍历set集合
    (1)集合 ---遍历map集合
  • 原文地址:https://www.cnblogs.com/redmoon/p/4711435.html
Copyright © 2020-2023  润新知