Ошибка страницы ActionResultFilter не найдена

Я разрабатываю веб-сайт с использованием .NET MVC3. У меня есть контроллер, где я делаю загрузку файла клиенту.

    [DeleteFileAfterDownloadFilter()]
    public FileResult DownloadVersion(int VersionID)
    { 
        //staff to get the tempZipFile    
        return File(tempZipFile, "zip", "file.zip"); 
    }

что мне нравится делать, так это удалять файл после загрузки этого файла. Я подумал, что могу использовать ActionFilterAttribute. Итак, я написал класс ниже:

public class DeleteFileAfterDownloadFilter : ActionFilterAttribute
{
    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        string fileName = ((FileStreamResult)filterContext.Result).FileDownloadName;
        File.Delete(fileName);
        base.OnResultExecuted(filterContext);
    }
}

Я думаю, у меня есть 2 проблемы здесь. Во-первых, когда я запускаю эту штуку, она выдает ошибку ".../Company/DownloadVersion?versionID=2057", страница не найдена. Как заставить его работать?

И вторая проблема заключается в том, что, как вы могли понять, "((FileStreamResult)filterContext.Result).FileDownloadName", вероятно, не тот путь к файлу, который я хочу удалить. Это должна быть локальная переменная «tempZipFile» в контроллере. Но я не знаю, как передать это значение этому событию.


person Tolga Evcimen    schedule 05.06.2013    source источник
comment
спасибо за исправления, стало читабельнее.   -  person Tolga Evcimen    schedule 05.06.2013
comment
А ошибка PageNotFound вызвана фильтром (т.е. загрузка идет без него)?   -  person Henk Holterman    schedule 05.06.2013
comment
загрузка не происходит.   -  person Tolga Evcimen    schedule 05.06.2013
comment
неужели никто ничего не знает по этой теме? :( тут застрял..   -  person Tolga Evcimen    schedule 06.06.2013
comment
Вы можете проверить часть имени файла с помощью отладчика или путем регистрации. У нас слишком мало деталей, чтобы понять ошибку маршрутизации.   -  person Henk Holterman    schedule 06.06.2013


Ответы (1)


Я попробовал ваш фильтр, и (после исправления) он выдает неприятную ошибку COM.

Это связано с асинхронным характером операции: OnResultExecuted это ваш последний шанс что-то сделать, но это происходит, когда ответ (с именем файла, но не с самим файлом) был отправлен обратно клиенту. Когда клиент (браузер) затем начинает загрузку, возникает ошибка Not Found или хуже.

Другими словами, ваш подход выглядит красиво, но он не будет работать.

Некоторые грубые идеи для решения:

  • убедитесь, что ваши файлы на стороне сервера имеют уникальные имена и надежную временную метку
  • использовать фоновый процесс для их периодической очистки или
  • очищать старый файл каждый раз, когда готовите новый

Я изменил ваш фильтр следующим образом:

    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {            
        base.OnResultExecuted(filterContext);

        var r = filterContext.Result as FilePathResult; // not FileContent           
        string fileName =
           filterContext.RequestContext.HttpContext.Server.MapPath(r.FileName);            
        System.IO.File.Delete(fileName);
    }

Обновлять :

Благодаря этому ответу SO должно работать следующее:

    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {            
        base.OnResultExecuted(filterContext);

        var r = filterContext.Result as FilePathResult; // not FileContent           
        string fileName =
           filterContext.RequestContext.HttpContext.Server.MapPath(r.FileName);   

        filterContext.HttpContext.Response.Flush();
        filterContext.HttpContext.Response.End();

        System.IO.File.Delete(fileName);
    }
person Henk Holterman    schedule 06.06.2013
comment
Спасибо, а если вокруг метода File.Delete проверить, занят файл или нет? если во время отправки файла клиенту файл остается занятым на стороне сервера, я думаю, мой подход сработает, в противном случае все еще проблема периодически очищать их, так как я не знаю, загружается ли файл все еще или нет. И ожидание загрузки нового файла также не является хорошим подходом, поскольку это приведет к перегрузке моего сервера. потому что файлы, которые необходимо загрузить, могут весить около 2-3 ГБ. Я не хочу их хранить. - person Tolga Evcimen; 06.06.2013
comment
Еще раз спасибо, я думаю, этот метод сброса заставляет ждать завершения загрузки, верно? - person Tolga Evcimen; 06.06.2013
comment
Да, вы можете следить за тайм-аутом. - person Henk Holterman; 06.06.2013
comment
Большое спасибо за помощь. и что мне делать, чтобы обойти ошибку page not found? если вы можете помочь мне с этим тоже, я буду признателен. - person Tolga Evcimen; 07.06.2013
comment
Я понятия не имею. Попробуйте отследить его и лучше задокументировать (маршруты и т. д.). А затем, возможно, опубликовать новый отдельный вопрос. - person Henk Holterman; 07.06.2013