传统Webform 跨域调用 MVC 4 Web API实现分布式 无法解析 解决方案

前言:



正好在大概7月1日学习一份kendo ui的资料时发现一共5个章节,前3个章节都是用来讲Web API了,既然都已经看了索性就尝试一下,也不做深层次了解了,于是查阅了一些资料尝试写一个基于MVC 4 的WebAPI Demo。

正文:



下文简略介绍服务端的部分实现:

创建一个MVC4 基本项目,也就是不需要自己创建一些基本的注册绑定了。

直接新建一个Controller以及一个Model,如下所示:

UserModel.cs

1     public class UserModel
2     {
3         public string UserID { get; set; }
4         public string UserName { get; set; }
5         public string UserPwd { get; set; }
6     }

UserController

1 public class UserController : ApiController
2     {
3         public UserModel getUser()
4         {
5             return new UserModel { UserID="1000",UserName="Admin",UserPwd="Admin888"};
6         }
7     }

查看一些App_Start 下WebAPI的路由设置如下:

1         public static void Register(HttpConfiguration config)
2         {
3             config.Routes.MapHttpRoute(
4                 name: "DefaultApi",
5                 routeTemplate: "api/{controller}/{id}",
6                 defaults: new { id = RouteParameter.Optional }
7             );
8         }

此时,直接访问api/User/getUser

即可得到以下结果:

可以看到结果是一个xml文档。
直接在本页面创建一个index.html页面,使用ajax以json数据形式调用这个api,实现如下:

        $(function () {
            $.ajax({
                type: ‘GET‘,
                url: ‘api/user/getadmin‘,
                dataType: ‘json‘,
                success: function (data, textStatus) {
                    alert("用户ID:"+data.UserID + " , 用户名:" + data.UserName+" , 用户密码:"+data.UserPwd);
                },
                error: function (xmlHttpRequest, textStatus, errorThrown) {
                }
            });
        })

实现效果如下:

这属于在一个项目中调用数据,也就并提不上什么分布式了,另外新建一个webform项目,同样创建一个index.html页面,以同样的方式调用这一api,区别在于需要写上域名和主机头以及协议:

        $(function () {
            $("#btnGet").click(function () {
                $.ajax({
                    type: ‘GET‘,
                    url: ‘http://localhost:16564/api/user/getUser‘,
                    dataType: ‘json‘,
                    success: function (data, textStatus) {
                        alert("用户ID:" + data.UserID + " , 用户名:" + data.UserName + " , 用户密码:" + data.UserPwd);
                    },
                    error: function (xmlHttpRequest, textStatus, errorThrown) {
                    }
                });
            });
        })

可以看到单击后并无任何效果。

打开chrome开发人员工具,查看网络请求可以看到,请求的api/user/getUser   状态是cancel,这应该是JS不允许跨域调用的结果,如下图所示:

通过分析以下错误信息:No ‘Access-Control-Allow-Origin‘ header is present on the requested resource.  查看后发现确实如此,OK,解决方案随之产生,直接将dataType 从json 改为JSONP即可。

            $("#btnGet").click(function () {
                $.ajax({
                    type: ‘GET‘,
                    url: ‘http://localhost:16564/api/user/getUser‘,
                    dataType: ‘JSONP‘,
                    success: function (data, textStatus) {
                        alert("用户ID:" + data.UserID + " , 用户名:" + data.UserName + " , 用户密码:" + data.UserPwd);
                    },
                    error: function (xmlHttpRequest, textStatus, errorThrown) {
                    }
                });
            }); 

此时刷新后再次访问仍然无响应,再次查看,结果如下:

得到的返回结果是:{"UserID":"1000","UserName":"Echo","UserPwd":"EchoIsnotLoser"}
如果想用JSONP来获得跨域的数据,需求的格式是
jQuery123456([{‘UserID‘:‘1000‘}])
而WebAPI本身是不支持JS的callback的,它返回的JSON是这样的:
{"UserID":"1000","UserName":"Echo","UserPwd":"EchoIsnotLoser"}

故而无法解析。

找到原因后只需要在WebAPI这个服务端写一个拓展类,并在全局注册即可:
1.创建一个JsonCallbackAttribute    判断接口的访问是属于跨域,还是非跨域,正常的返回。

    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 = System.Web.HttpContext.Current.Request.QueryString[CallbackQueryParameter];

            return !string.IsNullOrEmpty(callback);
        }
    }

2.在全局注册这个扩张类

        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);

            GlobalConfiguration.Configuration.Filters.Add(new JsonCallbackAttribute());
        } 

此时 重新编译整个项目,再次运行即可查看到需要的效果,如下图所示:

至此在传统Webform中调用WebAPI的基本操作就实现了。

时间: 2024-10-29 02:00:32

传统Webform 跨域调用 MVC 4 Web API实现分布式 无法解析 解决方案的相关文章

