Web探索|Asp.net||Jquery|MVC

Web前沿技术、移动解决方案
  博客园  :: 首页  :: 新随笔  :: 管理

开源框架介绍

Posted on 2014-11-10 16:01  reckcn  阅读(290)  评论(0)    收藏  举报

Bootstrap

  这玩意我想很多人都知道,我就不多说了。有了它之后,我们程序员不需要美工也可以做出很漂亮的界面了,虽然我这个Demo没有很好看,但要是没有它那还真不知道要丑上多少倍。它还有中文版的站点: http://www.bootcss.com/

director.js

  这是一个前端的route框架,什么叫前端route呢?大家如果去看我的那个Demo就会发现,URL并不是像某Q邮箱那样一直不变的,我们还是可以像以前那样每一个单一的功能一个URL。比如说:

  • #/events/create
  • #/events/all
  • #/events/closed
  • #/events/1

  除了对用户比较友好之后,写代码的时候也会更加逻辑清晰,因为director会为每一个url绑定一个函数,就像mvc里面的action一样。当用户输入对应的url的时候,相应的函数就会被触发。

  下面是来自官方首页的一个小小的例子,让你一眼就会用director。

requireJS

  这玩意我也不用多介绍了吧,它具有延迟加载和避免重复加载的功能,来自官方的定义: requireJS是一个JavaScript文件和模块加载器。

knockout.js

  这玩意就算我想给你介绍也不是三言两语就能说的清的,具体您还是参考源码吧。或者园子里面的大叔曾经翻译了官方的一个教程,有兴趣同学可以看看。 总之它是一个JavaScript的MVVM框架,当然这种框架有很多,backboneJS, breezeJS, Durandal,EmberJS,Angular 等等,我并没有全部了解过,所以我也不能告诉你他们的优势和缺点分别在哪里。选择knockout.js是因为之前了解过,好上手,然后以上这3种开源的框架全是基于MIT开源协议的,这样我们就可以用它做商业开发了。

用requireJS实现远程模板的调用

  直接用require来加载html模板是不行的,人家已经说了是一个Javascript文件和模块的加载器。所以这里面我们需要用到requireJS的文本插件,这样我们就可以用它来加载文本了。https://github.com/requirejs/text

  把那个text.js下载下来,直接放到我们程序的根目录下,然后我们就可以用像加载js一样的方法来加载html代码了,除了要在我们文件位置前面加上一个text! 之外。

1
2
3
require(['text!/template/createevent'], function (template) {
                // 你在这里就可以拿到模板了。
})

rest中关于局部更新的讨论

  我们常用的http verb有四种:

  我们用PUT方式去更新的话,是将整个Model全部更新。当然你也可以换成下面这种方式,只更新你想要更新的字段。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[HttpPut]
public void Put(Event item)
{
    var newItem = new Event();
    newItem.Id = item.Id;
 
    // 在下面将你想要更新的值转到newItem下
    newItem.Title = item.Title;
 
    if (!repository.Update(newItem))
    {
        throw new HttpResponseException(HttpStatusCode.NotFound);
    }
}

  注意:Put方式的URl只有一种(在我们不建其它route的情况下),也就是我们上面列出来的 /api/events/{id},然后将event对象作为body传过去。比如说在我们的demo中,我们有更新操作,还有像“关闭”这样的操作,我想这样的操作几乎在每一个系统里面都会遇到,这样的操作只会更新一个字段(在这里是“状态”列)。 那我怎么样再建一个Put方法去更改这一个字段呢?而且最好的方法是我只用传id过去就可以了。

  通过google,我找到一个叫Patch的玩意, 它也是一种http verb,并且同样也是提供更新操作。但是与Put不一样的是Patch允许只将你需要更改的字段传到服务器端。

1
2
3
4
5
6
7
8
9
10
11
var obj = { Revision : "2"};
  
$.ajax({
    url: 'api/values/1',
    type: 'PATCH',
    data: JSON.stringify(obj),
    dataType: 'json',
    contentType: 'application/json',
    success: function (data) {           
    }
});

  但是不管怎么说,这种方式我是没有行通的,一旦我的实体对象加上一些验证的Attribute比如说Required之后,那些字段全都会被赋上默认值。 最后我不得不放弃了这种做法。

添加Route来创建两个PUT方法

  另外一种做法,也就是我们Demo中实现的做法是增加了一个Route,在我们的web api中实现了两个put的方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[Route("api/events/{id}/close")]
public void Put(int id)
{
var item = repository.Get(id);
if (item == null)
{
    throw new HttpResponseException(HttpStatusCode.NotFound);
}
 
item.Status = EventStatus.Closed;
if (!repository.Update(item))
{
    throw new HttpResponseException(HttpStatusCode.NotFound);
}
}

  这样当我用PUT的方式提交到 api/events/3/close 的时候,我们的web api就会执行上面的方法然后把我们的event关闭了。

WEB API的验证

  基本上任何系统都避免不了与验证打交道,除非那个系统压根不从用户那里获取数据。WEB API的验证方式大至相同,我们仍旧可以在我们的Model中采用Attribute的方式去声明验证条件。

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Event
{
public int Id { get; set; }
[Required]
[MinLength(10)]
public string Title { get; set; }
public string Description { get; set; }
public DateTime Start { get; set; }
public DateTime End { get; set; }
[Required]
public string Owner { get; set; }
public EventStatus Status { get; set; }
}

  在api方法中我们用ModelState.IsValid判断就可以了。

1
2
3
4
5
6
7
8
9
10
11
12
public HttpResponseMessage Post(Event item)
{
    if (ModelState.IsValid)
    {
        // 保存操作
        return new HttpResponseMessage(HttpStatusCode.OK);
    }
    else
    {
        return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
    }
}

用AOP的方式去实现验证

  或者我们可以换成下面的这种方式,先创建一个Filter。

1
2
3
4
5
6
7
8
9
10
11
public class ValidateModelAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        if (!actionContext.ModelState.IsValid)
        {
            actionContext.Response = actionContext.Request.CreateErrorResponse(
                HttpStatusCode.BadRequest, actionContext.ModelState);
        }
    }
}

  再到Post和PUT的方法上面打上这个标签。

1
2
3
4
5
6
7
8
9
[HttpPut]
[ValidateModel]
public void Put(Event item)
{
    if (!repository.Update(item))
    {
        throw new HttpResponseException(HttpStatusCode.NotFound);
    }
}

  我们还需要在我们的WebApiConfig中注册这个Filter。

1
2
3
4
5
6
7
public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.Filters.Add(new ValidateModelAttribute());
    }
}

  

  前端拿到这个消息之后,就可以通知给用户了。当然最后还是需要加上前端验证,可以大大的提高用户体验以及减轻服务器的压力。