瞎折腾之Mvc WebApi的使用以及跨域问题
在公司经常会用到调用接口的情况,但是一直是用的webservice,我感觉真是太笨重了。虽然某些人感觉用的很爽、非常爽。比如说:公司在开发的时候需要对接另一组的接口,然后就只能是指定端口和ip到他的电脑。其中各种问题,他在修改代码,或者电脑不开启,我们这边都不能进行开发了。我希望下次能用上api
然后就是,园子里好多api的文章都没有降到跨域的解决方案,演示项目创建成功了,然后就在当前项目的调取成功了api的接口方法。就成功了?逗我们玩呢?没有错、就是在逗我们玩。
接下来让我们进入webapi
创建WebApi项目
这里我已经提前创建好了2个站点,一个api和一个mvc项目。然后分别添加到IIS(这里的iis8),如果不知道怎么添加到iis我就简单描述一下。
打开iis管理器-->网站,右键添加网站-->网站名称随意取名、物理路径选择你项目web所在路径-->然后是应用程序池,最好选择DefaultAppPool-->主机名:取一个自己网站的名字(注意:这里的名字是需要配置host文件的)-->确定
然后就是配置host文件了,C:\Windows\System32\Drivers\etc 路径下面的hosts文件,有些电脑是可以直接修改的,如果不可以就复制到桌面修改了再放进去这个文件夹下面即可。配置如下:
127.0.0.1 myWeb.loca/
127.0.0.1 myApi.loca/
我的web主机名:myWeb.loca/(跟配置iis给自己网站取名是一样的)
我的api主机名:myApi.loca/(跟配置iis给自己网站取名是一样的)
浏览器访问的时候在前面记得加上:http://myWeb.loca/


