В чем разница между HttpPostedFile и HttpPostedFileBase [duplicate]

Многие объяснения уже присутствуют, чтобы объяснить, как это происходит и как это исправить, но вы также должны следовать рекомендациям, чтобы избежать NullPointerException вообще.

См. также: A хороший список лучших практик

Я бы добавил, очень важно, хорошо использовать модификатор final. Использование "окончательной" модификатор, когда это применимо в Java

Сводка:

  1. Используйте модификатор final для обеспечения хорошей инициализации.
  2. Избегайте возврата null в методы, например, при возврате пустых коллекций.
  3. Использовать аннотации @NotNull и @Nullable
  4. Быстрое завершение работы и использование утверждений, чтобы избежать распространения нулевых объектов через все приложение, когда они не должен быть пустым.
  5. Сначала используйте значения с известным объектом: if("knownObject".equals(unknownObject)
  6. Предпочитают valueOf() поверх toString ().
  7. Используйте null safe StringUtils StringUtils.isEmpty(null).

9
задан alex 12 December 2014 в 15:23
поделиться

1 ответ

На самом деле это действительно просто. HttpPostedFileBase - это абстрактный класс, используемый исключительно с целью получения. Он использовался так, что некоторые вещи в закрытом классе HttpPostedFile были бы издевательскими.

Однако в реальной жизни HttpPostedFile - это то, что у вас есть для обработки размещенных файлов, и чтобы быть последовательным, был создан HttpPostedFileWrapper. Этот класс обеспечивает реализацию для HttpPostedFileBase путем переноса HttpPostedFile.

Итак, HttpPostedFileBase - это унифицированная абстракция, HttpPostedFile - это класс, представляющий опубликованные файлы, а HttpPostedFileWrapper - это реализация HttpPostedFileBase, которая обертывает HttpPostedFile. Реализация свойства ContentType для HttpPostedFileWrapper считывает тип содержимого из подкласса HttpPostedFile.

EDIT: какое-то объяснение

ASP.NET MVC получил файл, а где-то в глубине ниже он создал экземпляр HttpPostedFile, так как это работает с .NET Framework 1.0. Определение HttpPostedFile выглядит следующим образом:

public sealed class HttpPostedFile

, который в основном означает, что он не может быть унаследован и не может быть посмеялся за модульное тестирование.

Чтобы устранить эту проблему ASP. NET MVC разработчики создали макет абстракции - HttpPostedFileBase, который определяется следующим образом:

public abstract class HttpPostedFileBase

Итак, теперь вы можете определить свои действия MVC, чтобы они принимали HttpPostedFileBase, а не un-mockable HttpPostedFile:

[HttpPost]
public ActionResult PostFile(HttpPostedFileBase file)
{
    // some logic here...
}

Проблема в том, что где-то глубоко внизу, единственный способ представить опубликованный файл - это хороший старый жесткий HttpPostedFile. Поэтому, чтобы поддержать эту абстракцию, разработчики MVC создали декоратор под названием HttpPostedFileWrapper, который выглядит примерно так:

public class HttpPostedFileWrapper : HttpPostedFileBase
{
    private HttpPostedFile _httpPostedFile;    

    public HttpPostedFileWrapper(HttpPostedFile httpPostedFile) { 
        _httpPostedFile = httpPostedFile;
    }

    public string ContentType { get { return _httpPostedFile.ContentType; } }

    // implementation of other HttpPostedFileBase members
}

Итак, теперь HttpPostedFileWrapper - это то, что вы на самом деле получаете при выполнении реального HTTP-запроса POST с опубликованным файлом. Благодаря полиморфизму вы можете передать экземпляр производного класса - HttpPostedFileWrapper - к методу, принимающему базовый класс - HttpPostedFileBase.

Все это время вы можете создать свою собственную макетную реализацию, которая, например, будет выглядеть как видео файл публикуется. Вы сделали бы это так

public class MockPostedVideoFile : HttpPostedFileBase
{
    public string ContentType { get { return "video/mp4"; } }

    // rest of implementation here
}

ДРУГОЕ ИЗМЕНЕНИЕ: Фактическое создание HttpPostedFile обрабатывается System.Web для вас. Связывание ASP.NET MVC довольно разумно в отношении данных о форме. Он автоматически обнаруживает, что определенные значения сообщений фактически являются байтами файла, поэтому для правильного их представления он может использовать что-то старое из фреймворка System.Web для создания экземпляра HttpPostedFile.

Главное, - вам не нужно беспокоиться об этом. Здесь есть много вещей, и нам действительно нужно быть благодарными команде ASP.NET MVC за то, что они абстрагировали все эти низкоуровневые вещи.

Единственное место, где вам нужно беспокоиться об этом - это модульное тестирование. В своем тесте вы можете просто вызвать свое действие с помощью макетной реализации, например:

myController.PostFile(new MockPostedVideoFile())
15
ответ дан lawliet29 19 August 2018 в 07:56
поделиться
  • 1
    Я * думаю, что понимаю с точки зрения ... реализации. Но как они "создали" это? Как создать абстрактный класс, который показывает другой класс-оболочку, когда вы его проверяете / реализуете? – Beakie 23 July 2014 в 14:04
  • 2
    Это просто полиморфизм в расцвете сил :) Ну, с точки зрения использования, вы можете иметь экземпляр производного класса, где вы ожидаете базовый класс. Таким образом, ASP.NET MVC облегчает вам задачу, позволяя ожидать базовый класс, так что для модульного тестирования могут быть созданы различные реализации. В реальной жизни, однако, HttpPostedFileWrapper - это реализация, которую вы, скорее всего, получите. – lawliet29 23 July 2014 в 14:07
  • 3
    Мне нужно увидеть пример этого, чтобы понять. Это то, чего я никогда не сталкивался. Не могли бы вы ПОЛУЧИТЬ пример с кодом для 3 минимальных классов (MyHttpPostedFile, MyHttpPostedFileBase и MyHttpPostedFileWrapper), которые объясняли бы (в форме кода), что здесь происходит? Полиморфизм (как я знаю) требует, чтобы один объект был основой другого. Это не относится к этим объектам? – Beakie 23 July 2014 в 14:12
  • 4
    См. Выше ответ. – Beakie 23 July 2014 в 14:45
Другие вопросы по тегам:

Похожие вопросы: