移动服务集成与Azure系统生产准备
1. 移动服务开发要点
1.1 调试控制台使用注意
在生产环境中应谨慎使用调试控制台,因为根据标签设置,通知可能会发送给真实用户。
1.2 应用完成步骤
数据服务通过以下步骤注入到视图模型中:
1. 首先在
ViewModelLocator
中注册数据服务。
2. 然后在视图模型构造函数中添加接口参数以进行绑定。
1.3 避免提前调用登录方法
要确保在UI完全加载之前不调用
MobileServiceClient.LoginAsync
方法,因为该方法需要插入到根UI元素中,提前调用会导致失败。为确保这一点,代码示例中的视图模型通过触发器挂钩到页面加载事件,以进行初始化、检索数据和设置推送通道(当获得有效通道时,将进行经过身份验证的请求)。
1.4 更新订单处理器
更新订单处理器工作角色,以便在订单状态更改时调用
Notification/PostOrderUpdate
操作,具体步骤如下:
1. 在NuGet包管理器控制台中使用以下命令安装移动服务NuGet包:
Install-Package WindowsAzure.MobileServices
-
在角色设置中添加
mobileServiceUrl字符串设置,本地使用本地服务的URL,云端使用发布服务的URL。 -
在角色设置中添加
mobileServiceKey字符串设置,本地使用本地服务的主密钥,云端使用发布服务的主密钥。 -
添加
MobileServiceClient变量,并在构造函数中使用云配置设置进行实例化:
private readonly MobileServiceClient _mobileService;
public OrderProcessor()
{
var mobileServiceUrl = CloudConfigurationManager.GetSetting("mobileServiceUrl");
var mobileServiceKey = CloudConfigurationManager.GetSetting("mobileServiceKey");
this._mobileService = new MobileServiceClient(mobileServiceUrl, mobileServiceKey);
}
-
添加
NotifyHub方法,以使用更新后的订单ID调用Notification/PostOrderUpdate操作:
private async Task NotifyHub(int orderId)
{
dynamic data = new ExpandoObject();
data.orderId = orderId;
await this._mobileService.InvokeApiAsync<object, dynamic>("Notification/PostOrderUpdate", data);
}
-
最后,如果订单状态发生更改,添加一行代码调用
NotifyHub方法:
public async Task Process(Order order)
{
// Update status
var currentOrder = this._ctx.Orders.FirstOrDefault(o => o.Id == order.Id);
if (currentOrder != null && currentOrder.Status != order.Status)
{
currentOrder.Status = order.Status;
await this._ctx.SaveChangesAsync();
await this.NotifyHub(order.Id);
}
}
1.5 更新管理网站
对管理网站进行小修改,以便在创建新产品时调用
Notification/PostProductNews
操作,向所有客户发送推送通知。创建一个单独的辅助类将逻辑与控制器分离:
private readonly MobileServiceClient _mobileService;
public Notifications()
{
var mobileServiceUrl = ConfigurationManager.AppSettings["mobileServiceUrl"];
var mobileServiceKey = ConfigurationManager.AppSettings["mobileServiceKey"];
this._mobileService = new MobileServiceClient(mobileServiceUrl, mobileServiceKey);
}
public async Task NotifyPostProductNews(int productId)
{
dynamic data = new ExpandoObject();
data.productId = productId;
await this._mobileService.InvokeApiAsync<object, dynamic>("Notification/PostProductNews", data);
}
该方法可由
ProductController.Create
操作调用:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create([Bind(Include = "Id,Name,ProductType,Price,IsAvailable")] Product product)
{
if (ModelState.IsValid)
{
db.Products.Add(product);
db.SaveChanges();
// Notify users via push notifications
await new Notifications().NotifyPostProductNews(product.Id);
return RedirectToAction("Index");
}
return View(product);
}
1.6 创建供应移动服务
创建一个移动服务和Windows应用商店应用程序,使仓库工作人员能够在平板电脑设备上查看待发货订单、打印标签并将订单标记为已发货。具体步骤如下:
1. 右键单击解决方案,选择“添加” -> “新项目”,从“云”模板部分选择“Windows Azure移动服务”模板。
2. 在NuGet包管理器控制台中输入以下命令,安装
WindowsAzure.ServiceBus
NuGet包,以便将已发货订单状态更新发送到服务总线主题:
Install-package WindowsAzure.ServiceBus
-
在NuGet包管理器控制台中输入以下命令,安装
WindowsAzure.StorageNuGet包,以便从订单表存储中读取订单实体,并从Blob存储中读取条形码地址标记的JPEG图像:
Install-package WindowsAzure.Storage
1.7 配置移动服务以进行Azure AD身份验证
将供应系统与Azure Bakery AD集成,具体步骤如下:
1. 在AD命名空间工作区的“应用程序”选项卡中,点击工具栏上的“添加”,选择“添加我的组织正在开发的应用程序”。
2. 为应用程序命名,保留默认的“Web应用程序和/或Web API”类型。
3. 填写“登录URL”和“应用程序ID URI”字段,这些URL是服务发布时创建的,可从“IDENTITY”选项卡中的Windows Azure Active Directory部分收集,格式类似
https://azurebakerysupply.azure-mobile.net/signin-aad
。
4. 按照之前对Web API的操作方式,修改清单以允许其他应用程序(我们的移动应用)访问它。
5. 在应用程序的“配置”标签上,复制“客户端ID”值。
6. 将其粘贴到移动服务“IDENTITY”选项卡中的“客户端ID”设置中,并将AD租户添加到“允许的租户”中,然后点击“保存”。
1.8 创建条形码控制器
以下
ApiController
从Blob存储中检索由订单处理器创建的JPEG条形码地址标签:
[AuthorizeLevel(AuthorizationLevel.User)]
public class BarcodeController : ApiController
{
private readonly CloudStorageAccount _storageAccount;
public ApiServices Services { get; set; }
public BarcodeController()
{
// Retrieve the storage account from the connection string.
this._storageAccount = CloudStorageAccount.Parse(ConfigurationManager.ConnectionStrings["StorageConnectionString"].ConnectionString);
}
// GET api/Barcode
public async Task<byte[]> Get(string reference)
{
Services.Log.Info("BarcodeController - Patch Start");
try
{
var blobClient = this._storageAccount.CreateCloudBlobClient();
var container = blobClient.GetContainerReference("barcodes");
var blobRef = container.GetBlockBlobReference(reference);
await blobRef.FetchAttributesAsync();
var buffer = new byte[blobRef.Properties.Length];
await blobRef.DownloadToByteArrayAsync(buffer, 0);
Services.Log.Info("BarcodeController - Patch Completed");
return buffer;
}
catch (Exception ex)
{
Services.Log.Error("BarcodeController - Get Error", ex);
throw;
}
}
}
1.9 创建订单控制器
OrderController
类的
Get
方法从表存储中的
Orders
表返回
OrderEntity
实体,这些实体由订单处理器创建和更新:
public IEnumerable<OrderEntity> Get()
{
Services.Log.Info("OrderController - Get Start");
try
{
var tableClient = _storageAccount.CreateCloudTableClient();
var table = tableClient.GetTableReference("orders");
var query = new TableQuery<OrderEntity>()
.Where(TableQuery.GenerateFilterCondition("Status", QueryComparisons.Equal, OrderStatus.Open.ToString()));
var data = table.ExecuteQuery(query);
Services.Log.Info("OrderController - Get Completed");
return data;
}
catch (System.Exception ex)
{
Services.Log.Error("OrderController - Get Error", ex);
throw;
}
}
Put
方法使用
TableOperation.Replace
操作更新
OrderEntity
实体,然后使用类似于管理网站中实现的
MessagingService
将订单更新发送到服务总线:
public async Task Put([FromBody] OrderEntity entity)
{
Services.Log.Info("OrderController - Put Start");
try
{
// Get orders table
var tableClient = _storageAccount.CreateCloudTableClient();
var table = tableClient.GetTableReference("orders");
// Update entity
var updateOp = TableOperation.Replace(entity);
var updateResult = await table.ExecuteAsync(updateOp);
// Send to service bus
var messaging = new MessagingService();
await messaging.CreateSubscriptionAsync();
await messaging.DispatchOrder(entity);
Services.Log.Info("OrderController - Put Completed");
}
catch (System.Exception ex)
{
Services.Log.Error("OrderController - Put Error", ex);
throw;
}
}
1.10 创建供应Windows应用商店应用程序
添加一个Windows应用商店应用程序以与移动服务进行交互,具体步骤如下:
1. 右键单击解决方案,选择“添加” -> “新项目”,从“应用商店应用”模板中选择Windows应用模板。
2. 在NuGet包管理器控制台中输入以下命令,安装
WindowsAzure.MobileServices
NuGet包:
Install-package WindowsAzure.MobileServices
-
在NuGet包管理器控制台中输入以下命令,安装
MVVM LightNuGet包:
Install-package MvvmLight
-
在NuGet包管理器控制台中输入以下命令,安装
Microsoft.IdentityModel.Clients.ActiveDirectoryNuGet包,用于Azure AD身份验证:
Install-package Microsoft.IdentityModel.Clients.ActiveDirectory
-
在NuGet包管理器控制台中输入以下命令,安装
WindowsAzure.StorageNuGet包,以便与服务中的TableEntity实体进行交互:
Install-package WindowsAzure.Storage
-
在
Package.appxmanifest文件中启用“企业身份验证”和“专用网络(客户端和服务器)”,以便应用程序可以使用AD身份验证。
1.11 配置应用商店应用以进行AD身份验证
将应用程序在应用商店中注册以获取
Package SID
值,然后添加一个类似于之前创建的WPF客户端应用程序的AD应用程序,具体步骤如下:
1. 右键单击应用项目,选择“应用商店” -> “将应用与应用商店关联”。
2. 在下一个屏幕上点击“下一步”,然后登录到应用商店账户;如果没有账户,请先在
https://appdev.microsoft.com/StorePortals/en-us/Account/Signup/Start
创建。
3. 输入应用名称,点击“保留”进行保留,然后点击“下一步”。
4. 在下一个屏幕上点击“关联”以完成关联。
5. 登录到Microsoft账户开发者中心,选择新应用程序(
https://account.live.com/developers/applications
),并复制
Package SID
值。
6. 点击工具栏上的“添加”,选择“添加我的组织正在开发的应用程序”。
7. 输入名称,这次选择“本机客户端应用程序”。
8. 将
Package SID
值粘贴到“重定向URI”设置中,然后点击对勾完成设置。
9. 最后,在AD应用的“配置”选项卡中,为移动服务添加权限(此权限来自我们在移动服务的AD应用程序中进行的清单修改)。
1.12 创建DataServiceBase类
DataServiceBase
类与之前使用Twitter身份验证创建的Windows Phone
DataServiceBase
类非常相似,但在调用
LoginAsync
方法之前需要额外的步骤来获取访问令牌:
var ac = new AuthenticationContext(authority);
var ar = await ac.AcquireTokenAsync(resourceURI, clientID);
var payload = new JObject();
payload["access_token"] = ar.AccessToken;
user = await client.LoginAsync(_provider, payload);
2. 准备Azure系统用于生产
2.1 多环境项目配置
之前我们直接从Visual Studio发布网站和云服务,并使用Entity Framework Code First Migrations构建数据库。但从开发人员机器上的构建将系统部署到非开发环境不是一个好的做法,因为我们没有一种可控的方式来生成可重现、有版本号的部署。使用构建服务器可以确保我们从源代码控制中获得干净的构建,不受开发环境的影响,并且可以重复生成可版本化和存储的部署包,这样可以控制部署过程,并且在出现问题时可以轻松回滚到已知版本。
2.2 网站配置
对于网站,大部分配置都在
Web.config
文件中,其中包含数据库和存储连接字符串、身份验证提供程序密钥和服务总线连接字符串等信息。我们可以使用配置转换在发布网站时更改某些配置设置。在构建服务器上构建Web部署包时,打包过程还会创建一个
MyWebsite.SetParameters.xml
文件,允许我们在部署时更改秘密设置,也可以在门户中覆盖配置设置,但最好一开始就使用正确的设置,以免网站在部署后立即失败。
2.3 云服务配置
对于云服务,我们可以选择在
app.config
文件或
.cscfg
云配置中配置设置,云配置允许我们通过门户在运行时更改配置。一般来说,最佳实践是将所有设置放在云配置中。但对于一些情况,如EF(默认从配置文件中读取连接字符串,不进行修改就无法读取云配置)、不同类型应用程序共享的库(没有云配置的概念),我们需要使用
app.config
进行配置。这可能会带来一些困难,因为我们需要在部署前手动修改包中的
app.config
设置(包是ZIP文件,我们可以手动解压或编写脚本来自动化这个过程)。
2.4 敏感信息处理
许多配置设置包含敏感信息,我们应该谨慎对待谁可以访问这些信息,特别是在生产环境中。在一些公司(通常是较小的公司,不需要系统管理员),采用DevOps或NoOps方法进行部署,开发人员负责部署系统,他们可能会访问密码和身份验证密钥等秘密信息,但不应该将这些信息存储在源代码控制中,以免暴露给任何有权访问源代码的人,从而使系统面临风险。
2.5 多环境配置策略
之前我们在发布时通常使用Release配置转换来更改设置,但当我们开始将系统部署到多个环境时,这种策略不再满足需求,因为每个环境可能有不同的数据库、存储账户、Active Directory命名空间和服务总线命名空间,我们需要为每个环境配置相应的设置。我们将创建Prod、QA和测试配置,在打包网站和云服务时应用这些配置。
2.6 常见问题解答
| 问题 | 答案 |
|---|---|
| Azure移动服务与其他类型的服务相比有哪些优势? | 灵活的身份验证模型、推送通知和通知中心集成,以及适用于所有主要移动平台的客户端SDK。 |
| 管理授权级别有什么特别之处? | 这是最高级别的授权,会覆盖所有其他级别,并且需要移动服务主密钥,该密钥不应在客户端应用程序中使用。 |
| TableController为什么可能会给现有数据库架构带来问题,我们有哪些解决方法? |
TableController是针对
ITableData
接口进行类型化的,该接口需要一些默认字段,而现有表可能没有这些字段。我们可以使用类似AutoMapper的工具将现有实体映射到新实体,或者使用API控制器。
|
| 定时作业应该实现哪个基类,如何调用它们? |
ScheduledJob
;可以通过HTTP POST请求调用,并在门户中配置其运行计划。
|
| 如何将移动服务中通过OAuth提供程序进行身份验证的用户与MVC网站创建的用户关联起来? |
在
DbContext
中添加
AspNetUser
和
AspNetUserLogin
用户的模型,并使用匹配的
DbSet
属性,然后使用这些属性将用户凭据中的登录提供程序ID和密钥与表中的值关联起来。
|
| 移动服务的“PUSH”选项卡中,“启用未经身份验证的推送通知”(Windows Phone通知设置(mpns))设置有什么作用? | 该设置允许没有身份验证证书的请求进行推送通知,但每天限制为500条。 |
从
MobileServiceClient
实例成功登录后,哪个对象包含用户凭据?
|
MobileServiceClient.CurrentUser
属性中的
MobileServiceUser
对象。
|
在
DataServiceBase
类中,为什么
MobileServiceClient
变量被标记为静态?
| 因为只有一个实例,这意味着用户凭据可用于应用程序中的所有请求。 |
| 在Windows Phone应用中,需要启用哪个功能,在哪里进行配置? |
ID_CAP_PUSH_NOTIFICATION
,在
WMAppManifest.xml
文件中配置。
|
当我们调用
NotificationHub.RegisterNativeAsync
方法时,
tagExpression
参数有什么作用?
| 它允许我们提供与用户想要订阅的主题相关的标签列表,这些标签应该在应用程序中可由用户配置。 |
| 访问表和Blob存储需要哪个NuGet包? |
WindowsAzure.Storage
。
|
使用
MobileServiceClient
进行AD身份验证登录之前,必须执行哪个步骤?
|
调用
AuthenticationContext.AcquireTokenAsync
方法获取访问令牌。
|
综上所述,在移动服务开发和Azure系统生产准备过程中,我们需要注意各个环节的配置和操作,确保系统的安全性、稳定性和可维护性。同时,通过合理的配置和使用工具,我们可以更高效地进行开发和部署工作。
3. 配置与操作流程可视化
3.1 移动服务开发流程
graph LR
classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px
classDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px
A([开始]):::startend --> B(调试控制台使用注意):::process
B --> C(应用完成步骤):::process
C --> D(避免提前调用登录方法):::process
D --> E(更新订单处理器):::process
E --> F(更新管理网站):::process
F --> G(创建供应移动服务):::process
G --> H(配置移动服务以进行Azure AD身份验证):::process
H --> I(创建条形码控制器):::process
I --> J(创建订单控制器):::process
J --> K(创建供应Windows应用商店应用程序):::process
K --> L(配置应用商店应用以进行AD身份验证):::process
L --> M(创建DataServiceBase类):::process
M --> N([结束]):::startend
3.2 多环境配置流程
graph LR
classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px
classDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px
A([开始]):::startend --> B(多环境项目配置):::process
B --> C(网站配置):::process
C --> D(云服务配置):::process
D --> E(敏感信息处理):::process
E --> F(多环境配置策略):::process
F --> G([结束]):::startend
4. 总结与建议
4.1 移动服务开发总结
在移动服务开发过程中,我们涉及了多个方面的操作,包括应用的完成、订单处理器和管理网站的更新、移动服务和应用程序的创建以及身份验证的配置等。每个步骤都有其特定的要求和注意事项,例如在生产环境中谨慎使用调试控制台,避免提前调用登录方法等。同时,通过合理使用NuGet包和配置文件,我们可以更高效地完成开发工作。
4.2 Azure系统生产准备总结
在准备Azure系统用于生产时,多环境项目配置是关键。使用构建服务器可以确保部署的可重现性和版本化,同时要注意网站和云服务的不同配置方式以及敏感信息的处理。为每个环境创建相应的配置可以更好地满足不同环境的需求。
4.3 建议
- 在开发过程中,严格遵循操作步骤和注意事项,确保代码的正确性和稳定性。
- 对于敏感信息,采用安全的存储和管理方式,避免泄露。
- 定期对系统进行测试和监控,及时发现和解决问题。
- 持续学习和关注Azure相关技术的发展,不断优化系统性能和安全性。
通过以上的总结和建议,希望能够帮助开发者更好地进行移动服务开发和Azure系统生产准备工作,确保系统的顺利运行和稳定发展。
超级会员免费看
1398

被折叠的 条评论
为什么被折叠?



