目前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. 复利程序(c语言)(张俊毅 周修文)

    因为之前发烧一直没有了解这个 所以最近才补上 分数扣了就扣了 补上先 单元测试迟点更 #include<stdio.h> #include <math.h> #include ...

  2. JS 中 this上下文对象的使用方式

    JavaScript 有一套完全不同于其它语言的对 this 的处理机制. 在五种不同的情况下 ,this 指向的各不相同. 有句话说得很在理 -- 谁调用它,this就指向谁 一.全局范围内 在全局 ...

  3. 爆搜 + 模拟 --- codeforces 475C

    Problem's Link:http://codeforces.com/problemset/problem/475/Chttp://codeforces.com/problemset/proble ...

  4. GitHub Extension for Visual Studio 2.0 is now available

    GitHub Extension for Visual Studio 2.0 is now available We're pleased to announce that version 2.0 o ...

  5. Asp.Net 三层架构之泛型应用

    一说到三层架构,我想大家都了解,这里就简单说下,Asp.Net三层架构一般包含:UI层.DAL层.BLL层,其中每层由Model实体类来传递,所以Model也算是三层架构之一了,例外为了数据库的迁移或 ...

  6. 控制网页的Panel是否显示

    在网页上有十二个Panel控件,默认状态是不显示的,根据当前月作为条件去控制对应的Panel控件显示. Insus.NET以下使用三种方法来实现它,先是第一种,使用FindControl方法 第二种方 ...

  7. .net开发微信公众平台

    一.说明:公众平台信息接口为开发者提供了一种新的消息处理方式,只有申请成为开发者后,你才能使用公众平台的开发功能,在这里你需要填写一个URL和一个Token,这两项信息也需要你拥有自己的服务器(外网服 ...

  8. inotify--内核中文件系统的通知机制

    转载:http://www.ibm.com/developerworks/cn/linux/l-inotifynew/index.html 一. 引言 众所周知,Linux 桌面系统与 MAC 或 W ...

  9. java之内的工具分享,附带下载链接,方便以后自己寻找

    class反编译工具:http://pan.baidu.com/s/1geYvX5L redis客户端工具:http://pan.baidu.com/s/1eRJ4ThC mysql客户端-[mysq ...

  10. play HTTP路由 http://play-framework.herokuapp.com/zh/routes#syntax

    HTTP路由 HTTP路由(译者注:Play的路径映射机制)组件负责将HTTP请求交给对应的action(一个控制器Controller的公共静态方法)处理. 对于MVC框架来说,一个HTTP请求可以 ...