文件上传后服务堆栈会话丢失
Service Stack Session Lost After File Upload
我们使用 Service Stack 创建了一个小型网站,但遇到了用户上传问题。我们发现,当用户使用 POST 上传文件时,他们的会话已关闭。
文件的大小似乎无关紧要,响应上传的延迟也无关紧要POST。
我已确认浏览器在上传前后仍在发送相同的会话 ID (ss-id) cookie。
以下是我们处理 AAA 的方式:
public override void Configure(Container container)
{
//Config examples
//this.Plugins.Add(new PostmanFeature());
//this.Plugins.Add(new CorsFeature());
ServiceStack.Text.JsConfig.DateHandler = ServiceStack.Text.DateHandler.ISO8601;
Plugins.Add(new AuthFeature(() => new AuthUserSession(),
new IAuthProvider[] {
new FeedPartnerAuthProvider(), //Custom MSSQL based auth
}
));
//Global response filter to extend session automatically
this.GlobalResponseFilters.Add((req, res, requestDto) =>
{
var userSession = req.GetSession();
req.SaveSession(userSession, slidingExpiryTimeSpan);
});
this.Plugins.Add(new RazorFormat());
}
上传代码如下所示:
//Upload Test Models
[Route("/upload", "POST")]
public class PostUpload : IReturn<PostUploadResponse>
{
public String Title { get; set; }
}
public class PostUploadResponse
{
public String Title { get; set; }
public Boolean Success { get; set; }
}
//Upload Test Service
[Authenticate]
public object Post(PostUpload request)
{
string uploadPath = "~/uploads";
Directory.CreateDirectory(uploadPath.MapAbsolutePath());
var customerFile = Request.Files.SingleOrDefault(uploadedFile =>
uploadedFile.ContentLength > 0 &&
uploadedFile.ContentLength <= 500 * 1000 * 1024);
if (customerFile == null)
throw new ArgumentException("Error: Uploaded file must be less than 500MB");
//determine the extension of the file
String inputFileExtension = "";
var regexResult = Regex.Match(customerFile.FileName, "^.*\.(.{3})$");
if (regexResult.Success)
inputFileExtension = regexResult.Groups[1].Value;
if (inputFileExtension.Length == 0)
throw new Exception("Error determining extension of input filename.");
//build a temporary location on the disk for this file
String outputFilename = "{0}/{1}.{2}".FormatWith(uploadPath, Guid.NewGuid(), inputFileExtension).MapAbsolutePath();
if (File.Exists(outputFilename))
throw new Exception("Unable to create temporary file during upload.");
//Get some information from the session
String ownerId = "Partner_" + this.GetSession().UserAuthId;
//Write the temp file to the disk and begin creating the profile.
try
{
//Move the file to a working directory.
using (var outFile = File.OpenWrite(outputFilename))
{
customerFile.WriteTo(outFile);
}
}
catch (Exception ex)
{
throw new Exception("Error creating profile with uploaded file. ", ex);
}
finally
{
//Clean up temp file no matter what
try { File.Delete(outputFilename); }
catch (Exception delException) { }
}
return new PostUploadResponse
{
Title = request.Title,
Success = true
};
}
文件上传成功,响应正确传回浏览器,但对任何服务的后续调用都会收到 302 重定向到 /login,即使正确的 ss- id 和 sp-pid 作为请求的一部分传输。
是什么导致我的用户会话在我上传文件时结束?
非常感谢!
-Z
好吧,我解决了这个:
这里发生的事情是用户上传的文件以 /bin/uploads 而不是 /uploads 结尾。每当 /bin 的内容更改时,App Domain 都会重新启动,从而使会话无效。
这个例子中的错误是我使用 .MapAbsolutePath() 而不是 .MapServerPath()
我们使用 Service Stack 创建了一个小型网站,但遇到了用户上传问题。我们发现,当用户使用 POST 上传文件时,他们的会话已关闭。
文件的大小似乎无关紧要,响应上传的延迟也无关紧要POST。
我已确认浏览器在上传前后仍在发送相同的会话 ID (ss-id) cookie。
以下是我们处理 AAA 的方式:
public override void Configure(Container container)
{
//Config examples
//this.Plugins.Add(new PostmanFeature());
//this.Plugins.Add(new CorsFeature());
ServiceStack.Text.JsConfig.DateHandler = ServiceStack.Text.DateHandler.ISO8601;
Plugins.Add(new AuthFeature(() => new AuthUserSession(),
new IAuthProvider[] {
new FeedPartnerAuthProvider(), //Custom MSSQL based auth
}
));
//Global response filter to extend session automatically
this.GlobalResponseFilters.Add((req, res, requestDto) =>
{
var userSession = req.GetSession();
req.SaveSession(userSession, slidingExpiryTimeSpan);
});
this.Plugins.Add(new RazorFormat());
}
上传代码如下所示:
//Upload Test Models
[Route("/upload", "POST")]
public class PostUpload : IReturn<PostUploadResponse>
{
public String Title { get; set; }
}
public class PostUploadResponse
{
public String Title { get; set; }
public Boolean Success { get; set; }
}
//Upload Test Service
[Authenticate]
public object Post(PostUpload request)
{
string uploadPath = "~/uploads";
Directory.CreateDirectory(uploadPath.MapAbsolutePath());
var customerFile = Request.Files.SingleOrDefault(uploadedFile =>
uploadedFile.ContentLength > 0 &&
uploadedFile.ContentLength <= 500 * 1000 * 1024);
if (customerFile == null)
throw new ArgumentException("Error: Uploaded file must be less than 500MB");
//determine the extension of the file
String inputFileExtension = "";
var regexResult = Regex.Match(customerFile.FileName, "^.*\.(.{3})$");
if (regexResult.Success)
inputFileExtension = regexResult.Groups[1].Value;
if (inputFileExtension.Length == 0)
throw new Exception("Error determining extension of input filename.");
//build a temporary location on the disk for this file
String outputFilename = "{0}/{1}.{2}".FormatWith(uploadPath, Guid.NewGuid(), inputFileExtension).MapAbsolutePath();
if (File.Exists(outputFilename))
throw new Exception("Unable to create temporary file during upload.");
//Get some information from the session
String ownerId = "Partner_" + this.GetSession().UserAuthId;
//Write the temp file to the disk and begin creating the profile.
try
{
//Move the file to a working directory.
using (var outFile = File.OpenWrite(outputFilename))
{
customerFile.WriteTo(outFile);
}
}
catch (Exception ex)
{
throw new Exception("Error creating profile with uploaded file. ", ex);
}
finally
{
//Clean up temp file no matter what
try { File.Delete(outputFilename); }
catch (Exception delException) { }
}
return new PostUploadResponse
{
Title = request.Title,
Success = true
};
}
文件上传成功,响应正确传回浏览器,但对任何服务的后续调用都会收到 302 重定向到 /login,即使正确的 ss- id 和 sp-pid 作为请求的一部分传输。
是什么导致我的用户会话在我上传文件时结束?
非常感谢!
-Z
好吧,我解决了这个:
这里发生的事情是用户上传的文件以 /bin/uploads 而不是 /uploads 结尾。每当 /bin 的内容更改时,App Domain 都会重新启动,从而使会话无效。
这个例子中的错误是我使用 .MapAbsolutePath() 而不是 .MapServerPath()