开启api路程
接下来我开始实施工程了。上面一系列的配置已经准备好。
首先我就要修改webapi的路由,因为默认的是根据参数的传递来决定访问的方法的。这里我设置成mvc的习惯 App_Start-->WebApiConfig.cs
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
然后就是已经写好了的api一个方法
public class ValuesController : ApiController
{
private LX.EFOPT.BLL.IBLL.IUser_InfoBLL User_InfoBLL = new User_InfoBLL(); // GET api/values
public string GetList()
{
List<LX.EFOPT.Model.User_Info> modelUser_InfoList = User_InfoBLL.GetUser_InfoList(); string jsonList = JsonUtils.SerializeToJson(modelUser_InfoList); return JsonUtils.SerializeToJson(new
{
code = "",
msg = "success",
data = modelUser_InfoList
});
}
然后呢,我们直接在浏览器访问这个api,验证一下我们的数据是否正确输出,直接访问地址:http://myapi.loca/api/values/GetList
结果显示如下:

哎呀妈呀,好开森!当然,这还没有完呢,我没有逗你们玩。接下来,我在myWeb.loca/ 这个web站点访问api。走你~
同样、我已经在web站点建好了一个user控制器、马上建一个apitest的页面
<input type="button" id="getlist" value="get数据list" /><br />
function getlist() {
var url = "http://myapi.loca/api/values/GetList?callback=?";
console.log("getJSON:start");
$.getJSON(url,
function (data) {
//处理data数据
console.log("getJSON:end");
console.log($.parseJSON(data));
});
}

返回结果:没有执行回调函数
这个问题第一次会很难找到原因。ajax已经执行而且状态是200,在Network里面还可以看见Response返回的字符串。总之、在$.getJSON的回调函数里面没有执行返回结果。
第一种解决方案
1、我们先来一个低成本(低版本)的解决方案。因为此版本只需要Framework 4.0就可以了
我们在App_Start文件夹下面添加一个JsonCallbackAttribute属性类,让它继承自ActionFilterAttribute。注意看代码,这段代码是根据传过来的参数callback判断的
public class JsonCallbackAttribute : ActionFilterAttribute
{
private const string CallbackQueryParameter = "callback";
public override void OnActionExecuted(HttpActionExecutedContext context)
{
var callback = string.Empty; if (IsJsonp(out callback))
{
var jsonBuilder = new StringBuilder(callback); jsonBuilder.AppendFormat("({0})", context.Response.Content.ReadAsStringAsync().Result); context.Response.Content = new StringContent(jsonBuilder.ToString());
} base.OnActionExecuted(context);
} private bool IsJsonp(out string callback)
{
callback = HttpContext.Current.Request.QueryString[CallbackQueryParameter];
return !string.IsNullOrEmpty(callback);
}
}
然后把这个 [JsonCallback]属性加到api方法上面或者控制器上面都可以。
[JsonCallback]
public class ValuesController : ApiController
//或者
[JsonCallback]
public string GetList()
{
}
接下来我们再看看执行ajax之后的结果是怎么样呢?

加了[JsonCallback]结果显示:很明显结果显示回调成功了。而且还打印出了json,此刻代表着我们的方案成功了。哎哟、不错哦~
第二种解决方案
这个方法需要的成本可就高点了,至少是Framework 4.5以上的版本才行。怕什么。装一个就可以了呗。是、但是一般的服务器上面有4.5的吗?反正我们的就没有
第一步:还是在api站点的App_Start文件夹下面添加一个JsonpMediaTypeFormatter类
public class JsonpMediaTypeFormatter : JsonMediaTypeFormatter
{
public string Callback { get; private set; } public JsonpMediaTypeFormatter(string callback = null)
{
this.Callback = callback;
}
public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, System.Net.TransportContext transportContext)
{
if (string.IsNullOrEmpty(this.Callback))
{
return base.WriteToStreamAsync(type, value, writeStream, content, transportContext);
}
try
{
this.WriteToStream(type, value, writeStream, content);
return Task.FromResult<AsyncVoid>(new AsyncVoid());
}
catch (Exception exception)
{
TaskCompletionSource<AsyncVoid> source = new TaskCompletionSource<AsyncVoid>();
source.SetException(exception);
return source.Task;
}
} private void WriteToStream(Type type, object value, Stream writeStream, HttpContent content)
{
JsonSerializer serializer = JsonSerializer.Create(this.SerializerSettings);
using (StreamWriter streamWriter = new StreamWriter(writeStream, this.SupportedEncodings.First()))
using (JsonTextWriter jsonTextWriter = new JsonTextWriter(streamWriter) { CloseOutput = false })
{
jsonTextWriter.WriteRaw(this.Callback + "(");
serializer.Serialize(jsonTextWriter, value);
jsonTextWriter.WriteRaw(")");
}
} public override MediaTypeFormatter GetPerRequestFormatterInstance(Type type, HttpRequestMessage request, MediaTypeHeaderValue mediaType)
{
if (request.Method != HttpMethod.Get)
{
return this;
}
string callback;
if (request.GetQueryNameValuePairs().ToDictionary(pair => pair.Key,
pair => pair.Value).TryGetValue("callback", out callback))
{
return new JsonpMediaTypeFormatter(callback);
}
return this;
}
}
第二步:在Global.asax的Application_Start里面注册一下全局
GlobalConfiguration.Configuration.Formatters.Insert(, new JsonpMediaTypeFormatter());
其实还有第三第四中解决方案的、只是我测试还没有成功,不知道具体是什么原因。
总结
这里解决了ajax get获取数据的方法,至于post嘛、客户端自己ajax先提交到自己的Handler.ashx或者控制器嘛。然后用httppost去提交api的接口也是一样的。
谢谢!希望各位大神能留下一点建议和意见,本人才开始写文章。给点鼓励。
感谢大神的文章
参考文章:http://www.cnblogs.com/artech/p/cors-4-asp-net-web-api-03.html
http://stackoverflow.com/questions/9421312/jsonp-with-asp-net-web-api/18206518#18206518
原文出自:http://www.cnblogs.com/lxsweat/
瞎折腾之Mvc WebApi的使用以及跨域问题的更多相关文章
- Asp.Net WebApi+Microsoft.AspNet.WebApi.Core 启用CORS跨域访问
WebApi中启用CORS跨域访问 1.安装 Nugget包Microsoft.AspNet.WebApi.Cors This package contains the components to e ...
- ASP.Net中关于WebAPI与Ajax进行跨域数据交互时Cookies数据的传递
本文主要介绍了ASP.Net WebAPI与Ajax进行跨域数据交互时Cookies数据传递的相关知识.具有很好的参考价值.下面跟着小编一起来看下吧 前言 最近公司项目进行架构调整,由原来的三层架构改 ...
- asp.net (webapi) core 2.1 跨域配置
原文:asp.net (webapi) core 2.1 跨域配置 官方文档 ➡️ https://docs.microsoft.com/zh-cn/aspnet/core/security/cors ...
- ahjesus 让我的MVC web API支持JsonP跨域
无数被跨域请求爆出翔来的人 遇到请求成功却不能进入success 总是提示parsererror 参考一下两篇文章吧 参考文章http://www.asp.net/web-api/overview/s ...
- mvc中使用jsonp进行跨域请求详细说明
在web开发中,如果你要在不同域下进行数据异步请求,会出现一个No ‘Access-Control-Allow-Origin’ header is present on the requested r ...
- ASP.Net WebAPI与Ajax进行跨域数据交互时Cookies数据的传递
前言 最近公司项目进行架构调整,由原来的三层架构改进升级到微服务架构(准确的说是服务化,还没完全做到微的程度,颗粒度没那么细),遵循RESTFull规范,使前后端完全分离,实现大前端思想.由于是初次尝 ...
- WebApi使用cors配置跨域问题
1.首先安装CORS,在WebApiCors项目上面使用Nuget搜索“microsoft.aspnet.webapi.cors”,安装第一个 2.当我们安装这个包之后,现有的packages目录下会 ...
- WebApi开启CORS支持跨域POST
概念:CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing).它允许浏览器向跨源服务器,发出XMLHttpRequest请求 ...
- WebAPI IE8、IE9 跨域问题
关于WebAPI跨域的问题,网上已经很多了,以下方案可以解决很多跨域问题,但是都不支持IE8.IE9浏览器,JSONP也只能支持Get请求 通过dll配置 Install-Package Micros ...
随机推荐
- Topcoder srm 632 div2
脑洞太大,简单东西就是想复杂,活该一直DIV2; A:水,基本判断A[I]<=A[I-1],ANS++; B:不知道别人怎么做的,我的是100*N*N;没办法想的太多了,忘记是连续的数列 我们枚 ...
- 百度之星A
Scenic Popularity Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...
- LCIS(m*n) 最长公共上升子序列
详见:http://wenku.baidu.com/view/3e78f223aaea998fcc220ea0n3的: for(int i=1;i<=n;i++) for ...
- 彻底理解js中this的指向
首先必须要说的是,this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象(这句话有些问题,后面会解释为什么会有问题,虽然 ...
- Sql注入一种dump所有数据的方法
Select exp(~(select*from(select(concat(@:=0,(select count(*)from`information_schema`.columns where t ...
- Sql调用WebService
DECLARE @scid int,@rt int ) --创建MSSOAP.SoapClient组件(如果安装的是SoapToolkit30,应该是MSSOAP.SoapClient30,否则是MS ...
- Git 10 周年之际,创始人 Linus Torvalds 访谈
点这里 十年前的这一周,linux 内核社区面临一个根本性的挑战:他们不再能够使用他们的修复控制系统:BitKeeper,同时其他的软件配置管理遇到了对分布式系统的新需求.Linus Torvalds ...
- Activity学习(二)——生命周期
一.什么是Activity? 简单的说:Activity就是布满整个窗口或者悬浮于其他窗口上的交互界面.在一个应用程序中通常由多个Activity构成,都会在Manifest.xml中指定一个主的Ac ...
- 如何在Windows7(IIS7)环境下安装 PHP
一.安装IIS7 打开(1)[程序和功能],然后点击(2)[打开或关闭Windows功能] 勾选(1)[IIS管理控制台]和(2)CGI,然后点击[确定]按钮,等待安装完成.这个过程可能需要系统安装光 ...
- 从.NET 1.1 升级到.NET 4.0 遇到 线程间操作无效: 从不是创建控件 [XX] 的线程访问它.
有两种方式解决 1.在窗体构造函数中写Control.CheckForIllegalCrossThreadCalls =false;2.使用Invoke等委托函数 问题原因是 .NET2.0 以后拒绝 ...