65.9K
CodeProject 正在变化。 阅读更多。
Home

SilverlightDesktop.net 介绍

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.11/5 (4投票s)

2008年10月19日

BSD

5分钟阅读

viewsIcon

39712

downloadIcon

283

SilverlightDesktop.net 是一个开源的 ASP.NET 框架,允许您将 Silverlight 模块动态加载到可调整大小、可拖动的窗口中。

引言

注意:您应始终从 http://SilverlightDesktop.net 下载最新版本的 SilverlightDesktop.net。

SilverlightDesktop.net 是一个开源的 ASP.NET 框架,允许您将 Silverlight 模块动态加载到可调整大小、可拖动的窗口中。它还可以加载没有窗口的模块,以便轻松集成到现有网站中。SilverlightDesktop.net 可作为独立程序和 DotNetNuke™ 版本使用。

本文将探讨以下主题

  • 什么是 SilverlightDesktop 以及为什么我需要使用它?
    • 安装
    • 特点
    • 安全
  • 自定义模块
    • 安装模块
    • 自定义模块开发
  • 核心
    • SilverlightDesktop 项目
      • 可移动的可拖动窗口
    • SilverlightCore 项目
      • 电子邮件
      • 日志记录
  • SilverlightDesktop.net for DotNetNuke™

什么是 SilverlightDesktop 以及为什么我需要使用它?

Microsoft Silverlight 在客户端运行;也就是说,它不在 Web 服务器上运行,而是在用户的 Web 浏览器中运行。您必须有一种方法来在启动 Silverlight 应用程序的 Web 服务器与用户 Web 浏览器中运行的 Silverlight 应用程序之间进行通信。这种通信通常通过 Web 服务执行。

创建 Silverlight 应用程序时,您可能会发现需要安全、用户管理、电子邮件和日志记录。实现这些支持性元素可能比创建 Silverlight 应用程序本身需要更多时间。

SilverlightDesktop.net 提供了一个框架,允许您创建只包含所需自定义功能的模块。SilverlightDesktop.net 负责安全、用户和角色管理,同时还提供电子邮件和日志记录支持。

安装 SilverlightDesktop.net

要安装或升级 SilverlightDesktop.net

  • 创建数据库
  • 将 SilverlightDesktop 安装文件解压缩到硬盘上的一个目录中
  • 配置 IIS Web 服务器以指向该目录(或在 Visual Studio 2008 中打开该目录并运行应用程序以使用其内置 Web 服务器)
  • 在 Web 浏览器中打开该站点并按照向导完成安装

可以在以下链接中找到进一步的安装说明

SilverlightDesktop.net 功能

当您使用安装期间创建的用户名和密码登录 SilverlightDesktop.net 管理界面时,您将可以访问其功能

  • 一个密码保护的管理部分,允许您配置诸如允许的密码尝试次数和电子邮件设置等选项。
  • 一个用户管理器,允许您创建和编辑用户,并设置他们的角色和活动状态。
  • 模块设置,允许您配置您创建或上传的模块。您可以在 SilverlightDesktop.net 网站上找到要上传的模块
  • 多个您可以创建和配置的桌面实例。AutoLoad 模块功能允许显示单个模块而无需可移动的可调整大小的窗口。
  • 应用程序日志为管理员提供应用程序事件的概述

SilverlightDesktop.net 安全性

安全性实现如下

SilverlightDesktop.net 启动 Silverlight 控件。它使用代码传递 InitParameters,其中包含临时密码(它还存储 IP 地址)。

string strIPAddress = this.Context.Request.UserHostAddress;
int intPassword = Authendication.SetSilverlightKey(_UserID, strIPAddress);
string strWebServiceBase = GetWebServiceBase();

SilverlightDesktop.InitParameters =
    String.Format("PortalID={0},ModuleId={1},UserID={2}," + 
      "Password={3},WebServiceBase={4},AutoLoadModule={5}",
      "-1", _DesktopID.ToString(), _UserID.ToString(), 
      intPassword.ToString(), strWebServiceBase, AutoLoadModule);

在 SilverlightDesktop 项目(创建包含其他 Silverlight 模块加载的窗口的 Silverlight 应用程序)的 App.xaml.cs 文件中,代码检索参数...

