MVC5 Portable Area,如何使用消息总线?
MVC5 Portable Area, how do you use message bus?
我花了几个小时阅读了许多不同的示例和文档,以使用 ASP.NET MVC 设置一个可移植区域,目的是共享一个具有多个应用程序身份验证的公共登录页面。我把它们放在一起,到目前为止效果很好,但我遇到的一件事是消息总线的使用。我看到这是主机和便携式组件之间的一种通信方式,但我没有看到如何执行此操作的明确方法。
例如;如果我的便携式登录成功,我如何告诉主机以便它可以做一些事情(设置 cookie、重定向到特定页面等)?另外,如果我想向 Portable 发送一些东西(比如主机应用程序的标题或程序集版本),我该怎么做?我还没有尝试任何东西,因为我似乎找不到完整的例子。
我都弄明白了。有一个 MvcContrib source code archive 我无法下载,因为 Google Chrome 阻止了 .zip 文件,但我可以使用 Internet Explorer 获取它。
以下是根据我的应用程序进行调整后的重要部分。希望这可以帮助某人。我已尽力正确格式化我的答案,这是我第一次在 Whosebug 上发帖:
在便携式 class 库中
使用 ICommandResult 接口创建 LoginResult class
public class LoginResult: MvcContrib.PortableAreas.ICommandResult
{
public bool Success { get; set; }
public string Message { get; set; }
public string Username { get; set; }
}
创建一个 LoginMessage class,它也使用带有 LoginResult 的 ICommandResult 接口。 LoginMessage class 有一个 属性 用于我在 Login.cshtml 视图中使用的 LoginViewModel(它有用户名、密码和视图所需的其他一些字段)
public class LoginMessage : ICommandMessage<LoginResult>
{
public LoginResult Result { get; set; }
public LoginViewModel Input { get; set; }
}
在Login controller的HttpPost action中,创建一个LoginMessage的实例,传入login view的LoginViewModel,用MvcContrib.Bus.Send[=16=发送给Host ]
[HttpPost]
public ActionResult Login(LoginViewModel mdl)
{
// TODO: Do basic auth here first, then send to Host for additional validation
// Create and send message to the Host
var message = new LoginMessage { Input = mdl, Result = new LoginResult() };
MvcContrib.Bus.Send(message);
if (message.Result.Success)
{
// Redirect to defaultUrl set in the Host's web.config
FormsAuthentication.RedirectFromLoginPage(mdl.Username, false);
}
return View("Login", "_Layout", mdl);
}
注意:LoginMessage设置一个新的空LoginResult,然后等待Success。 Success 由主机设置(如下所示)。我这样做是因为某些 Host 应用程序具有仅适用于该应用程序的特定附加逻辑,因此我让 Host 执行它需要的操作,并向 Portable return 通知它是通过还是失败。最终,我将首先在 Portable 中拥有基本的身份验证逻辑,然后让 Host 完成额外的工作,但为了这个示例,我保持简单。
在主机 Web 应用程序中(它引用了我的便携式 dll)
为 Portable.LoginMessage 创建一个处理程序,以便我们可以在主机中读取它。请注意,IsValidLogin 是我最终将执行附加身份验证逻辑以查看用户是否有效的地方
public class LoginHandler : MvcContrib.PortableAreas.MessageHandler<Portable.LoginMessage>
{
public override void Handle(Portable.LoginMessage message)
{
if (IsValidLogin(message.Input.Username, message.Input.Password))
{
message.Result.Success = true;
message.Result.Username = message.Input.Username;
}
else
{
message.Result.Message = "Username or Password was incorrect";
}
}
private bool IsValidLogin(string username, string password)
{
// TODO: Replace with actual authentication
return username.Equals("admin") && password.Equals("password");
}
}
在web.config中,当message.Result.Success时,在我之前描述的控制器中设置Portable将重定向到的defaultUrl是真的。您不需要使用 Forms 身份验证,模式可以设置为 None,但您需要有 defaultUrl 才能正常工作。
<system.web>
<authentication mode="Forms">
<forms loginUrl="~/Portable/Login" defaultUrl="~/Home/Index" />
</authentication>
</system.web>
就是这样!这对我来说是一次很好的锻炼和学习经历。我仍在弄清楚问题的第二部分,我需要先将信息发送到便携式设备(例如应用程序标题和程序集版本),但我认为我可以做几乎相同的事情,但反过来,我发送的地方当我的主机启动时向便携式设备发送 ICommandMessage (global.asax)。
我花了几个小时阅读了许多不同的示例和文档,以使用 ASP.NET MVC 设置一个可移植区域,目的是共享一个具有多个应用程序身份验证的公共登录页面。我把它们放在一起,到目前为止效果很好,但我遇到的一件事是消息总线的使用。我看到这是主机和便携式组件之间的一种通信方式,但我没有看到如何执行此操作的明确方法。
例如;如果我的便携式登录成功,我如何告诉主机以便它可以做一些事情(设置 cookie、重定向到特定页面等)?另外,如果我想向 Portable 发送一些东西(比如主机应用程序的标题或程序集版本),我该怎么做?我还没有尝试任何东西,因为我似乎找不到完整的例子。
我都弄明白了。有一个 MvcContrib source code archive 我无法下载,因为 Google Chrome 阻止了 .zip 文件,但我可以使用 Internet Explorer 获取它。
以下是根据我的应用程序进行调整后的重要部分。希望这可以帮助某人。我已尽力正确格式化我的答案,这是我第一次在 Whosebug 上发帖:
在便携式 class 库中
使用 ICommandResult 接口创建 LoginResult class
public class LoginResult: MvcContrib.PortableAreas.ICommandResult { public bool Success { get; set; } public string Message { get; set; } public string Username { get; set; } }
创建一个 LoginMessage class,它也使用带有 LoginResult 的 ICommandResult 接口。 LoginMessage class 有一个 属性 用于我在 Login.cshtml 视图中使用的 LoginViewModel(它有用户名、密码和视图所需的其他一些字段)
public class LoginMessage : ICommandMessage<LoginResult> { public LoginResult Result { get; set; } public LoginViewModel Input { get; set; } }
在Login controller的HttpPost action中,创建一个LoginMessage的实例,传入login view的LoginViewModel,用MvcContrib.Bus.Send[=16=发送给Host ]
[HttpPost] public ActionResult Login(LoginViewModel mdl) { // TODO: Do basic auth here first, then send to Host for additional validation // Create and send message to the Host var message = new LoginMessage { Input = mdl, Result = new LoginResult() }; MvcContrib.Bus.Send(message); if (message.Result.Success) { // Redirect to defaultUrl set in the Host's web.config FormsAuthentication.RedirectFromLoginPage(mdl.Username, false); } return View("Login", "_Layout", mdl); }
注意:LoginMessage设置一个新的空LoginResult,然后等待Success。 Success 由主机设置(如下所示)。我这样做是因为某些 Host 应用程序具有仅适用于该应用程序的特定附加逻辑,因此我让 Host 执行它需要的操作,并向 Portable return 通知它是通过还是失败。最终,我将首先在 Portable 中拥有基本的身份验证逻辑,然后让 Host 完成额外的工作,但为了这个示例,我保持简单。
在主机 Web 应用程序中(它引用了我的便携式 dll)
为 Portable.LoginMessage 创建一个处理程序,以便我们可以在主机中读取它。请注意,IsValidLogin 是我最终将执行附加身份验证逻辑以查看用户是否有效的地方
public class LoginHandler : MvcContrib.PortableAreas.MessageHandler<Portable.LoginMessage> { public override void Handle(Portable.LoginMessage message) { if (IsValidLogin(message.Input.Username, message.Input.Password)) { message.Result.Success = true; message.Result.Username = message.Input.Username; } else { message.Result.Message = "Username or Password was incorrect"; } } private bool IsValidLogin(string username, string password) { // TODO: Replace with actual authentication return username.Equals("admin") && password.Equals("password"); } }
在web.config中,当message.Result.Success时,在我之前描述的控制器中设置Portable将重定向到的defaultUrl是真的。您不需要使用 Forms 身份验证,模式可以设置为 None,但您需要有 defaultUrl 才能正常工作。
<system.web> <authentication mode="Forms"> <forms loginUrl="~/Portable/Login" defaultUrl="~/Home/Index" /> </authentication> </system.web>
就是这样!这对我来说是一次很好的锻炼和学习经历。我仍在弄清楚问题的第二部分,我需要先将信息发送到便携式设备(例如应用程序标题和程序集版本),但我认为我可以做几乎相同的事情,但反过来,我发送的地方当我的主机启动时向便携式设备发送 ICommandMessage (global.asax)。