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つの要求応答ヘルプクラスを追加し、接続方式でサーバコードを共有する
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(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>(commandrelativePath,                (error, response) =>                {                    if (error != null)                    {                        this.ShowMessageBox("error = "+ error.ToString());                    }                    else                    {                        var result = string.Empty;                        response.ForEach(s => result += (s + ""));
                        this.ShowMessageBox(result);                    }                });        }