Lightswitch Desktopclinet 中如何调用WEB API



Lightswitch Desktopclinet 本质就是一个silverlight 桌面客户端程序,当然也有对应的asp.net后台服务,数据的真正处理都在后台端。那也可以尝试以WEB API 进行自定义的调用。(注:LS是很方便,但太不注意性能,获取的数据都是整个表及关联性数据)。

服务器端处理:

1 GLOBAL文件,添加WEBAPI路由注册信息

  public class Global : System.Web.HttpApplication
    {

        protected void Application_Start(object sender, EventArgs e)
        {
            // needs references: System.Web.Http, System.web.Http.WebHost en System.Net.Http
            RouteTable.Routes.MapHttpRoute(
               name: "DefaultApi",
               routeTemplate: "api/{controller}/{action}/{id}",
               defaults: new { action = "get", id = RouteParameter.Optional }
           );
        }
    }


2. 添加 一个调用LS环境的基类(如果要使用现成的LS的数据访问功能,如自己用ADO.NET则无需)

或  PM> Install-package the lightswitchtoolbox.webapicommanding.server 

手工代码:

LightSwitchApiControllerbase.cs

  public abstract class LightSwitchApiControllerbase : ApiController
    {
        private ServerApplicationContext _context;

        public ServerApplicationContext Context
        {
            get
            {
                return _context;
            }
        }

        public ServerApplicationContext GetContext()
        {

            return _context;
        }

        public LightSwitchApiControllerbase()
        {
            _context = ServerApplicationContext.Current;
            if (_context == null)
            {
                _context = ServerApplicationContext.CreateContext();
            }
        }

    }


3.实现WEB API

    public class CommandController : LightSwitchApiControllerbase
    {
        [HttpGet]
        public IEnumerable<string> TestGetCommand()
        {
            List<string> list = new List<string>();
            try
            {
                using (var ctx = this.Context)
                {

                    if (ctx.Application.User.HasPermission(Permissions.CanSendCommand))
                    {
                        list.Add("can CanSendCommand ");
                    }

                    if (ctx.Application.User.HasPermission(Permissions.CanSendCommand))
                    {

                        list.Add("value 1");
                        list.Add("value 2");
                        string lastNameFirstCustomer = ctx.DataWorkspace.ApplicationData.Customers.First().LastName;
                        list.Add(lastNameFirstCustomer);
                        return list;
                    }
                }
            }
            catch (Exception ex)
            {

                list.Add(ex.Message);
            }
             return list;
        }
      
        [HttpPost]
        public HttpResponseMessage TestCommand(SimpleCommandRequestParameters parameters)
        {
            Thread.Sleep(3000);
           string s="";
            try
            {

                using (var ctx = this.Context)
                {
                    if (ctx.Application.User.HasPermission(Permissions.CanSendCommand))
                    {
                        string lastNameFirstCustomer = ctx.DataWorkspace.ApplicationData.Customers.First().LastName;

                      

                            s = "ok for " + parameters.ReqParam + " for " + lastNameFirstCustomer;
                    }

                    else
                    {
                       
                            s = "NOT OK for " + parameters.ReqParam;
                    }
                }
            }
            catch(Exception ex)
            {
                s = ex.Message;
            }

            return Request.CreateResponse<SimpleCommandResponseParameters>(HttpStatusCode.Accepted,
                      new SimpleCommandResponseParameters
                      {

                          RespParam = s
                      });
        
           
        }

    }

4. 添加请求响应参数帮助类,上面引用到的,注:同时在客户端也添加此文件连接以共享代码

  public class SimpleCommandResponseParameters
    {
        public string RespParam { get; set; }
    }
  public class SimpleCommandRequestParameters
    {
        public string ReqParam { get; set; }
    }


客户端处理:

1. 添加上述二个请求响应帮助类,以连接方式共享服务器代码

2.添加一个API代理调用类

