使用 IFrames 将 Visual Studio LightSwitch 应用程序集成到现有网站中






4.77/5 (22投票s)
一个高级 LightSwitch 教程,涵盖预处理查询、电子邮件、弹出窗口、WCF RIA 服务和 HTML 页面
![]() |
![]() |
实时示例
有关 LightSwitch 的入门文章,请参阅
注意:您必须拥有 Visual Studio Professional 或更高版本,才能执行本教程中的所有步骤。
您可以从此链接下载 Visual Studio LightSwitch
将多个 LightSwitch 应用程序放入您的网站
Microsoft Visual Studio LightSwitch 存在我称之为“全屏限制”的问题。LightSwitch 希望填满整个屏幕,并且希望管理角色和用户。如果您只有一个应用程序,这没关系,但是有很多情况下,您希望 LightSwitch 应用程序成为单个门户中一组应用程序的一部分。您希望所有应用程序共享相同的用户、角色和数据库。
与描述正常“LightSwitch 仅部署”的文章 Online Ordering 不同,本文将探讨将 LightSwitch 应用程序部署到包含其他应用程序的 ASP.NET 应用程序中的技术。在本文中,将使用 DotNetNuke,但是本文中的所有内容都可以用于任何 ASP.NET 应用程序。
将 LightSwitch 集成到 ASP.NET 应用程序中的关键是使用 IFrames
。
要求
在此示例中,我们将创建一个满足以下要求的应用程序
- 允许注册用户(发帖人)能够创建他们要出售的物品的帖子,而无需发布他们的电子邮件地址
- 允许匿名用户(买家)能够查看帖子,而无需他们安装 Silverlight 插件
- 允许买家回复帖子,并自动发送电子邮件给发帖人
- 允许发帖人查看和回复所有按帖子排序的通信
- 允许管理员编辑所有数据
这可能不是一个大型应用程序,但可能需要几天的时间。使用 LightSwitch,您可以在大约一个小时内创建整个应用程序。
“待售物品”应用程序的演练
您可以在此链接尝试实时待售物品应用程序
当您未登录时,您将看到可以浏览的帖子列表。
您可以点击帖子向发帖人发送消息。
登录后,您将能够创建帖子,并查看与帖子相关的任何消息(当您的帖子收到新消息时,您将收到电子邮件)。
另请注意,LightSwitch 会自动实现许多其他功能,例如 并发检查和 自动省略。
创建应用程序
您可以从此链接下载 Visual Studio LightSwitch
安装后,使用文件、新建项目来创建 LightSwitch 应用程序。
在解决方案资源管理器中双击 属性。
将应用程序设置为Web 应用程序。
将其设置为使用表单身份验证。
类别表和屏幕
创建类别表和编辑它们的屏幕,这项任务可以在一分钟内完成。
右键单击解决方案资源管理器中的数据源节点,然后选择添加表。
单击表名更改名称。输入Category作为名称。
创建上面的表。
右键单击屏幕节点,然后选择添加屏幕...
使用Categories创建一个可编辑网格屏幕(LightSwitch 会自动“复数化”表名)。
屏幕将显示。
按F5运行应用程序。
我们现在可以在应用程序中创建类别。
关闭您的网页浏览器以停止应用程序。
创建剩余的表
创建一个具有上述架构的Post
表。
创建一个具有上述架构的Message
表。
创建关系
打开Message
表,然后单击Relationship
按钮。
在添加新关系框中,输入上面的设置。
打开Post
表。
在添加新关系框中,输入上面的设置。
关系已完成。
设置关系对于 LightSwitch 非常重要。它允许重要功能,例如创建屏幕,其中与 Posts
相关的 Posts
和 Messages
始终保持同步,而无需任何代码。
任何 Entity
(表)与一个或多个其他 Entities 没有关系的情况非常罕见。
设置记录创建时的默认值
打开Message
表,然后选择编写代码,然后选择 Message Created。
将方法更改为以下内容
partial void Message_Created()
{
this.MessageCreated = DateTime.UtcNow;
}
这将设置创建 Message
时的日期。请注意,我们使用的是“UtcNow”,因此时间以协调世界时 (UTC) 记录。显示时间时,我们可以将其转换为用户的本地时间。
打开Post
表,然后选择编写代码,然后选择 Post Updating。
将方法更改为以下内容
partial void Posts_Updating(Post entity)
{
entity.PostUpdated = DateTime.UtcNow;
}
打开Post
表,然后选择编写代码,然后选择 Post Created。
将方法更改为以下内容
partial void Post_Created()
{
this.PostedBy = this.Application.User.Name;
this.PostCreated = DateTime.UtcNow;
this.PostUpdated = DateTime.UtcNow;
this.Active = true;
}
请注意该行
this.PostedBy = this.Application.User.Name;
这就是按用户分割数据所需的所有内容。
在运行时,DotNetNuke 站点(或任何在表单身份验证下运行的 ASP.NET 站点)将为“this.Application.User.Name
”提供用户名。
在后续步骤中,我们将使用 PreProcess
查询来限制用户只能查看他们自己的 Posts
(和 Messages
)。
发送电子邮件
此应用程序需要发送电子邮件。现在让我们启用此功能。
为此,我们需要切换到文件视图。
在 Server
项目中,添加对 System.configuration
和 System.Messaging
的引用。
在 Server
项目的 UserCode 文件夹中添加一个名为 MailHelper.cs 的类。
使用以下代码
// Adapted from:
// http://www.paulspatterson.com/technology/lightswitch/
// microsoft-lightswitch-sending-emails-from-the-client/#more-2896
using System.Net;
using System.Net.Mail;
using System.Configuration;
using System;
namespace LightSwitchApplication
{
public class MailHelper
{
private string _SMTPSendingEmailAddress { get; set; }
private string _SMTPServer { get; set; }
private string _SMTPUserId { get; set; }
private string _SMTPPassword { get; set; }
private int _SMTPPort { get; set; }
private bool _SMTPSSL { get; set; }
private string _MailFromName { get; set; }
private string _MailToEmail { get; set; }
private string _MailToName { get; set; }
private string _MailSubject { get; set; }
private string _MailBody { get; set; }
public MailHelper(
string SendFromName, string SendToEmail,
string SendToName, string Subject,
string Body)
{
_MailFromName = SendFromName;
_MailToEmail = SendToEmail;
_MailToName = SendToName;
_MailSubject = Subject;
_MailBody = Body;
_SMTPSendingEmailAddress = Convert.ToString
(ConfigurationManager.AppSettings["SMTPSendingEmailAddress"]);
_SMTPServer = Convert.ToString(ConfigurationManager.AppSettings["SMTPServer"]);
_SMTPUserId = Convert.ToString(ConfigurationManager.AppSettings["SMTPUserID"]);
_SMTPPassword = Convert.ToString(ConfigurationManager.AppSettings["SMTPPassword"]);
_SMTPPort = Convert.ToInt32(ConfigurationManager.AppSettings["SMTPPort"]);
_SMTPSSL = Convert.ToBoolean(ConfigurationManager.AppSettings["SMTPSSL"]);
}
public void SendMail()
{
MailMessage mail = new MailMessage();
System.Net.Mail.MailAddress mailFrom =
new System.Net.Mail.MailAddress(_SMTPSendingEmailAddress, _MailFromName);
System.Net.Mail.MailAddress mailTo =
new System.Net.Mail.MailAddress(_MailToEmail, _MailToName);
var _with1 = mail;
_with1.From = mailFrom;
_with1.To.Add(mailTo);
_with1.Subject = _MailSubject;
_with1.Body = _MailBody;
SmtpClient smtp = new SmtpClient(_SMTPServer, _SMTPPort);
smtp.EnableSsl = _SMTPSSL;
smtp.Credentials =
new NetworkCredential(_SMTPUserId, _SMTPPassword);
smtp.Send(mail);
}
}
}
单击解决方案资源管理器中的项目名称,然后选择显示所有文件。
这将允许您看到 ServerGenerated
项目。
此项目由 LightSwitch 创建,并在 LightSwitch 部署为 Web 应用程序时使用。这是我们将最终放置用于生成 HTML 页面的 .aspx 文件的位置。目前,我们只需要在 Web.config 文件中添加一些条目
这将使我们在部署应用程序时能够轻松更改 SMTP 邮件服务器设置。
切换回逻辑视图。
打开Message
表,然后选择 Messages_Inserted
方法。
为该方法使用以下代码(用于发送电子邮件)
#region Messages_Inserted
partial void Messages_Inserted(Message entity)
{
string strSubject = "Message From ThingsForSale";
string strMessage = String.Format("{0}",
"This is a message From the Things For Sale program.")
+ Environment.NewLine + Environment.NewLine;
strMessage = strMessage + String.Format("Regarding the post '{0}'",
entity.Post.Description) + Environment.NewLine;
strMessage = strMessage + String.Format("This message was sent by {0}",
entity.NameFrom) + Environment.NewLine + Environment.NewLine;
strMessage = strMessage + String.Format("Message: {0}",
entity.MessageText) + Environment.NewLine;
// Create the MailHelper class created in the Server project.
MailHelper mailHelper =
new MailHelper(
entity.NameFrom,
entity.EmailTo,
entity.NameTo,
strSubject,
strMessage);
// Send Email
mailHelper.SendMail();
}
#endregion
创建帖子和消息屏幕
在解决方案资源管理器中,右键单击屏幕节点并选择添加屏幕...
创建一个列表和详细信息屏幕。
注意:由于我们在表之间创建了关系,因此可以通过勾选一个框来使帖子和消息显示在同一个屏幕上。
屏幕将显示
运行应用程序时,您将能够输入帖子和消息。
将应用程序部署到 DotNetNuke 网站
在此处遵循有关将应用程序部署到 DotNetNUke 网站的说明: Easy DotNetNuke LightSwitch Deployment。
我们现在有了上面所示的基本布局。LightSwitch 应用程序运行在 IFrame
中,并具有相同的数据库连接、MachineKey 和 Forms Cookie,因此它能够与托管它的 DotNetNuke 站点通信并共享用户身份验证。
对于许多应用程序来说,这就足够了。在我们的示例中,我们需要确定用户是否是管理员,因为我们希望为管理员提供额外的功能。
我们可以简单地将 DotNetNuke 用户和角色表添加到 LightSwitch 应用程序作为外部表,但我发现这有时会导致用户表锁定(请参阅 此链接了解更多信息)。
添加 WCF RIA Service 可以防止任何锁定问题。
创建 WCF RIA 服务
(注意:您必须拥有 Visual Studio Professional 或更高版本,才能执行以下步骤。)
(请参阅 此链接了解有关为 LightSwitch 创建 WCF RIA Services 的官方信息。)
添加新项目。
创建一个新的类库。
右键单击创建的 Class1.cs 文件并删除它。
添加实体数据模型...
连接到DotNetNuke数据库。
通常,我们只需要添加 vw_UserRoles
视图来确定用户是否是管理员。
但是,我们还将添加 Category
、Post
和 Message
表,因为我们还将在后续步骤中创建的 .aspx(HTML)页面中使用实体数据模型。
生成项目。
添加域服务类。
我们只需要 Domain Service Class 中的 vw_userRoles
。此外,取消选中启用客户端访问以增加安全性,因为我们不需要它。
将创建域服务类。
将 [Query(IsDefault = true)]
添加到(自动创建的)方法的顶部。
保存文件并生成解决方案。
右键单击数据源节点,然后选择添加数据源...
选择WCF RIA Service然后单击下一步。
(如果框消失且长时间没有发生任何事情,请不要感到惊讶。另外,框现在可能隐藏在Visual Studio主窗口后面。)
单击添加引用。
选择数据项目然后单击确定。
等待域服务类出现在列表框中。有时需要 1-2 分钟。
出现时,选择它,然后单击下一步。
通过选中其框来选择要使用的实体(在这种情况下,我们要使用 vw_UserRoles
)。
请勿在连接字符串中输入任何内容,因为我们将在 Web.config 中手动设置它。
点击**完成**。
数据源将显示。
从数据项目的 App.config 中复制连接字符串。
切换到文件视图,然后打开 Web.config,然后添加连接字符串。
使用 WCF RIA 服务
为了演示如何使用我们新的 WCF RIA Service,请打开 EditableCategoriesGrid
屏幕并选择 EditableCategoriesGrid_CanRun
事件。
将方法更改为以下代码
partial void EditableCategoriesGrid_CanRun(ref bool result)
{
// Must be an Administrator for this link to show
var WorkSpace = this.CreateDataWorkspace();
var UserInRole = (from DNNUser in WorkSpace.DNNDomainServiceData.vw_UserRoles
where DNNUser.Username == this.User.Name
where DNNUser.RoleName == "Administrators"
select DNNUser).FirstOrDefault();
result = (UserInRole != null);
}
单击解决方案资源管理器中的项目。
这将允许您选择发布。
重新发布应用程序。
您必须重做在遵循 Easy DotNetNuke LightSwitch Deployment 中的说明时对 web.config 所做的所有更改,因为在创建 WCF RIA Service 时,web.config 中添加了新内容。
当您在 DotNetNuke 网站中运行应用程序时,只有管理员才能看到编辑类别的链接。
使用预处理查询启用安全性
其中一项要求是管理员可以看到所有帖子,而非管理员只能看到他们自己的帖子(和消息)。
打开Posts实体,然后选择Posts All PreprocessQuery。
将代码更改为以下内容
partial void Posts_All_PreprocessQuery(ref IQueryable<Post> query)
{
// Only run this PreProcess Query if user is Authenticated
if (this.Application.User.IsAuthenticated)
{
string UserName = this.Application.User.Name;
// Connect to DotNetNuke Data
var WorkSpace = this.Application.CreateDataWorkspace();
var UserInRole = (from DNNUser in WorkSpace.DNNDomainServiceData.vw_UserRoles
where DNNUser.Username == UserName
where DNNUser.RoleName == "Administrators"
select DNNUser).FirstOrDefault();
// If User is not an Administrator
// The User can only see their own posts
if (UserInRole == null)
{
query = query.Where(x => x.PostedBy == this.Application.User.Name);
}
}
}
模态窗口(弹出窗口)
模态窗口(也称为弹出窗口)是一个重要的用户界面工具,因为它们要求用户在执行其他任何操作之前完成指定的任务。
在此示例应用程序中,我们希望在用户查看现有消息或回复消息时显示弹出窗口。
还有其他弹出窗口,但它们由 LightSwitch 自动创建。
当前,当打开现有消息时,它会显示所有字段,如上图所示。
我们希望弹出窗口类似于上图。
为此,我们将创建自己的弹出窗口,然后覆盖打开当前弹出窗口的代码,以打开我们的弹出窗口。
在屏幕设计器中,选择详细信息列,然后添加消息的选定项。
它将显示。
将该部分更改为模态窗口。
将所有文本框更改为标签并删除其余项。
选择模态窗口,并记下窗口的名称。取消选中显示按钮框(否则 LightSwitch 会在屏幕底部显示一个按钮来打开窗口)。
单击消息数据网格,展开命令栏,右键单击编辑按钮,然后选择覆盖代码。
将代码更改为以下内容
partial void MessagesEditSelected_Execute()
{
this.OpenModalWindow("Messages_SelectedItem");
}
现在,如果我们选择编辑按钮,它将打开我们的自定义弹出窗口。
我们将在下一步添加一个回复按钮,该按钮将允许我们实际创建一条消息,作为对 HTML 页面(将在后续步骤中创建)中输入的消息的回复。
注意:要理解后续步骤,建议您阅读: This Is How LightSwitch Does MVVM。
切换到文件视图,并在 Client
项目中添加对 System.Windows.Controls
的引用(以便我们可以以编程方式将 PopUp
作为 ChildWindow
进行交互)。
选择添加数据项...
创建一个类型为 Message
的本地属性,并将其命名为 Message_Response
。
它将显示在屏幕的“视图模型”上(请参阅: This Is How LightSwitch Does MVVM 以了解视图模型的解释)。
选择详细信息列部分,并将消息响应属性添加到屏幕。
将其更改为模态窗口。
属性将显示。
- 删除除收件人姓名、收件人电子邮件和消息文本之外的所有控件
- 将收件人姓名更改为标签
- 在模态窗口的属性中,取消选中显示按钮
向模态窗口的命令栏添加一个按钮,并将其命名为 SaveResponse。
在按钮的属性中,将显示名称更改为保存消息。
右键单击按钮,然后选择编辑执行代码。
将代码更改为
#region SaveResponse_Execute
partial void SaveResponse_Execute()
{
this.CloseModalWindow("Message_Response");
this.Save();
}
#endregion
导航到消息数据网格的命令栏,删除添加按钮,然后添加一个新按钮。
将其命名为 RespondToMessage
。
将其拖到其他两个剩余按钮的顶部,然后右键单击它并选择编辑执行代码。
使用以下代码创建新的 Message
并打开弹出窗口,还可以检测弹出窗口何时关闭(单击弹出窗口右上角的 x 时),并删除任何未保存的 Messages
#region RespondToMessage_Execute
partial void RespondToMessage_Execute()
{
// Create a new Message
Message_Response = new Message();
//Set the Post
Message_Response.Post = Posts.SelectedItem;
// Set Email defaults
Message_Response.MessageBy = this.Application.User.Name;
// these values are from the currently selected Message
Message_Response.NameFrom = Messages.SelectedItem.NameTo;
Message_Response.EmailFrom = Messages.SelectedItem.EmailTo;
Message_Response.NameTo = Messages.SelectedItem.NameFrom;
Message_Response.EmailTo = Messages.SelectedItem.EmailFrom;
this.OpenModalWindow("Message_Response");
// Wire up an event to detect when the Modal window is closed
this.FindControl("Message_Response").ControlAvailable +=
new EventHandler<ControlAvailableEventArgs>(PostsListDetail_ControlAvailable);
}
#endregion
#region PostsListDetail_ControlAvailable
void PostsListDetail_ControlAvailable(object sender, ControlAvailableEventArgs e)
{
ChildWindow window = (ChildWindow)e.Control;
window.Closed += new EventHandler(Message_Response_Closed);
}
#endregion
#region Message_Response_Closed
void Message_Response_Closed(object sender, EventArgs e)
{
ChildWindow window = (ChildWindow)sender;
if (!(window.DialogResult.HasValue))
{
// Remove unsaved records
foreach (Message message in
this.DataWorkspace.ApplicationData.Details.GetChanges()
.AddedEntities.OfType<Message>())
{
message.Details.DiscardChanges();
}
}
}
#endregion
您还需要将 using System.Windows.Controls;
添加到类的顶部。
创建 HTML 页面
切换到文件视图。
向 ServerGenerated
项目添加对 System.configuration
的引用。
添加一个名为 PublicPage.aspx 的 .aspx 页面,并为代码隐藏使用以下代码(请从下载中获取HTML代码)
using DNNData;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text.RegularExpressions;
using System.Transactions;
using System.Web.UI;
using System.Web.UI.WebControls;
using LightSwitchApplication;
namespace ApplicationData.Implementation
{
public partial class PublicPage : System.Web.UI.Page
{
#region CurrentPage
public int CurrentPage
{
get
{
if (ViewState["CurrentPage"] == null)
{
return 1;
}
else
{
return (int)ViewState["CurrentPage"];
}
}
set
{
ViewState["CurrentPage"] = value;
}
}
#endregion
#region CurrentPostID
public int CurrentPostID
{
get
{
if (ViewState["CurrentPostID"] == null)
{
return -1;
}
else
{
return (int)ViewState["CurrentPostID"];
}
}
set
{
ViewState["CurrentPostID"] = value;
}
}
#endregion
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
GetPosts(true, CurrentPage);
}
}
#region GetPosts
private void GetPosts(bool FillCategories, int intPage)
{
// Collections to hold the final results
List<DNNData.Category> lstCategories = new List<DNNData.Category>();
// Connect to DotNetNuke Data
string _IntrinsicData = Convert.ToString
(ConfigurationManager.ConnectionStrings["DotNetNuke5Entities"]);
DotNetNuke5Entities db = new DotNetNuke5Entities(_IntrinsicData);
int intCategoryID = -1;
// Get selected category
if (!FillCategories)
{
intCategoryID = Convert.ToInt32(ddlCategories.SelectedValue);
}
if (FillCategories)
{
// execute query
var colCatagories = (from Cat in db.Categories
select Cat).ToList();
// Add an All option
DNNData.Category objCategory = new DNNData.Category();
objCategory.Id = -1;
objCategory.CategoryName = "All";
lstCategories.Add(objCategory);
// Add Categories
foreach (var item in colCatagories)
{
lstCategories.Add(item);
}
// We now have the results - bind then to the dropdown
ddlCategories.DataSource = lstCategories;
ddlCategories.DataBind();
}
// Get Posts
// create query
var colPosts = from PST in db.Posts
select PST;
// Get active posts
colPosts = colPosts.Where(x => x.Active == true);
// Get Category
if (intCategoryID != -1)
{
colPosts = colPosts.Where(x => x.Category.Id == intCategoryID);
}
// Do paging
colPosts =
colPosts.OrderByDescending(x => x.PostUpdated).
Skip(((intPage - 1) * 10)).Take(10);
// We now have the results - bind then to the dropdown
gvPosts.DataSource = colPosts;
gvPosts.DataBind();
}
#endregion
#region ddlCategories_SelectedIndexChanged
protected void ddlCategories_SelectedIndexChanged(object sender, EventArgs e)
{
pnlMessage.Visible = false;
GetPosts(false, CurrentPage);
}
#endregion
#region btnLeft_Click
protected void btnLeft_Click(object sender, EventArgs e)
{
pnlMessage.Visible = false;
if (CurrentPage > 1)
{
CurrentPage--;
}
GetPosts(false, CurrentPage);
}
#endregion
#region btnRight_Click
protected void btnRight_Click(object sender, EventArgs e)
{
pnlMessage.Visible = false;
if (gvPosts.Rows.Count > 0)
{
CurrentPage++;
}
GetPosts(false, CurrentPage);
}
#endregion
#region gvPosts_RowCommand
protected void gvPosts_RowCommand(object sender, GridViewCommandEventArgs e)
{
LinkButton lnkButtton = (LinkButton)e.CommandSource;
CurrentPostID = Convert.ToInt32(lnkButtton.CommandArgument);
pnlMessage.Visible = true;
}
#endregion
#region btnSubmit_Click
protected void btnSubmit_Click(object sender, EventArgs e)
{
try
{
Transaction currentTrx = Transaction.Current;
Transaction.Current = null;
// Validate
if (!IsValidEmail(txtEmail.Text))
{
lblError.Text = "Must use a valid Email";
return;
}
if (txtEmail.Text.Count() < 1)
{
lblError.Text = "Must enter a message";
return;
}
if (txtEmail.Text.Count() > 255)
{
lblError.Text = "Message must be less than 255 characters";
return;
}
// Connect to DotNetNuke Data
string _IntrinsicData = Convert.ToString
(ConfigurationManager.ConnectionStrings["DotNetNuke5Entities"]);
DotNetNuke5Entities db = new DotNetNuke5Entities(_IntrinsicData);
// Get the information for the user who made the Post
var DNNUser = (from PST in db.Posts
from vw_Users in db.vw_UserRoles
where PST.PostedBy == vw_Users.Username
where PST.Id == CurrentPostID
select vw_Users).FirstOrDefault();
// Create New Message
DNNData.Message NewMessage = new DNNData.Message();
NewMessage.NameFrom = txtName.Text;
NewMessage.EmailFrom = txtEmail.Text;
NewMessage.NameTo = DNNUser.DisplayName;
NewMessage.EmailTo = DNNUser.Email;
NewMessage.MessageText = txtMessage.Text;
NewMessage.MessageCreated = DateTime.UtcNow;
NewMessage.Message_Post = CurrentPostID;
db.AddToMessages(NewMessage);
db.SaveChanges();
// Get the information for the Post
var PostInfo = (from PST in db.Posts
where PST.Id == CurrentPostID
select PST).FirstOrDefault();
// Send Email
string strSubject = "Message From ThingsForSale";
string strMessage = String.Format("{0}",
"This is a message From the Things For Sale program.")
+ Environment.NewLine + Environment.NewLine;
strMessage = strMessage + String.Format("Regarding the post '{0}'",
PostInfo.Description) + Environment.NewLine;
strMessage = strMessage + String.Format("This message was sent by {0}",
txtName.Text) + Environment.NewLine + Environment.NewLine;
strMessage = strMessage + String.Format("Message: {0}",
txtMessage.Text) + Environment.NewLine;
// Create the MailHelper class created in the Server project.
MailHelper mailHelper =
new MailHelper(
txtName.Text,
DNNUser.Email,
DNNUser.DisplayName,
strSubject,
strMessage);
// Send Email
mailHelper.SendMail();
lblError.Text = "Success";
// Clear fields
txtMessage.Text = "";
}
catch (Exception ex)
{
lblError.Text = ex.Message;
}
}
#endregion
#region IsValidEmail
public static bool IsValidEmail(string strIn)
{
// Return true if strIn is in valid e-mail format.
// From: http://msdn.microsoft.com/en-us/library/01escwtf.aspx
return Regex.IsMatch(strIn,
@"^(?("")("".+?""@)|(([0-9a-zA-Z]((\.(?!\.))|
[-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)(?<=[0-9a-zA-Z])@))" +
@"(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-zA-Z][-\w]*
[0-9a-zA-Z]\.)+[a-zA-Z]{2,6}))$");
}
#endregion
}
}
在 LightSwitch 中创建指向 HTML 页面的链接
在 Client
项目中添加对 System.Windows.Browser
的引用。
切换到逻辑视图。
添加屏幕...
添加一个名为 PublicPage
的新数据屏幕,不选择屏幕数据。
选择 PublicPage_Run
方法。
将其更改为以下代码
partial void PublicPage_Run(ref bool handled)
{
// Set handled to 'true' to stop further processing.
Dispatchers.Main.Invoke(() =>
{
HtmlPage.Window.Navigate(new Uri("PublicPage.aspx", UriKind.Relative));
});
handled = true;
}
您还需要将以下 using
语句添加到类中
using Microsoft.LightSwitch.Threading;
using System.Windows.Browser;
现在我们需要将 PublicPage.aspx 添加到生成文件中,以便 LightSwitch 将其包含在生成中。
注意:您将希望在执行以下步骤之前备份整个解决方案
切换到文件视图,右键单击LightSwitch项目并选择卸载项目。
右键单击已卸载的项目并选择编辑。
将以下内容添加到 _buildFile
部分的底部
<_BuildFile Include="ServerGenerated\PublicPage.aspx">
<SubFolder>
</SubFolder>
<PublishType>
</PublishType>
</_BuildFile>
重新加载项目。
现在您可以运行项目并单击公共页面链接...
...并导航到 HTML 页面。
在您的应用程序中,您将希望使 HTML 页面对未经验证的用户可用。
LightSwitchHelpWebsite 上的实时演示有一个直接指向 PublicPage.aspx 的 IFrame
,并且仅显示给未经验证的用户。第二个 IFrame
,仅对注册用户启用,显示正常的 LightSwitch 应用程序。
收尾工作
在帖子屏幕上,删除发帖人,因为它是在编程方式设置的。
但是,请注意它仍然显示在自动创建的弹出窗口上。
打开Post实体,然后选择PostedBy
字段,然后取消选中默认显示框。
弹出窗口将不再显示该字段。
在帖子屏幕上,将消息数据网格设置为使用只读控件。
选择回复消息按钮的CanExecute Code。
将代码更改为以下内容
#region RespondToMessage_CanExecute
partial void RespondToMessage_CanExecute(ref bool result)
{
// Must have a Message Selected
result = (Messages.SelectedItem != null);
}
#endregion
对消息编辑按钮执行相同的操作。
这会导致按钮在未选择 Message
时被禁用。
转到项目的属性,将帖子列表详细信息屏幕设置为启动屏幕。
高级 LightSwitch 应用程序
这演示了一个高级 LightSwitch 应用程序。但是,LightSwitch 还有很多内容。例如,可以使用 Silverlight 自定义控件控制整个 UI。
在