private void Application_Startup(object sender, StartupEventArgs e)
{
    // Load the main control
    this.RootVisual = new Page(e.InitParams["PortalID"], 
        e.InitParams["ModuleId"], 
        e.InitParams["UserID"], 
        e.InitParams["Password"], 
        e.InitParams["WebServiceBase"], 
        e.InitParams["AutoLoadModule"]);
}

...并将它们传递给 Silverlight 自定义模块(当自定义模块被动态加载时)。它通过自定义模块的 .Tag 属性传递参数。

private void loadAssembly(Stream s)
{
    // from http://silverlight.net/forums/p/14941/49437.aspx (BlueAquarius)
    // From http://joel.neubeck.net/2008/03/
    //          silverlight-how-to-on-demand-assembly-deployment/

    try
    {
        Uri uri = new Uri(strXAPName.Replace(".xap", ".dll"), UriKind.Relative);
        StreamResourceInfo xapPackageSri = new StreamResourceInfo(s, null);
        StreamResourceInfo assemblySri = Application.GetResourceStream(xapPackageSri, uri);

        AssemblyPart assemblyPart = new AssemblyPart();
        Assembly a = assemblyPart.Load(assemblySri.Stream);

        UserControl objUserControl = (UserControl)a.CreateInstance(strAssemblyClassName);
        if (objUserControl == null)
        {
            debug("objUserControl is null " + strAssemblyClassName);
            return;
        }

      // Pass the parameters to the control that it will need to connect to the website
        objUserControl.Tag = string.Format("{0}, {1}, {2}, {3}, {4}", 
          intPortalID, intModuleId, intUserID, strPassword, strWebServiceBase);

        if (UseWindows)
        {
            SilverlightWindowControl objSilverlightWindowControl = 
              new SilverlightWindowControl(objSilverlightDesktopModule.WindowSize);
            objSilverlightWindowControl.Window.Content = objUserControl;
            objSilverlightWindowControl.WindowName.Text = 
                             objSilverlightDesktopModule.ModuleName;
            Canvas.SetLeft(objSilverlightWindowControl, (double)intWindowLocation);
            Canvas.SetTop(objSilverlightWindowControl, (double)intWindowLocation);

            this.LayoutRoot.Children.Add(objSilverlightWindowControl);
        }
        else
        {
            this.LayoutRoot.Children.Add(objUserControl);
        }
    }
    catch (Exception ex)
    {
        debug("Exception when loading the assembly part:");
        debug(ex.ToString());
    }
}

当自定义模块调用 Web 服务时,会传递临时密码给 Web 服务。

#region ShowWhoAmI
private void ShowWhoAmI()
{
    BasicHttpBinding bind = new BasicHttpBinding();
    EndpointAddress MyEndpointAddress = 
      new EndpointAddress(strWebServiceBase + "WhoAmI.asmx");
    var proxy = new WhoAmISoapClient(bind, MyEndpointAddress);

    proxy.WhoIAmCompleted += 
      new EventHandler<whoiamcompletedeventargs>(proxy_WhoIAmCompleted);
    proxy.WhoIAmAsync(intPortalID, intModuleId, intUserID, strPassword);
}

void proxy_WhoIAmCompleted(object sender, WhoIAmCompletedEventArgs e)
{
    UserInfo UserInfo = (UserInfo)e.Result;
    DisplayWhoIAm(UserInfo);
}

private void DisplayWhoIAm(UserInfo UserInfo)
{
    this.txtFirstName.Text = UserInfo.FirstName;
    this.txtLastName.Text = UserInfo.LastName;
    this.txtEmail.Text = UserInfo.Email;
}
#endregion

Web 服务将此临时密码以及调用它的 Silverlight 应用程序的 IP 地址(请记住,Silverlight 应用程序在用户的 Web 浏览器中运行)传递给 **SilverlightDesktopCore** 项目中的 Authentication 类。