using Microsoft.LightSwitch.Client;
using Microsoft.LightSwitch.Threading;
using Newtonsoft.Json;
using System;
using System.IO;
using System.Net;
using System.Reflection;
using System.Runtime.InteropServices.Automation;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace LightSwitchApplication
{
    public static class LightSwitchCommandProxy
    {
        private static object GetPrivateProperty(Object obj, string name)
        {
            BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public;
            Type type = obj.GetType();
            PropertyInfo field = type.GetProperty(name, flags);
            return field.GetValue(obj, null);
        }

        private static object GetPrivateField(Object obj, string name)
        {
            BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public;
            Type type = obj.GetType();
            FieldInfo field = type.GetField(name, flags);
            return  field.GetValue(obj);
        }

        public static void StartWebApiCommand<T>(this IScreenObject screen, string commandrelativePath,
            object data, Action<Exception, T> callback)
        {
           

            Uri baseAddress = null;
            baseAddress = GetBaseAddress();

            HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(new Uri(baseAddress, commandrelativePath));
            webRequest.Method = "POST";
            webRequest.ContentType = "application/json";
            if (System.Windows.Application.Current.IsRunningOutOfBrowser) //OOB模式,设置COOKIE
            {

                Object userState = null;
                var auths = Application.Current.AuthenticationService.LoadUser((loadOp) => { }, userState);
                var op = GetPrivateField(auths, "operation");
                var svc = GetPrivateProperty(op, "Service");
                System.Net.CookieContainer cc = (System.Net.CookieContainer)GetPrivateProperty(svc, "CookieContainer");
                webRequest.CookieContainer = cc;
                // CookieContainer的获取可以放在Application_LoggedIn 事件里获取,不用每次都取一下
                //public partial class Application
                //{
                //    partial void Application_LoggedIn()
                //    {
           
                //    }
                //}
            }
            webRequest.BeginGetRequestStream(iar =>
            {
                var requestStream = webRequest.EndGetRequestStream(iar);

                SerializeObject(data, requestStream);

                webRequest.BeginGetResponse(iar2 =>
                {
                    WebResponse webResponse;
                    try
                    {
                        webResponse = webRequest.EndGetResponse(iar2);
                    }
                    catch (Exception ex)
                    {
                        screen.Details.Dispatcher.BeginInvoke(() =>
                        {
                            callback(ex, default(T));
                        });
                        return;
                    }
                    var result = Deserialize<T>(new StreamReader(webResponse.GetResponseStream()));

                    screen.Details.Dispatcher.BeginInvoke(() =>
                    {
                        callback(null, result);
                    });
                }, null);
            }, null);
        }
        //for a get,不带COOKIE,有可能会被拒绝
        public static void StartWebApiRequest<T>(this IScreenObject screen, string requestRelativePath,
    Action<Exception, T> callback)
        {
            Uri serviceUri = new Uri(GetBaseAddress(), requestRelativePath);

            WebRequest.RegisterPrefix("http://",
                      System.Net.Browser.WebRequestCreator.BrowserHttp);
            WebRequest.RegisterPrefix("https://",
                       System.Net.Browser.WebRequestCreator.BrowserHttp);
            //out of browser does not work here !
            WebRequest webRequest = WebRequest.Create(serviceUri);
            webRequest.UseDefaultCredentials = true;
            webRequest.Method = "GET";
            webRequest.BeginGetResponse(iar2 =>
                 {
                     WebResponse webResponse;
                     try
                     {
                         webResponse = webRequest.EndGetResponse(iar2);
                     }
                     catch (Exception ex)
                     {
                         screen.Details.Dispatcher.BeginInvoke(() =>
                         {
                             callback(ex, default(T));
                         });
                         return;
                     }
                     var result = Deserialize<T>(new StreamReader(webResponse.GetResponseStream()));

                     screen.Details.Dispatcher.BeginInvoke(() =>
                     {
                         callback(null, result);
                     });
                 }, null);

        }

        public static Uri GetBaseAddress()
        {
            Uri baseAddress = null;
            Dispatchers.Main.Invoke(() =>
            {
                baseAddress = new Uri(new Uri(System.Windows.Application.Current.Host.Source.AbsoluteUri), "../../");

            });
            return baseAddress;
        }
        private static void SerializeObject(object data, Stream stream)
        {
            var serializer = new JsonSerializer();
            var sw = new StreamWriter(stream);
            serializer.Serialize(sw, data);
            sw.Flush();
            sw.Close();
        }

        private static T Deserialize<T>(TextReader reader)
        {
            var serializer = new JsonSerializer();
            return serializer.Deserialize<T>(new JsonTextReader(reader));
        }
    }
}

注:添加一下Newtonsoft.Json引用

3.客户端调用,新增一个屏幕,加上按钮事件,如下:

   partial void TestPostCommand_Execute()
        {
            string commandrelativePath = "api/Command/TestCommand";
            
            this.StartWebApiCommand<SimpleCommandResponseParameters>(commandrelativePath,
                new SimpleCommandRequestParameters { ReqParam = "hello" },
                (error, response) =>
                {
                    IsBusy = false;
                    if (error != null)
                    {
                        this.ShowMessageBox("error = " + error.ToString());
                    }
                    else
                    {
                        this.ShowMessageBox("result = " + response.RespParam);
                    }
                });
        }
        partial void TestGetCommand_Execute()
        {
            string commandrelativePath = "api/Command/TestGetCommand";

            this.StartWebApiRequest<List<string>>(commandrelativePath,
                (error, response) =>
                {
                    if (error != null)
                    {
                        this.ShowMessageBox("error = " + error.ToString());
                    }
                    else
                    {
                        var result = string.Empty;
                        response.ForEach(s => result += (s + " "));

                        this.ShowMessageBox(result);
                    }
                });
        }


 
 


你可能感兴趣的:(Web,api,LightSwitch)