在Web框架的范畴内,一切都是基于REST的-- 从返回包含CSS、JavaScript的网页的路由路径,到那些返回JSON数据的URL。

无论你怎么看它,两者都是必须的。我们使用一组URL来呈现URL,使用第二组URL给UI提供动态数据。有时我们还需要第三组URL给移动端提供数据。

其中的重复可能需要大量的工作。并且在我看来,这也是不优雅的。为了解决这个问题,很多框架(包含Nancy)提供了一种叫做内容协商(content negotiatio)的机制。

   协商什么内容

当你使用浏览器发出请求时(或者代码访问服务器),你就已经提供了很多信息来描述这个请求。

这些信息被称为请求头(request headers):

请看上图中请求头的Accept 行,这一行是用来描述浏览器或调用程序接收的内容类型,在我们的例子中是:

Accept: text/html,application/xhtml+xml,application/xml,image/webp,*/*

其中说,按优先顺序排列,我希望能接收到 html、 xml 或 webp 图像,如果不能提供序列中的任何类型,那随便什么都可以了。

Nancy在收到客户端请求后会留意请求头中Accept部分。基于查找到的资源,也是可以改变输出的请求头。

如果请求头中的Accept 如下:

Accept: application/json

Nancy会检查返回的数据是否是JSON格式的数据,如果不是,就会抛出异常,报出请求失败。假如我们不想请求失败,可以添加 */* 到后面,正如之前的示例,Nancy就能返回默认的内容。

默认情况下,在没有任何额外配置的情况下Nancy就能决定是否返回HTML,XML,或是JSON。如果你要创建一个API,用来返回一个简单的模型,正如我们前面章节介绍的,Nancy一般都能正确地返回。

如果你在浏览器下请求一个URL,Nancy会在视图文件夹中寻找一个名称匹配的文件。

就拿之前的Address对象举例,Nancy 会查找下面的文件:

'~/Views/Address.Html'

如果URL请求是来自网页中Javascript的调用,Accept头信息中会请求JSON类型的内容,Nancy会将对象按照JSON语法进行序列化,并返回。

如果允许Nancy自由支配返回的内容类型,只需要在路由模块中返回一个对象模型即可。这里没有用到之前那些返回字符串,网页或是视图内容的方法。如果使用了其中的方式,Nancy也就用不到对accept头信息进行分析了。最为简洁的方式如下:

Get[@"/{id}"] = parameters =>
{
int recId = parameters.id;
var record = Database.Find(recId);
return record;
};

无论是使用 new 创建一个对象或是从后台存储生成一个对象,Nancy都会根据头信息中的描述决定如何进行响应。

你也可以使用Negotiate响应API来完成同样的任务。区别就是你可以更多的控制响应,比如修改视图文件的名称,或是添加额外的头信息。该响应API的使用方法如下:

Get[@"/{id}"] = parameters =>
{
int recId = parameters.id;
var record = Database.Find(recId);
return Negotiate
.WithModel(record)
.WithHeader("X-CustomHeader", "Some custom value");
};

和之前一样,Database对象返回一条记录,不同的是这次不再直接返回对象模型,而是在响应中增加了一个定制化的头信息。通过这种方式可以在响应上增加一系列的添加。通过Visual Studio 的智能提示可以看到如下:

总结

在本章中,你已经简单的了解了Nancy中的内容协商 -- 如此简单的一个概念,无需配置就能执行。

你已经看到了,正确的使用内容协商,一个URL就能实现众多API,降低了维护的复杂性。

下一章,我们会近距离的看下Nancy的响应对象(response),区别下向客户端返回数据和返回网页的差异。