#region WhoIAm
[WebMethod(Description = "WhoIAm")]
[ScriptMethod()]
public UserInfo WhoIAm(int PortalID, int ModuleId, int UserID, string Password)
{
    string strIPAddress = this.Context.Request.UserHostAddress;
    SilverlightDesktopAuthendicationHeader 
      SilverlightDesktopAuthendicationHeader = 
        new SilverlightDesktopAuthendicationHeader();
    SilverlightDesktopAuthendicationHeader.PortalID = PortalID;
    SilverlightDesktopAuthendicationHeader.UserID = UserID;
    SilverlightDesktopAuthendicationHeader.Password = Password;
    SilverlightDesktopAuthendicationHeader.ModuleId = ModuleId;
    SilverlightDesktopAuthendicationHeader.IPAddress = strIPAddress;

    UserInfo response = new UserInfo();

    Authendication Authendication = 
       new Authendication(SilverlightDesktopAuthendicationHeader);
    if (Authendication.IsUserValid("WhoAmI"))
    {
        response = Authendication.GetUserInfo();
    }
    else
    {
        response.FirstName = "Visitor";
        response.LastName = DateTime.Now.ToLongDateString();
    }

    return response;
}
#endregion

Authentication 类比较用户名和密码以确定用户是否应被身份验证(注意:Strings.Left(result.IPAddress,6) 用于仅匹配 IP 地址的前一部分,以防用户位于代理服务器后面,代理服务器会不断更改 IP 地址)。

//  Get the SilverlightKey
var SilverlightKey = 
  (from ASilverlightDesktopUser in SilverlightDesktopDAL.SilverlightDesktopUsers
   where ASilverlightDesktopUser.UserID == _UserID
   select ASilverlightDesktopUser).FirstOrDefault();

if (SilverlightKey.SilverlightKey == ConvertToSilverlightkey(_Password) & 
    Strings.Left(SilverlightKey.IPAddress, 6) == Strings.Left(_IPAddress, 6))
{
    return true;
}
else
{
    if (Strings.Left(SilverlightUser.IPAddress,6) == Strings.Left(_IPAddress,6))
    {
        // The correct IP address was used
        // To prevent a brute force attack scramble the password
        // A hacker is now chasing a moving target
        SetSilverlightKey();
    }
    return
}

每次用户登录 SilverlightDesktop.net 站点时,都会获得一个新的临时密码。

自定义模块

可以通过上传 .zip 文件来安装模块。软件包清单在此处描述:创建模块包

自定义模块开发

自定义模块是通过创建生成 .xap 文件的 Silverlight 项目来创建的。

.xap 文件存储在 SilverlightDesktop 网站的 ClientBin 目录中。也可以创建 Web 服务和数据访问层等其他模块元素。

使用管理界面中的模块设置来配置模块。有关创建模块的更多信息可以在 此链接 找到。

核心

SilverlightDesktop.net 源代码包含五个项目

  • SilverlightDesktop_Web - 此项目包含用户与之交互的网站。该网站包含在 SilverlightDesktop.net 的“安装版本”中。
  • SilverlightDesktop - 此项目包含动态加载 Silverlight 自定义模块并可选地将其放置在可移动的可调整大小的窗口中的 Silverlight 项目。
  • SilverlightDesktopCore - 此项目包含身份验证、电子邮件和日志记录功能。自定义模块中的服务器端代码也可以引用此项目。
  • WhoAmI - 一个示例 Silverlight 自定义模块,用于显示当前登录用户的身份。
  • wsWhoAmI - WhoAmI 示例自定义模块的示例 Web 服务项目。

SilverlightDesktop 项目

SilverlightDesktop 项目被编译成 SilverlightDesktop.xap,并驻留在 SilverlightDesktop 网站的 ClientBin 目录中。当访问者查看他们的 SilverlightDesktop 或 **AutoLoad** 模块时,它会被加载。在 SilverlightDesktop 窗口模式下显示模块时,该项目会加载模块定义中指定的类,在 SilverlightWindowControl 中。

SilverlightWindowControl 由一组 Canvas 控件、Rectangle 控件和 Window 控件组成,这些控件被排列成一个可调整大小的窗口控件。事件处理程序已连接到各种元素,以支持拖动和调整大小的功能。

以下是用于操作左侧的代码

#region LeftSide
private void LeftSide_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    //Start Drag
    FrameworkElement LeftSide = (FrameworkElement)sender;
    LeftSide.CaptureMouse();

    // Set the starting point for the drag
    StartingDragPoint = e.GetPosition(LeftSide);
    Point ControlPoint = e.GetPosition(this);
    StartingDragPoint.X = StartingDragPoint.Y - ControlPoint.Y - .5;

    LeftSide.MouseMove += new MouseEventHandler(LeftSide_MouseMove);
    LeftSide.MouseLeftButtonUp += 
      new MouseButtonEventHandler(LeftSide_MouseLeftButtonUp);
}

