我有一个asp.net mvc4 Web应用程序,它使用C#编写的API消耗数据数据,并在Apache / mod_mono的Linux机器上托管
客户端应用程序是用C#/ asp.net编写的 - 它运行在不同的Web服务器上,也就是Linux / Apache / mod_mono。我不确定这些细节在这种情况下是否重要,但我认为任何背景都可能有所帮助。
导致这一问题的问题:AppHostBase instance not set - 帮助我更加了解这一切如何融合在一起。
我认为我现在应该问的正确问题是:一旦我在servicestack中创建会话(在API服务器上),我该如何正确地重新连接它?
根据之前问题的答案,我在客户端应用程序的auth控制器中使用了这段代码:
var authService = AppHostBase.Resolve<AuthService>();
authService.RequestContext = System.Web.HttpContext.Current.ToRequestContext();
var AuthResponse = authService.Authenticate(new Auth
{
provider = "credentials",
UserName = user.user_id,
Password = user.password,
RememberMe = true
});
这会返回一个ResolutionException:
无法解析ServiceStack.ServiceInterface.Auth.AuthService类型的必需依赖项。
在使用asp.net应用程序让客户端工作时,我可能会遗漏一些简单的东西吗?
如果问题太模糊,我会道歉并愿意提供更多信息。
更新
这是AuthController - 请原谅这个混乱,自从我上一篇文章以来,我一直在尝试一些事情:
{
public partial class AuthController : BaseController
{
JsonServiceClient client = new ServiceStack.ServiceClient.Web.JsonServiceClient("<TheAPIurl>");
// GET: /Login/
public ActionResult login()
{
if (Session["IsAuthenticated"] != null)
{
ViewData["Result"] = Session["IsAuthenticated"];
}
return View();
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult login(UserModel user)
{
try
{
var authService = AppHostBase.Resolve<AuthService>();
authService.RequestContext = System.Web.HttpContext.Current.ToRequestContext();
var AuthResponse = authService.Authenticate(new Auth
{
provider = "credentials",
UserName = user.user_id,
Password = user.password,
RememberMe = true
});
if (AuthResponse.SessionId != null)
{
Session["IsAuthenticated"] = true;
Session["UserID"] = AuthResponse.UserName;
Session["jsclient"] = client;
FormsAuthentication.SetAuthCookie(user.user_id, true);
return Redirect("/default");
}
else
{
Session["IsAuthenticated"] = false;
}
}
catch (Exception ex)
{
Session["IsAuthenticated"] = false;
}
return View();
}
protected override void ExecuteCore()
{
throw new NotImplementedException();
}
}
}
答案 0 :(得分:7)
如果ServiceStack实例托管在与MVC相同的App Domain中,您只能从ServiceStack容器中检索自动连接的ServiceStack服务(或其他IOC依赖关系),即:
var authService = AppHostBase.Resolve<AuthService>();
authService.RequestContext = System.Web.HttpContext.Current.ToRequestContext();
虽然推荐的解决其他服务的自动连接实现的代码是:
using (var authAservice = AppHostBase.ResolveService<AuthService>()) {
...
}
即。服务可能会利用应该处置的资源。在ServiceStack服务中,您应该使用base.ResolveService<AuthService>()
。
因此,如果ServiceStack在与MVC相同的AppDomain中托管,您可以调用Service目录,如下所示:
var authResponse = authService.Authenticate(new Auth {
provider = "credentials",
UserName = user.user_id,
Password = user.password,
RememberMe = true
});
否则,如果它是远程的,则需要使用ServiceStack's C# Service Clients之一,例如:
var client = new JsonServiceClient(ServiceStackBaseUrl);
var authResponse = client.Post(new Auth {
provider = "credentials",
UserName = user.user_id,
Password = user.password,
RememberMe = true
});
这将通过将其附加到ss-pid
Cookie来设置与该ServiceClient客户端的经过身份验证的会话(有关详细信息,请参阅Session docs)。您可以通过以下命令将此cookie传递给调用MVC的原始浏览器:
var response = HttpContext.Current.Response.ToResponse();
response.Cookies.AddSessionCookie(
SessionFeature.PermanentSessionId, authResponse.SessionId);
要从MVC中重新连接远程认证的ServiceStack会话,您需要将cookie传回服务客户端,例如:
var cookie = HttpContext.Request.Cookies.Get(SessionFeature.PermanentSessionId);
var client = new JsonServiceClient(ServiceStackBaseUrl);
var cookie = new Cookie(SessionFeature.PermanentSessionId, cookie.Value);
client.CookieContainer.Add(cookie);
您可以在Web.Config中全局设置Cookie域:
<httpCookies domain="mydomain.com" />
或在运行时使用:
cookie.Domain = "mydomain.com";
ServiceStack AuthTests.cs Integration Tests还有一些其他有用的示例,展示了身份验证在ServiceStack中的工作原理。