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

N 层项目,包含 WCF OData 服务、Entity Framework、MVC3.0、Ninject DI、jSOn.net 和 Automapper

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.62/5 (5投票s)

2012年12月10日

CPOL

3分钟阅读

viewsIcon

40778

downloadIcon

2008

N 层应用程序,包含 WCF OData 服务和 Entity Framework。

简要介绍

本文尝试解释可单元测试、解耦、部署灵活的 N 层架构。该架构还将解释 MVC 3.0 中的存储库模式。它还描述了如何使用 Ninject DI 容器注入依赖项,如何使用 Auto mapper 绑定 ViewModel 到 Model,以及如何使用 CSS3.0 媒体查询创建移动就绪的站点。

使用代码

该项目在 Visual Studio 2010 中使用 MVC 3.0 和 Entity Framework 4.1 创建,我还使用了 AutoMapper、jSon.net 和 Ninject 等第三方库。

在继续使用此示例项目之前,您需要遵循以下步骤。

在 SQL Server 中安装 Northwind 数据库(我使用的是 SQL Server Express 2008 R2),您也可以在旧版本中安装 Northwind 数据库。使用此命令(Install-Package Ninject)在 Nuget 包管理器控制台中安装 Ninject DI 容器。使用此命令(Install-Package AutoMapper -Pre)在 Nuget 包管理器控制台中安装 AutoMapper。修改 eShopping UI 项目中 Web.config 文件中的 NorthwindEntities 数据库连接字符串。如果您一切都已正确完成,只需运行项目。

此项目的架构

该项目包含五个层:

  1. eShopping.eShoppingDB 持久层
  2. eShopping.Business 域层或业务层
  3. eShopp.ing.Entities 业务实体层
  4. eShopping UI 层
  5. AuthenticationProvider

AuthenticationProvider (AuthenticationProvider)

我添加了 BasicAuthenticationProvider 类来模拟身份验证功能,如果用户已成功身份验证,则以下方法返回 true,并将当前用户设置为当前 http 上下文中的 IPrincipal

public static bool Authenticate(HttpContext context)
{
    if (!HttpContext.Current.Request.Headers.AllKeys.Contains("Authorization"))
        return false;

    string authHeader = HttpContext.Current.Request.Headers["Authorization"];

    IPrincipal principal;
    if (TryGetPrincipal(authHeader, out principal))
    {
        HttpContext.Current.User = principal;
        return true;
    }
    return false;
}
private static bool TryGetPrincipal(string authHeader, out IPrincipal principal)
{
    var creds = ParseAuthHeader(authHeader);
    if (creds != null && TryGetPrincipal(creds, out principal))
        return true;

    principal = null;
    return false;
}

业务层 (eShopping.Business)

我使用 Data Service Context 类来访问 WCF OData 服务,而 DbSContextDataServiceContext 类的实例。DbSContext 在向 WCF OData 服务发送请求以获取数据时,始终会发送加密的授权标头。我使用 RijndaelManaged 算法加密授权标头。

public static DataServiceContext DbSContext; static GlobalObjects()
{                
     DbSContext = new DataServiceContext(CommonVariables.DbServiceUrl);       
    DbSContext.SendingRequest += newEventHandler<sendingrequesteventargs>(OnSendingRequest);       
}

internal static void OnSendingRequest(object sender, SendingRequestEventArgs e)
{
    var creds = Encryption.EncryptString("Administrator") + 
                     Encryption.EncryptString("SecurePassword"); 
    var bcreds =Encoding.ASCII.GetBytes(creds); 
    var base64Creds = Convert.ToBase64String(bcreds);        
    e.RequestHeaders.Add("Authorization","Basic " + base64Creds); 
}

WCF OData 服务 (eShopping.DataService)

我创建了一个 IHttp Module (BasicAuthenticationModule) 来验证来自业务层的 OData 请求,如果用户名和密码不匹配,服务将返回 **Unauthorized 404** 错误消息。

我在 web.config 文件中注册了此模块(BasicAuthenticationModule)。

<httpModules>
 <add name="BasicAuthenticationModule" 
   type="eShopping.DataService.Authentication.BasicAuthenticationModule"/>
</httpModules>

当 WCF OData 服务接收到请求时,应用程序会调用已注册的模块来验证请求。

public void Init(HttpApplication context)
{
    context.AuthenticateRequest += new EventHandler(context_AuthenticateRequest);
}
#endregion


void context_AuthenticateRequest(object sender, EventArgs e)      
{
     HttpApplication application = (HttpApplication)sender; 
     if(!BasicAuthenticationProvider.Authenticate(application.Context))       
     {              
       application.Context.Response.Status = "401Unauthorized";
       application.Context.Response.StatusCode = 401;
       application.Context.Response.AddHeader("WWW-Authenticate","Basic");
       application.CompleteRequest();
     } 
}

业务实体层 (eShopping.Entities)

我将实体放在一个地方以保持一致性并消除重复。这将有助于在多个项目中共享相同的实体,例如在数据库层、业务层和 UI 层。

UI 层 (eShopping)

我使用 Ninjected DI 作为默认依赖注入器,并使用 Automapper 来使用视图模型映射模型。

我在 Global.asax 文件中注册了 AutoMapper

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);
    ControllerBuilder.Current.SetControllerFactory(new eShoppingControllerFactory());
    InitializeAutoMapper();
}
private void InitializeAutoMapper()
{
    Mapper.CreateMap<customerview,>();
    Mapper.AssertConfigurationIsValid();
}

免责声明 

该项目完全基于我个人的学习、知识和研究,不基于任何其他项目。我使用了 eShopping 之类的术语,但这完全是演示术语,与任何实际工作的项目无关。我使用了 Microsoft Northwind 数据库,它是 Microsoft 公开提供的示例数据库。我没有为 eShopping 实现像购物、查看产品等功能,我的目的是仅描述 N 层架构,以及 ASP.NET MVC3.0 中最常用的开源工具,如 Ninject 和 AutoMapper。我没有在此项目中添加单元测试,所以如果您愿意,可以向此项目添加单元测试。请随时与我联系,以添加更多功能。

© . All rights reserved.