文件上载后服务堆栈会话丢失



我们已经使用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的内容发生更改时,应用程序域就会重新启动,从而使会话无效。

这个例子中的错误是我使用了.MapAbsolutePath()而不是.MapServerPath()

最新更新