目前WebApi在使用上大部分都是跟MVC组合的,而且使用起来也确实十分便利。

但有时候我们也需要在WebForm中使用WebApi,二者还是有一定区别的。

首先看下结构

 ①ApiController

即Controller部分,当然也包含Api的路径也是很重要的。这里面是Api/{function}/{controller}/{action}

看一下Controller里面的内容

using System;
using System.Web.Http; namespace WebApiTest.Api.Func
{
public class TestController : ApiController
{
[HttpPost]
public TestModel Post([FromBody]TestModel model)
{
model.Name = "Post";
model.UpdatedOn = DateTime.Now;
model.Age++;
return model;
}
}
}

注意的地方有这么几点:

  • Controller要继承ApiController
  • Action要加上特性 [HttpPost] ,[HttpGet] 。。。如下图
  • 一般情况我们用的都是[HttpPost],这时候参数中就要加特性[FromBody]了
  • 为了能够直接使用请求过来的数据,而不必去转化成对应的实体类,我们需要给参数实体类加特性[Newtonsoft.Json.JsonObject]否则返回的数据会是酱紫的

这是使用的实体类

[Newtonsoft.Json.JsonObject]
public class TestModel
{
public string Name { set; get; } public int Age { set; get; } public DateTime UpdatedOn { set; get; }
}

②跨域处理程序CorsHandler.cs

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Net.Http;
using System.Threading.Tasks;
using System.Threading;
using System.Net; namespace WebApiTest.Handler
{
public class CorsHandler : DelegatingHandler
{
const string Origin = "Origin";
const string AccessControlRequestMethod = "Access-Control-Request-Method";
const string AccessControlRequestHeaders = "Access-Control-Request-Headers";
const string AccessControlAllowOrigin = "Access-Control-Allow-Origin";
const string AccessControlAllowMethods = "Access-Control-Allow-Methods";
const string AccessControlAllowHeaders = "Access-Control-Allow-Headers"; protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
bool isCorsRequest = request.Headers.Contains(Origin);
bool isPreflightRequest = request.Method == HttpMethod.Options;
if (isCorsRequest)
{
if (isPreflightRequest)
{
return Task.Factory.StartNew<HttpResponseMessage>(() =>
{
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
response.Headers.Add(AccessControlAllowOrigin, request.Headers.GetValues(Origin).First()); string accessControlRequestMethod = request.Headers.GetValues(AccessControlRequestMethod).FirstOrDefault();
if (accessControlRequestMethod != null)
{
response.Headers.Add(AccessControlAllowMethods, accessControlRequestMethod);
} string requestedHeaders = string.Join(", ", request.Headers.GetValues(AccessControlRequestHeaders));
if (!string.IsNullOrEmpty(requestedHeaders))
{
response.Headers.Add(AccessControlAllowHeaders, requestedHeaders);
} return response;
}, cancellationToken);
}
else
{
return base.SendAsync(request, cancellationToken).ContinueWith<HttpResponseMessage>(t =>
{
HttpResponseMessage resp = t.Result;
resp.Headers.Add(AccessControlAllowOrigin, request.Headers.GetValues(Origin).First());
return resp;
});
}
}
else
{
return base.SendAsync(request, cancellationToken);
}
}
}
}

CorsHandler.cs

③Controller配置程序 HttpControllerSelector.cs

 using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Web.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Dispatcher; namespace WebApiTest.Handler
{
public class HttpControllerSelector : DefaultHttpControllerSelector
{
private HttpConfiguration configuration = null;
public HttpControllerSelector(HttpConfiguration configuration)
: base(configuration)
{
this.configuration = configuration;
GetControllerMapping();
} public override string GetControllerName(HttpRequestMessage request)
{
object function, c;
var routedata = request.GetRouteData(); if (routedata.Values.TryGetValue("function", out function) &&
routedata.Values.TryGetValue("controller", out c))
{
var item = dict.FirstOrDefault(t => t.Key.Contains(string.Format("{0}.{1}controller", function, c).ToLower()));
if (item.Value != null)
{
return item.Value.ControllerName;
}
}
return base.GetControllerName(request);
} IDictionary<string, HttpControllerDescriptor> dict = new Dictionary<string, HttpControllerDescriptor>();
public override IDictionary<string, HttpControllerDescriptor> GetControllerMapping()
{
var list = Assembly.GetAssembly(this.GetType()).GetTypes().Where(t => t.IsSubclassOf(typeof(ApiController)));
foreach (var type in list)
{
dict.Add(type.FullName.ToLower(), new HttpControllerDescriptor(this.configuration, type.FullName.ToLower(), type));
} return dict;
} public override HttpControllerDescriptor SelectController(HttpRequestMessage request)
{
HttpControllerDescriptor c;
var cn = GetControllerName(request);
if (dict.TryGetValue(cn, out c))
{
return c;
}
return base.SelectController(request);
}
}
}

HttpControllerSelector.cs

④路由注册程序WebApiConfig.cs

 using System.Web.Http;
using System.Web.Http.Dispatcher; namespace WebApiTest.Handler
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API 配置和服务
config.Services.Replace(typeof(IHttpControllerSelector), new HttpControllerSelector(config)); config.Routes.MapHttpRoute(
name: "Api",
routeTemplate: "api/{function}/{controller}/{action}"
);
}
}
}

WebApiConfig.cs

⑤Global.asax.cs

在该文件中添加如下代码

        public override void Init()
{
this.EndRequest += Global_EndRequest;
this.BeginRequest += Global_BeginRequest;
base.Init();
} protected void Application_Start(object sender, EventArgs e)
{
GlobalConfiguration.Configuration.MessageHandlers.Add(new CorsHandler());
WebApiConfig.Register(GlobalConfiguration.Configuration);
}

至此 服务端的配置就基本OK了。

调用的地方用如下Ajax就可以了

$.ajax({
url: "api/func/Test/Post",
type: "POST",
data: {Name:"Ray"},
dataType:"json",
success: function (result) {
console.log(result);
}
});

代码下载


上面讲的是服务端的配置,顺带一提客户端的调用。

但是,如果是在后台调用某个WebApi该如何破呢?

我使用的是Intersoft的CrossLight,用起来也是比较简单。

TestModel model = new TestModel();
RestClient c = new RestClient("http://localhost:1234/API/Module/");
RestRequest req = new RestRequest("Function/Do", HttpMethod.POST);
req.RequestFormat = RequestDataFormat.Json;
req.AddBody(model);
var res = c.ExecuteAsync<WebApiModel>(req);
var tmp = JsonConvert.DeserializeObject<WebApiModel<TestModel>>(res.Result.Content).Model; if (res.Result.Data.HasError) {
throw new Exception(res.Result.Data.ErrorMessage);
}

这里面有个包装的类WebApiModel,是为了更好的传递其他信息(如错误信息),定义如下

using System;

