返璞归真 asp.net mvc (10) - asp.net mvc 4.0 新特性之 Web API
原文:返璞归真 asp.net mvc (10) - asp.net mvc 4.0 新特性之 Web API

[索引页]
[源码下载]

返璞归真 asp.net mvc (10) - asp.net mvc 4.0 新特性之 Web API

作者:webabcd

介绍
asp.net mvc 之 asp.net mvc 4.0 新特性之 Web API

  • 开发一个 CRUD 的 Demo,服务端用 Web API,并使其支持 jsonp 协议,客户端用 jQuery

示例
1、自定义一个 JsonMediaTypeFormatter,以支持 jsonp 协议
MyJsonFormatter.cs

/** 自定义一个 JsonMediaTypeFormatter,以支持 jsonp 协议*/using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using System.Web;namespace MVC40.Controllers
{public class MyJsonFormatter : JsonMediaTypeFormatter{// jsonp 回调的函数名称private string JsonpCallbackFunction;public MyJsonFormatter(){}public override bool CanWriteType(Type type){return true;}// 每个请求都先来这里public override MediaTypeFormatter GetPerRequestFormatterInstance(Type type, System.Net.Http.HttpRequestMessage request, MediaTypeHeaderValue mediaType){var formatter = new MyJsonFormatter(){JsonpCallbackFunction = GetJsonCallbackFunction(request)};// 增加一个转换器,以便枚举值与枚举名间的转换formatter.SerializerSettings.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter());// 增加一个转换器,以方便时间格式的序列化和饭序列化var dateTimeConverter = new Newtonsoft.Json.Converters.IsoDateTimeConverter();dateTimeConverter.DateTimeFormat = "yyyy-MM-dd HH:mm:ss";formatter.SerializerSettings.Converters.Add(dateTimeConverter);// 排版返回的 json 数据,使其具有缩进格式,以方便裸眼查看formatter.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.Indented;return formatter;}// 序列化的实现public override Task WriteToStreamAsync(Type type, object value, Stream stream, HttpContent content, TransportContext transportContext){if (string.IsNullOrEmpty(JsonpCallbackFunction))return base.WriteToStreamAsync(type, value, stream, content, transportContext);StreamWriter writer = null;try{writer = new StreamWriter(stream);writer.Write(JsonpCallbackFunction + "(");writer.Flush();}catch (Exception ex){try{if (writer != null)writer.Dispose();}catch { }var tcs = new TaskCompletionSource<object>();tcs.SetException(ex);return tcs.Task;}return base.WriteToStreamAsync(type, value, stream, content, transportContext).ContinueWith(innerTask =>{if (innerTask.Status == TaskStatus.RanToCompletion){writer.Write(")");writer.Flush();}}, TaskContinuationOptions.ExecuteSynchronously).ContinueWith(innerTask =>{writer.Dispose();return innerTask;}, TaskContinuationOptions.ExecuteSynchronously).Unwrap();}// 从请求 url 中获取其参数 callback 的值private string GetJsonCallbackFunction(HttpRequestMessage request){if (request.Method != HttpMethod.Get)return null;var query = HttpUtility.ParseQueryString(request.RequestUri.Query);var queryVal = query["callback"];if (string.IsNullOrEmpty(queryVal))return null;return queryVal;}}
}

2、在 Global 中做的一些配置
Global.asax.cs

using MVC40.Controllers;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Formatting;
using System.Net.Http.Headers;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;namespace MVC40
{public class WebApiApplication : System.Web.HttpApplication{protected void Application_Start(){AreaRegistration.RegisterAllAreas();WebApiConfig.Register(GlobalConfiguration.Configuration);FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);RouteConfig.RegisterRoutes(RouteTable.Routes);BundleConfig.RegisterBundles(BundleTable.Bundles);// 添加一个转换器 IsoDateTimeConverter,其用于日期数据的序列化和反序列化var dateTimeConverter = new IsoDateTimeConverter();dateTimeConverter.DateTimeFormat = "yyyy-MM-dd HH:mm:ss";JsonSerializerSettings serializerSettings = new JsonSerializerSettings();serializerSettings.Converters.Add(dateTimeConverter);// 清除全部 Formatter(默认有 4 个,分别是:JsonMediaTypeFormatter, XmlMediaTypeFormatter, FormUrlEncodedMediaTypeFormatter, JQueryMvcFormUrlEncodedFormatter)// GlobalConfiguration.Configuration.Formatters.Clear();// 如果请求 header 中有 accept: text/html 则返回这个新建的 JsonMediaTypeFormatter 数据var jsonFormatter = new JsonMediaTypeFormatter();jsonFormatter.SerializerSettings = serializerSettings;// jsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html")); jsonFormatter.MediaTypeMappings.Add(new RequestHeaderMapping("accept", "text/html", StringComparison.InvariantCultureIgnoreCase, true, new MediaTypeHeaderValue("text/html")));GlobalConfiguration.Configuration.Formatters.Insert(0, jsonFormatter);// 请求 url 中如果带有参数 xml=true,则返回 xml 数据GlobalConfiguration.Configuration.Formatters.XmlFormatter.MediaTypeMappings.Add(new QueryStringMapping("xml", "true", "application/xml"));// 请求 url 中如果带有参数 jsonp=true,则返回支持 jsonp 协议的数据(具体实现参见 MyJsonFormatter.cs)MyJsonFormatter formatter = new MyJsonFormatter();formatter.MediaTypeMappings.Add(new QueryStringMapping("jsonp", "true", "application/javascript"));GlobalConfiguration.Configuration.Formatters.Add(formatter);}}
}

关于项目模版生成的代码的简短说明

<p>项目模板更新了,原来堆在 Global.asax.cs 中的配置都分出去了<br />在 App_Start 文件夹里自动生成的 BundleConfig.cs 用于对多个 css 或 js 做打包和压缩<br />在 App_Start 文件夹里自动生成的 FilterConfig.cs 用于配置全局的 Action Filter<br />在 App_Start 文件夹里自动生成的 RouteConfig.cs 用于配置路由<br />在 App_Start 文件夹里自动生成的 WebApiConfig.cs 用于为 web api 配置路由
</p>

web api 的路由配置
WebApiConfig.cs

/** web api 的路由配置*/using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;namespace MVC40
{public static class WebApiConfig{public static void Register(HttpConfiguration config){// 此配置为默认生成的配置
            config.Routes.MapHttpRoute(name: "DefaultApi",routeTemplate: "api/{controller}/{id}",defaults: new { id = RouteParameter.Optional });// 由于默认为 web api 生成的路由配置,无 action 配置,所以只能通过 http 方法来匹配 action// 如果需要带 action 的路由则使用以下配置即可/*routes.MapHttpRoute(name: "ActionApi",routeTemplate: "api/{controller}/{action}/{id}",defaults: new { id = RouteParameter.Optional });*/}}
}

3、提供 Web API 服务的 Controller(数据层用 Entity Framework 5.0 来实现)
ProductsController.cs

/** ASP.NET Web API* * c - POST - 创建* r - GET - 读取* u - PUT - 更新* d - DELETE - 删除* * 注:win8 的 iis 默认不会安装 asp.net,需要在“程序和功能”中手动添加*/using MVC40.Models;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Http;namespace MVC40.Controllers
{/** Web API 的 Controller 要从 ApiController 继承* * 默认:http get 找 controller 的 get(), http post 找 controller 的 post(), http put 找 controller 的 put(), http delete 找 controller 的 delete()*/public class ProductsController : ApiController{// 获取全部 Product 数据:get http://localhost:17612/api/productspublic IEnumerable<Product> Get(){NorthwindEntities db = new NorthwindEntities();var products = from p in db.Productsorderby p.ProductID descendingselect p;return products.ToList();}// 根据 ProductId 获取指定的 Product 数据:get http://localhost:17612/api/products/3public Product Get(int id){NorthwindEntities db = new NorthwindEntities();var product = db.Products.SingleOrDefault(p => p.ProductID == id);return product;}// 新建 Product:post 一个 product 到 http://localhost:17612/api/productspublic void Post(Product product){NorthwindEntities db = new NorthwindEntities();db.Products.Add(product);db.SaveChanges();}// 更新 Product:put 一个 product 到 http://localhost:17612/api/productspublic void Put(Product product){NorthwindEntities db = new NorthwindEntities();db.Products.Attach(product);var entry = db.Entry(product);entry.State = EntityState.Modified;db.SaveChanges();}// 根据 ProductId 删除指定的 Product 数据:delete http://localhost:17612/api/products/3public void Delete(int id){NorthwindEntities db = new NorthwindEntities();var product = db.Products.SingleOrDefault(p => p.ProductID == id);db.Products.Remove(product);db.SaveChanges();}}
}

4、调用 Web API 的客户端(用 jQuery 实现)
CRUDDemo.cshtml

@{Layout = null;
}<!DOCTYPE html><html>
<head><title>演示如何通过 jQuery 调用 asp.net web api 做 crud 操作</title><script src="../Scripts/jquery-1.7.1.js" type="text/javascript"></script>
</head>
<body><table id="tblProducts" border="1"><tr><th>Product Id</th><th>Product Name</th><th>Unit Price</th><th>Actions</th></tr><tr><td><input type="text" id="txtProductId" size="5" disabled /></td><td><input type="text" id="txtProductName" /></td><td><input type="text" id="txtUnitPrice" /></td><td><input type="button" name="btnInsert" value="Insert" /></td></tr></table><script type="text/javascript">$(document).ready(function () {loadProductsAsync();});// 异步获取全部 Product 数据function loadProductsAsync() {$.getJSON("/api/products?jsonp=true&callback=?", loadProductsCompleted).error(function () { alert('error') });}// 显示获取到的 Product 数据function loadProductsCompleted(data) {$("#tblProducts").find("tr:gt(1)").remove();$.each(data, function (key, val) {var tableRow = '<tr>' +'<td>' + val.ProductID + '</td>' +'<td><input type="text" value="' + val.ProductName + '"/></td>' +'<td><input type="text" value="' + val.UnitPrice + '"/></td>' +'<td><input type="button" name="btnUpdate" value="Update" />  <input type="button" name="btnDelete" value="Delete" /></td>' +'</tr>';$('#tblProducts').append(tableRow);});$("input[name='btnInsert']").click(onInsert);$("input[name='btnUpdate']").click(onUpdate);$("input[name='btnDelete']").click(onDelete);}// 新增 Product 数据function onInsert(evt) {var productName = $("#txtProductName").val();var unitPrice = $("#txtUnitPrice").val();// 构建需要 post 的数据,即需要添加的数据var data = '{"ProductName":"' + productName + '","UnitPrice":' + unitPrice + '}';$.ajax({type: 'POST',url: '/api/products/',data: data,contentType: "application/json; charset=utf-8",dataType: 'json',success: function (results) {$("#txtProductName").val('');$("#txtUnitPrice").val('');alert('Product Added');loadProductsAsync();}})}// 更新 Product 数据function onUpdate(evt) {var productId = $(this).parent().parent().children().get(0).innerHTML;var cell = $(this).parent().parent().children().get(1);var productName = $(cell).find('input').val();cell = $(this).parent().parent().children().get(2);var unitPrice = $(cell).find('input').val();// 构建需要 put 的数据,即需要更新的数据var data = '{"ProductID":"' + productId + '","ProductName":"' + productName + '","UnitPrice":' + unitPrice + '}';$.ajax({type: 'PUT',url: '/api/products/',data: data,contentType: "application/json; charset=utf-8",dataType: 'json',success: function (results) {alert('Product Updated');}})}// 删除指定的 Product 数据function onDelete(evt) {var productId = $(this).parent().parent().children().get(0).innerHTML;$.ajax({type: 'DELETE',url: '/api/products/' + productId,contentType: "application/json; charset=utf-8",dataType: 'json',success: function (results) {alert('Product Deleted');loadProductsAsync();}})}</script>
</body>
</html>

OK
[源码下载]

posted on 2014-03-09 17:44 NET未来之路 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/lonelyxmas/p/3590291.html

返璞归真 asp.net mvc (10) - asp.net mvc 4.0 新特性之 Web API相关推荐

  1. 精进不休 .NET 4.0 (2) - asp.net 4.0 新特性之url路由

    [索引页] [源码下载] 精进不休 .NET 4.0 (2) - asp.net 4.0 新特性之url路由, 自定义CacheProvider, 新增的表达式<%: expression %& ...

  2. 如约而至,Java 10 正式发布:包含 109 项新特性

    如约而至,Java 10 正式发布:包含 109 项新特性 期待已久,没有跳票的 Java 10 已正式发布!你可以通过这里下载 Java 10 正式版. 此前我们曾报道过,为了更快地迭代,以及跟进社 ...

  3. 谷歌手机升级android10,Android Q安卓10.0新特性,首批支持升级21款手机

    原标题:Android Q安卓10.0新特性,首批支持升级21款手机 2019年5月8日,一年一度的谷歌I/O开发者大会在美国加州如期召开,并发布了全新系列Android Q(安卓10.0)操作系统, ...

  4. 背水一战 Windows 10 (1) - C# 6.0 新特性

    背水一战 Windows 10 (1) - C# 6.0 新特性 原文:背水一战 Windows 10 (1) - C# 6.0 新特性 [源码下载] 背水一战 Windows 10 (1) - C# ...

  5. 背水一战 Windows 10 (43) - C# 7.0 新特性

    背水一战 Windows 10 (43) - C# 7.0 新特性 原文: 背水一战 Windows 10 (43) - C# 7.0 新特性 [源码下载] 背水一战 Windows 10 (43) ...

  6. .NET2.0和microsoft新知识体系-ASP.NET 2.0新特性

    ASP.NET技术从1.0版本升级到1.1变化不是很大.然而,从ASP.NET 1.x升级到2.0,却不是件轻而易举的事情.ASP.NET 2.0技术增加了大量方便.实用的新特性.图1-1所示列举了A ...

  7. ASP.NET Core与Dapper和VS 2017使用JWT身份验证WEB API并在Angular2客户端应用程序中使用它

    目录 介绍 背景 步骤1 创建ASP.NET Core Web API项目 Fitness.JWT.API项目说明 使用代码 startup.cs JwtIssuerOptions.cs JwtCon ...

  8. Java 10正式发布,带来了这些新特性

    点击上方"程序员小灰",选择"置顶公众号" 有趣有内涵的文章第一时间送达! 本文转载自公众号  InfoQ 作者 | 张建锋编辑 | 郭蕾 北京时间 3 月 2 ...

  9. 10个不那么知名但很强大的Web API

    点击上方 前端Q,关注公众号 回复加群,加入前端Q技术交流群 作者 | Tapas Adhikary 译者 | 平川  策划 | 小智 在本文中,我将介绍 10 个不那么流行的 Web API.不那么 ...

最新文章

  1. 树状数组 | 1057
  2. mysql安装教程8.3,Summary_虚拟机安装centos8.3Linux系统_安装Mysql
  3. web展现mysql_web页面实现LED跑马灯效果(涉及web前端、原生JS、PHP、mysql)
  4. postman可以测试websocket吗_小海塔罗娱乐测试2021年可以脱单吗?
  5. OC之ARC环境中的循环strong问题
  6. python 函数可以作为容器对象的元素_14、函数对象和闭包
  7. 单点登录相关问题总结
  8. swig: 未找到命令
  9. 明尼苏达大学Transportation Research Data Lab (TDRL)交通数据读取
  10. 梦想易语言零基础注册机到多线程教程
  11. 路由器恢复出厂设置后dns服务器未响应,路由器恢复出厂设置后连不上网怎么办?...
  12. .Net Core 阿里云短信服务Demo
  13. Unity 打包项目发红
  14. CVF2020邻域自适应/语义分割:FDA: Fourier Domain Adaptation for Semantic SegmentationFDA:用于语义分割的傅立叶域自适应算法
  15. labview文件上传服务器,基于labview的局域网TCP传输文件夹问题的解决
  16. 现代人必备的计算机工具
  17. 一位牵手腾讯应届毕业生的求职杂谈
  18. 人脸对齐(Face Alignment)
  19. python和土木工程_Python 的开发效率真的比 Java高吗?
  20. 数码相机必备软件-Download篇

热门文章

  1. python 句子中没有中文_AI伪原创,我们是认真的。[Python实现]
  2. linux安装tune2fs工具,linux tune2fs简解(每日一令之五)
  3. echarts tree默认展开_echarts tree控制节点的展开收起
  4. vsftp匿名访问目录_vsftp 匿名访问设置设置
  5. fast软件_自媒体者遇见喜欢好听的视频背景音乐,用一款软件就可以把它提取...
  6. 梦幻桌面wmv_【 梦幻桌面 】梦幻桌面(DreamScene桌面美化工具)新版下载 - U大师
  7. 跨网页的新手引导_IOS中新手引导页面的实现(新手引导,Guide)
  8. php请求aspx,PHP用curl函数POST请求到ASP页面提示无效请求
  9. MATLAB对比度调节工具
  10. 学习Kali Linux必须知道的几点