【问题标题】:Redirect to post with nancyfx使用 nancyfx 重定向到帖子
【发布时间】:2015-11-03 22:09:19
【问题描述】:

使用 nancyfx 是否可以使用发布数据重定向到另一个方法?

在我的示例中,在用户注册后,我想自动执行登录(我知道还有其他方法可以实现这一点,我可以从 Post["/login"] 中提取代码并从两种方法中调用它,但这是一个普遍的问题,我想知道这是否可能(也许我想重定向到另一个开发人员维护的另一个模块,我不能只提取代码)。

这就是我想做的(伪代码)

return RedirectToModule<LoginModule>()
           .WithFormsValue("username", model.UserName)
           .WithFormsValue("password", model.Password);

这是一个包含两个模块的示例。

public class LoginModule : NancyModule
{
    public LoginModule()
    {
        Get["/login"] = _ => {
            return View["login"]; // return login view
        }
        Post["/login"] = _=> {
            // 1. get model
            var model = this.Bind<LoginViewModel>();
            // 2. perform login
            // ...
            // 3. redirect to home
            return Response.AsRedirect("~/");            
        };
    }
}    
public class RegisterModule : NancyModule
{
    public RegisterModule()
    {
        Get["/register"] = _=> {
            return View["register"]; // return register view
        };
        Post["/register"] = _ => {

              // 1. get model
              var model = this.Bind<RegisterModel>();
              // 2. create new User
              // ...
              // 3. redirect To /login with post data (pseudocode)
              return RedirectToModule<LoginModule>()
                 .WithFormsValue("username", model.UserName)
                 .WithFormsValue("password", model.Password);
        };
    }
}

【问题讨论】:

  • 我为我正在做的一个项目探索了类似的东西,并得出结论,它很容易完成。可以获取IOC容器并创建LoginModule的实例然后直接调用Post["/Login"]方法,但是参数不清楚。我确定的方法是创建第三个类,该类可以从包含常用方法的任一模块实例化。
  • @RonBeyer 我认为您正在做的是正确的方法,而不是调用 HTTP POST 到另一个模块。在可以访问代码库的模块中执行 HTTP POST 是一种过度杀伤,使用 IoC 容器更有意义。关于最初的问题,如果你绝对必须,你可以使用HttpClient 和PostAsync()(不是 NancyFX 特定的),但我不确定你是否可以直接在 Nancy 内部进行。
  • @kha 是的,我确实相信这将是更“正确”的方式,即使实施起来有点困难(不得不打破常规)。这导致我不得不创建一个ILoginManager 接口和一个具体的实现,然后它会更容易一些,因为您不需要专门使用 IoC 容器,您只需将 ILoginManager 添加到构造函数参数并让 IoC小心注射它。
  • 感谢您的建议。 HttpClient 不起作用,因为服务器本身就是客户端,但是从 IOC 容器中获取模块并自己调用该方法可能是一个快速而肮脏的解决方案(我想我必须自己弄清楚如何修改参数以适应我的需求)。

标签: c# nancy


【解决方案1】:

您应该可以使用307 temporary redirect 来做到这一点,但要做到这一点,您必须“手动”设置重定向响应:

public class RegisterModule : NancyModule
{
    public RegisterModule()
    {
        Get["/register"] = _=> {
          return View["register"]; // return register view
        };
        Post["/register"] = _ => {
          // 1. get model
          var model = this.Bind<RegisterModel>();
          // 2. create new User
          // ...
          // 3. redirect To /login with post data (pseudocode)
          return 
              Negotiate
              .WithStatusCode(HttpStatusCode.TemporaryRedirect)
              .WithHeader("Location", "/login");
      };
   }
}

这告诉客户端使用相同的 HTTP 方法和相同的正文(包括表单值)重新向Location 标头中指示的 URL 提交请求。

如果您愿意,可以在 Negotiator 上创建一个扩展来一次性做出此响应:

public Negotiator WithTemporaryRedirect(this Negotiator self, string location) =>
      self.Negotiate
          .WithStatusCode(HttpStatusCode.TemporaryRedirect)
          .WithHeader("Location", "/login");

【讨论】:

  • 但这会重定向到我的Get["/login"] 还是我错过了什么?
  • 307 指示客户端使用与最初使用的相同的 HTTP 方法。那就是客户端执行POST 并获得307 响应它应该 对Location 响应标头中的URL 执行POST。
猜你喜欢
  • 2017-10-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-23
  • 1970-01-01
  • 2016-06-30
  • 1970-01-01
  • 2013-10-02
相关资源
最近更新 更多