void LeftSide_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
    //Stop Drag
    FrameworkElement LeftSide = (FrameworkElement)sender;
    LeftSide.ReleaseMouseCapture();

    LeftSide.MouseMove -= new MouseEventHandler(LeftSide_MouseMove);
    LeftSide.MouseLeftButtonUp -= 
      new MouseButtonEventHandler(LeftSide_MouseLeftButtonUp);
}

void LeftSide_MouseMove(object sender, MouseEventArgs e)
{
    Point LeftSidePoint = e.GetPosition(LeftSide);
    double PointDifference = LeftSidePoint.X - StartingDragPoint.X;

    if (PointDifference < 0)
    {
        PointDifference = PointDifference * -1;

        if (LeftSidePoint.X < (Window.Width + (PointDifference) - 60))
        {
            this.SetValue(WidthProperty, (double)(PointDifference));
            Window.SetValue(WidthProperty, (double)Window.Width + (PointDifference));
            DragStackPanel.SetValue(WidthProperty, 
               (double)DragStackPanel.Width + (PointDifference));
            DragBar.SetValue(WidthProperty, (double)DragBar.Width + (PointDifference));
            TopSide.SetValue(WidthProperty, (double)TopSide.Width + (PointDifference));
            BottomSide.SetValue(WidthProperty, 
               (double)BottomSide.Width + (PointDifference));

            Canvas Canvas = (Canvas)this.Parent;
            Point Point = e.GetPosition(Canvas);
            Canvas.SetLeft(this, Point.X - StartingDragPoint.X);
            Canvas.SetLeft(RightSide, (double)TopSide.Width + StartingDragPoint.X);
        }
    }
    else
    {
        if (LeftSidePoint.X < (Window.Width - (PointDifference) - 60))
        {
            this.SetValue(WidthProperty, (double)(PointDifference));
            Window.SetValue(WidthProperty, (double)Window.Width - (PointDifference));
            DragStackPanel.SetValue(WidthProperty, 
               (double)DragStackPanel.Width - (PointDifference));
            DragBar.SetValue(WidthProperty, (double)DragBar.Width - (PointDifference));
            TopSide.SetValue(WidthProperty, (double)TopSide.Width - (PointDifference));
            BottomSide.SetValue(WidthProperty, 
                      (double)BottomSide.Width - (PointDifference));

            Canvas Canvas = (Canvas)this.Parent;
            Point Point = e.GetPosition(Canvas);
            Canvas.SetLeft(this, Point.X - StartingDragPoint.X);
            Canvas.SetLeft(RightSide, (double)TopSide.Width + StartingDragPoint.X);
        }
    }
}
#endregion

SilverlightDesktopCore 项目

SilverlightDesktopCore 项目由主 SilverlightDesktop 网站使用,但自定义模块也可以引用它。

SilverlightDesktopCore 项目中可用的一些类和方法如上所示。

它为自定义模块提供的核心功能包括身份验证、日志记录

// Log the event
ApplicationLog.AddToLog(String.Format("Module: {0} - File deleted {1}.", 
   objModules.FirstOrDefault().ModuleName, strFileToDelete));

以及电子邮件

#region Send Test Email
protected void lnkTestEmail_Click(object sender, EventArgs e)
{
    string[] arrAttachments = new string[0];
    string strEmailResponse = Email.SendMail(txtSMTPFrom.Text.Trim(), 
      txtSMTPFrom.Text.Trim(), "", "", 
      txtSMTPFrom.Text.Trim(), MailPriority.Normal, 
      "SilverlightDesktop Email", Encoding.UTF8, 
      "A test email sent from SilverlightDesktop",
      arrAttachments, txtSMTPEmailServer.Text.Trim(), 
      rbAuthendication.SelectedValue, txtSMTPUsername.Text.Trim(), 
      txtSMTPPassword.Text.Trim(), chkSecureAccess.Checked);

    lblUpdated.Text = (strEmailResponse.Trim() == "") ? 
                       "Email Sent." : strEmailResponse;
}
#endregion

SilverlightDesktop.net for DotNetNuke™

SilverlightDesktop.net 也提供了一个在 DotNetNuke™ 中运行的版本。更多信息可以在此处找到

注意:两个版本都需要 ASP.NET 3.5 或更高版本以及 SQL Server(或 Express)2005 或更高版本。

© . All rights reserved.