传统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的基本操作就实现了。

转载于:https://www.cnblogs.com/ecoder/p/4619881.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值