NancyFX 第八章 内容协商的更多相关文章

  1. NancyFx And ReactiveX

    http://reactivex.io/ https://github.com/dotnet/reactive http://nancyfx.org/ NancyFX Nancy快速上手 (使用Nan ...

  2. NancyFX 简介

    Nancy是.NET 平台的微框架.在受到Ruby社区的Sinatra框架启发下,NancyFx框架提供一个.NET平台下的低门槛.易上手的可用于Web开发工具包. 请注意我说的是可用于Web开发,这 ...

  3. NancyFX 第一章 NancyFX 简介

    Nancy是.NET 平台的微框架.在受到Ruby社区的Sinatra框架启发下,NancyFx框架提供一个.NET平台下的低门槛.易上手的可用于Web开发工具包. 请注意我说的是可用于Web开发,这 ...

  4. 前端学HTTP之内容协商

    前面的话 一个URL常常需要代表若干不同的资源.例如那种需要以多种语言提供其内容的网站站点.如果某个站点有说法语的和说英语的两种用户,它可能想用这两种语言提供网站站点信息.理想情况下,服务器应当向英语 ...

  5. 精通Web Analytics 2.0 (10) 第八章:竞争情报分析

    精通Web Analytics 2.0 : 用户中心科学与在线统计艺术 第八章:竞争情报分析 在现实世界中,收集竞争情报可能意味着雇人在竞争对手的垃圾桶(实际会发生!)翻找. 在虚拟世界中,堆如山的数 ...

  6. 《Linux内核设计与实现》读书笔记 第十八章 调试

    第十八章调试 18.1 准备开始          需要准备的东西: l  一个bug:大部分bug通常都不是行为可靠而且定义明确的 l  一个藏匿bug的内核版本:找出bug首先出现的版本 l  相 ...

  7. 《Entity Framework 6 Recipes》中文翻译系列 (42) ------ 第八章 POCO之使用POCO

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 第八章 POCO 对象不应该知道如何保存它们,加载它们或者过滤它们.这是软件开发中熟 ...

  8. 《Entity Framework 6 Recipes》中文翻译系列 (46) ------ 第八章 POCO之领域对象测试和仓储测试

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 8-8  测试领域对象 问题 你想为领域对象创建单元测试. 这主要用于,测试特定的数 ...

  9. Python之路【第十八章】:Django基础

    Django基本配置 Python的WEB框架有Django.Tornado.Flask 等多种,Django相较与其他WEB框架其优势为:大而全,框架本身集成了ORM.模型绑定.模板引擎.缓存.Se ...

随机推荐

  1. Python网络编程(1)-socket

    我会在近期尽快更新好之前写的博客,会添加新的知识点和注意问题,排版和内容都会较之前有很大的改观,感谢大家一直的支持! 1. 客户端/服务器架构 客户端/服务器架构也称主从式架构,简称C/S架构,它是一 ...

  2. 一起学微软Power BI系列-使用技巧(6) 连接Sqlite数据库

    好久没有研究Power BI了,看到高飞大神弄的东西,太惭愧了.今天有个小东西,数据在Sqlite里面,想倒腾到Power BI Desktop里面折腾一下,结果发现还不直接支持.所以只好硬着头皮上去 ...

  3. 软AP的实现------hostapd的编译运行

    最近要给摄像头做一个软ap,让手机能够连上这个热点,从而能够与摄像头进行通信. 1.什么是hostapd : hostapd能够使得无线网卡切换为master模式,模拟AP(通常可以认为是路由器)功能 ...

  4. elasticsearch-5.1.1使用snapshot接口备份索引

    如果ES是集群,那么需要使用共享存储,支持的存储有:a.shared file systemb.S3c.HDFS 我使用的是第一种,NFS共享文件系统.这里要说一下权限问题,ES一般是使用 elast ...

  5. Spring / Hibernate 应用性能调优

    来源:ImportNew - 陈晓舜 对大部分典型的Spring/Hibernate企业应用来说,应用的性能大部分由持久层的性能决定. 这篇文章会重温一下怎么去确认我们的应用是否是”数据库依赖(dat ...

  6. Apple 内购

    关于内购所需东西: 1.测试开发证书:需要打开in-app-purchase,绑定bundleid:com.aragon.TexasPoker 2.iTunes connect 里添加内购应用: 1& ...

  7. html、text、val、attr、prop区别。this.value和$(this).val()区别以及return用法

    html(): html() 方法返回或设置被选元素的内容 (inner HTML). 当使用该方法读取多个值时,它会返回第一个匹配元素的内容. 当使用该方法设置一个值时,它会覆盖所有匹配元素的内容. ...

  8. redis绑定ip以及启动和查看启动状态

    改绑定ip: 或许是对redis的了解还不够多的缘故,单单只是从安装和启动来讲,个人觉得好像是比mongodb和mysql要简单一些. 我的安装包是这个:http://download.csdn.ne ...

  9. sdl的缩放问题

    SDL是一种既是开源的,也是跨平台的多媒体开发包,在各种平台上应用很广,经常和FFMPEG等解码器同时使用.对于在windows mobile等缺乏通用播放器的平台来说,是一种很好的选择.网上很多代码 ...

  10. Caused by: org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; Content is not allowed in

    1.错误描述 严重: Exception sending context initialized event to listener instance of class org.springframe ...