如何通过js跨域调用ASP.NET Web API (请问如何实现在javascript中通过http get的方式跨域调用ASP.NET Web API?)

客户端js无需任何专门设置,使用通常的ajax调用即可: $.ajax({ url: '跨域URL', type: 'get', dataType: 'json', success: function (data) { $('#banner_right').html(data); } }); 服务端需要在WebApiConfig.Register()中添加如下的代码 public static class WebApiConfig { public static void Register(Ht

支持Ajax跨域访问ASP.NET Web Api 2(Cors)的简单示例教程演示

随着深入使用ASP.NET Web Api,我们可能会在项目中考虑将前端的业务分得更细.比如前端项目使用Angularjs的框架来做UI,而数据则由另一个Web Api 的网站项目来支撑.注意,这里是两个Web网站项目了,前端项目主要负责界面的呈现和一些前端的相应业务逻辑处理,而Web Api则负责提供数据. 这样问题就来了,如果前端通过ajax访问Web Api项目话,就涉及到跨域了.我们知道,如果直接访问,正常情况下Web Api是不允许这样做的,这涉及到安全问题.所以,今天我们这篇文章的主

改变mvc web api 支持android ,ios ,ajax等方式跨域调用

公司一个移动后端的项目用到了 webapi 项目搭建到外网环境共app开发者调用测试接口时遇到了一个问题 接口不允许跨域调用 .查阅资料明白 同源策略原则根据请求报头值 Origin 与回应报头值 Access-Control-Allow-Origin 来判断是否允许调用 解决方法 1.ajax使用jsonp jsonp 是通过请求参数中加入回调函数参数值.webapi 收到回调函数参数值返回数据不再是单纯的json,而是根据回调函数参数值 的js方法调用,这样就避免的同源策略 需要webapi

关于AJAX跨域调用ASP.NET MVC或者WebAPI服务的问题及解决方案

原文:http://www.cnblogs.com/chenxizhang/p/3821703.html 问题描述 当跨域(cross domain)调用ASP.NET MVC或者ASP.NET Web API编写的服务时,会发生无法访问的情况. 重现方式 1.使用模板创建一个最简单的ASP.NET Web API项目,调试起来确认能正常工作 public class TestController : ApiController { // GET api/test public IEnumera

跨域调用webapi web端跨域调用webapi

https://www.baidu.com/s?ie=UTF-8&wd=webapi%20%E8%B7%A8%E5%9F%9F web端跨域调用webapi 在做Web开发中,常常会遇到跨域的问题,到目前为止,已经有非常多的跨域解决方案. 通过自己的研究以及在网上看了一些大神的博客,写了一个Demo 首先新建一个webapi的程序,如下图所示: 由于微软已经给我们搭建好了webapi的环境,所以我们不必去添加引用一些dll,直接开始写代码吧. 因为这只是做一个简单的Demo,并没有连接数据库.

跨域调用(mvc、webapi)

JavaScript出于安全方面的考虑,不允许跨域调用其他页面的对象.通常来说,跨域分为以下几类: 先创建两个项目,一个mvc,一个webapi,演示由mvc调用webapi mvc前端: 会出现问题 然后新建一个类在webapi根目录下,这个类创建特性[CrossSite],放在需要跨域的方法前,方法就可跨域 using System.Web; using System.Web.Http.Filters; using System.Web.Mvc; namespace APIApplicati

AJAX跨域调用ASP.NET MVC或者WebAPI服务的解决方案

问题描述 当跨域(cross domain)调用ASP.NET MVC或者ASP.NET Web API编写的服务时,会发生无法访问的情况. 重现方式 使用模板创建一个最简单的ASP.NET Web API项目,调试起来确认能正常工作 public class UserController : ApiController { public UserModel getInfo() { UserModel um = new UserModel(); um.Uid = 5; um.UserName =

web api 跨域请求,ajax跨域调用webapi

1.跨域问题仅仅发生在Javascript发起AJAX调用,或者Silverlight发起服务调用时,其根本原因是因为浏览器对于这两种请求,所给予的权限是较低的,通常只允许调用本域中的资源,除非目标服务器明确地告知它允许跨域调用.假设我们页面或者应用已在 http://www.test1.com 上了,而我们打算从 http://www.test2.com 请求提取数据.一般情况下,如果我们直接使用 AJAX 来请求将会失败,浏览器也会返回“源不匹配”的错误,"跨域"也就以此由来. 2

web端跨域调用webapi

在做Web开发中,常常会遇到跨域的问题,到目前为止,已经有非常多的跨域解决方案. 通过自己的研究以及在网上看了一些大神的博客,写了一个Demo 首先新建一个webapi的程序,如下图所示: 由于微软已经给我们搭建好了webapi的环境,所以我们不必去添加引用一些dll,直接开始写代码吧. 因为这只是做一个简单的Demo,并没有连接数据库. 第一步我们要在Models文件夹里添加一个实体类Employees,用来存放数据. Employees.cs里的内容如下: 1 using System; 2