namespace XX
{
[Newtonsoft.Json.JsonObject]
[Serializable]
public class WebApiModel
{
public WebApiModel()
{ } public WebApiModel(object model)
{
this.Model = model;
} public object Model { get; set; } public bool HasError
{
get
{
return !string.IsNullOrEmpty(ErrorMessage);
}
}
public string ErrorMessage { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace XX
{
[Newtonsoft.Json.JsonObject]
[Serializable]
public class WebApiModel<T>
{
public WebApiModel()
{ } public WebApiModel(T model)
{
this.Model = model;
} public T Model { get; set; } public bool HasError
{
get
{
return !string.IsNullOrEmpty(ErrorMessage);
}
}
public string ErrorMessage { get; set; }
}
}

Asp.Net实现WebApi跨域 (非MVC)的更多相关文章

  1. ASP.Net开发WebAPI跨域访问(CORS)的精简流程

    1: Web.config里有一行: <remove name="OPTIONSVerbHandler" /> 这个要删除. 2: nuget安装Microsoft.A ...

  2. 连表查询都用Left Join吧 以Windows服务方式运行.NET Core程序 HTTP和HTTPS的区别 ASP.NET SignalR介绍 asp.net—WebApi跨域 asp.net—自定义轻量级ORM C#之23中设计模式

    连表查询都用Left Join吧   最近看同事的代码,SQL连表查询的时候很多时候用的是Inner Join,而我觉得对我们的业务而言,99.9%都应该使用Left Join(还有0.1%我不知道在 ...

  3. asp.net—WebApi跨域

    一.什么是跨域? 定义:是指浏览器不能执行其他网站的脚本,它是由浏览器的同源策略造成的,是浏览器对JavaScript实施的安全限制. 同源策略限制了以下行为: 1.Cookie.LocalStora ...

  4. WebAPI跨域处理

    原文来自:http://www.cnblogs.com/heifengwll/p/6243374.html WebApi2跨域问题   一.跨域问题产生的原因:同源策略(Same origin pol ...

  5. SNF快速开发平台MVC-EasyUI3.9之-WebApi跨域处理方案

    在做Web开发中,常常会遇到跨域的问题,到目前为止,已经有非常多的跨域解决方案.由于时间有限,本文不会深入. 笔者遇到的问题是Js调用WebAPI中的数据进行跨域的场景.涉及若干跨域方案:目前采用we ...

  6. C#进阶系列——WebApi 跨域问题解决方案:CORS

    前言:上篇总结了下WebApi的接口测试工具的使用,这篇接着来看看WebAPI的另一个常见问题:跨域问题.本篇主要从实例的角度分享下CORS解决跨域问题一些细节. WebApi系列文章 C#进阶系列— ...

  7. WebApi 跨域问题解决方案:CORS

    注:本文为个人学习摘录,原文地址:http://www.cnblogs.com/landeanfen/p/5177176.html 前言:上篇总结了下WebApi的接口测试工具的使用,这篇接着来看看W ...

  8. 关于WebApi 跨域问题的解决的方式

    最近在做WebApi 进行开发的时候 一直会遇到跨域方面的问题那么如何进行跨域问题其实非常的简单. 1.一直在使用WebApi的时候总是遇到跨域的问题 那么 什么是跨域?跨域,指的是浏览器不能执行其他 ...

  9. C#进阶系列——WebApi 跨域问题解决方案:CORS(转载)

    C#进阶系列——WebApi 跨域问题解决方案:CORS   阅读目录 一.跨域问题的由来 二.跨域问题解决原理 三.跨域问题解决细节 1.场景描述 2.场景测试 四.总结 正文 前言:上篇总结了下W ...

随机推荐

  1. fis3使用环境

    1.全局安装nodejs 2.安装http-server npm install http-server -g 3.安装fis3 npm install -g fis3 如要限制版本号写法是:npm ...

  2. Mysql学习笔记(三)运算符和控制流函数

    本章学习内容: 1.操作符 2.控制流程函数 操作符: i.圆括号.. 简单的介绍一下圆括号,圆括号的使用的目的是规定计算表达式的顺序...这个想必大家都熟悉例如  mysql>select 1 ...

  3. css居中学习笔记

    css居中学习笔记 一.水平居中 以下面的代码为例: <body> <div class="parent"> <div class="chi ...

  4. mysql update中需要根据条件列更新写法update case

    以下两条语句是否可以合并成一条: where b>'2015-10-12'; , e='2015-01-01' where b='2015-10-12'; 既然来写博客了,那答案肯定是可以的, ...

  5. PHP 表单验证--安全性--小记

    HTML 表单数据进行适当的验证对于防范黑客和垃圾邮件很重要! -------------------------------------------------------------------- ...

  6. android 获取当前位置

    1. Android开发位置感知应用程序方式:1. GPS 定位     精确度高,仅适用于户外,严重消耗电量.如果手机内置GPS接受模块,即使手机处于信号盲区,依然可以获取位置信息. 2. NETW ...

  7. JS 获取 本周、本月、本季度、本年、上月、上周、上季度、去年

    工具类定义: /** * 日期范围工具类 */ var dateRangeUtil = (function () { /*** * 获得当前时间 */ this.getCurrentDate = fu ...

  8. Oracle级联查询

    在ORACLE 数据库中有一种方法可以实现级联查询   select  *                //要查询的字段 from table              //具有子接点ID与父接点I ...

  9. 很震撼的HTML5视频播放器,电影院的感觉

    效果很震撼!有电影院的感觉了.呵呵. 看了下代码,依然是 在一个canvas里嵌入<video>然后getImageData 点击这里查看效果 代码: var canvas = docum ...

  10. 译 PrestaShop开发者指南 第四篇 深入PrestaShop核心开发

    ## 访问数据库 ### 数据库结构 PrestaShop的数据库表默认带有ps_的前缀,前缀在安装时可以自定义. 所有表名都是小写,以下划线分割.当一个表表示要在两个实体间建立连接时,表名中两个实体 ...