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

时间:2016-03-24 14:37:42

标签: c# http session upload servicestack

我们使用服务堆栈创建了一个小型网站,但是用户上传时遇到了问题。我们发现,当用户使用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

1 个答案:

答案 0 :(得分:4)

好吧,我解决了这个问题:

这里发生的事情是用户上传的文件最后是/ bin / uploads而不是/ uploads。只要/ bin的内容更改了重新启动的App域,这会使会话失效。

此实例中的错误是我使用.MapAbsolutePath()而不是.MapServerPath()