Сохранение сгенерированных файлов внутри webapp [duplicate]

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

Предположим, у вас есть веб-форма Contact.aspx, чей класс codebehind Свяжитесь с вами, и у вас есть имя объекта Contact.

Затем следующий код вызовет исключение NullReferenceException при вызове context.SaveChanges ()

Contact contact = new Contact { Name = "Abhinav"};
var context = new DataContext();
context.Contacts.Add(contact);
context.SaveChanges(); // NullReferenceException at this line

Ради полноты класса DataContext

public class DataContext : DbContext 
{
    public DbSet Contacts {get; set;}
}

и класс сущности контакта. Иногда классы сущностей являются частичными классами, так что вы можете распространять их и в других файлах.

public partial class Contact 
{
    public string Name {get; set;}
}

Ошибка возникает, когда оба класса entity и codebehind находятся в одном и том же пространстве имен. Чтобы исправить это, переименуйте класс сущности или класс codebehind для Contact.aspx.

Причина. Я все еще не уверен в причине. Но всякий раз, когда какой-либо из классов сущностей расширяет System.Web.UI.Page, возникает эта ошибка.

Для обсуждения рассмотрим NullReferenceException в DbContext.saveChanges ()

8
задан vale4674 15 December 2011 в 13:14
поделиться

5 ответов

Вырезать основную папку проекта скомпилированных подпапок («/ target / classes», «target / test-classes»), и у вас есть основной путь к восстановлению папок проекта с помощью:

import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;

public class SubfolderCreator {

public static void main(String... args) throws URISyntaxException, IOException {
    File newResourceFolder = createResourceSubFolder("newFolder");
}

private static File createResourceSubFolder(String folderName) throws URISyntaxException, IOException {
    java.net.URL url = SubfolderCreator.class.getResource("/EXISTING_SUBFOLDER/");
    File fullPathToSubfolder = new File(url.toURI()).getAbsoluteFile();
    String projectFolder = fullPathToSubfolder.getAbsolutePath().split("target")[0];
    File testResultsFolder = new File(projectFolder + "src/test/resources/" + folderName);
    if (!testResultsFolder.exists()) {
        testResultsFolder.mkdir();
    }
    return testResultsFolder;
}
}
0
ответ дан Emiel Ackermann 27 August 2018 в 17:29
поделиться

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

Если у вас уже загружен файл.

File existingFile = ...;
File parentDirectory = existingFile.getParentFile();
new File(parentDirectory, "newProperties.properties");

В противном случае попробуйте получить дескриптор каталога, который, как вам известно, уникален в вашем каталоге ресурсов. (Не уверен, что это работает)

URL url = this.getClass().getResource("/parentDirectory");
File parentDirectory = new File(new URI(url.toString()));
new File(parentDirectory, "newProperties.properties");
0
ответ дан Lionel Port 27 August 2018 в 17:29
поделиться

Как отмечали другие люди, ресурсы получают через ClassLoader. Однако эти два текущих ответа не смогли подчеркнуть следующие моменты:

  • ClassLoaders предназначены для абстрагирования процесса получения классов и других ресурсов. Ресурс не обязательно должен быть файлом в файловой системе; это может быть удаленный URL-адрес или что-то еще, что вы или кто-то еще может реализовать, расширяя java.lang.ClassLoader.
  • ClassLoaders существуют в цепочке делегирования дочерних / родительских. Обычное поведение для ClassLoader состоит в том, чтобы сначала попытаться получить ресурс от родителя и только затем выполнить поиск его собственных ресурсов, но некоторые загрузчики классов выполняют противоположный порядок (например, в контейнерах сервлетов). В любом случае вам нужно будет определить, какое место загрузчика для получения материала, в которое вы хотите поместить материал, и даже тогда другой вышегрузщик класса выше или ниже может «украсть» запросы ресурсов вашего клиента.
  • Как отмечает Lionel Port, даже у одного ClassLoader может быть несколько местоположений, из которых он загружает вещи.
  • ClassLoaders используются, чтобы загружать классы. Если ваша программа может записывать файлы в место, где загружаются классы, это может легко стать угрозой безопасности, поскольку пользователь может ввести код в ваше запущенное приложение.

Короткий вариант: не делайте этого. Напишите более абстрактный интерфейс для концепции «хранилища ресурсоподобных вещей, из которых я могу получить материал», и subinterface для «хранилища ресурсоподобных материалов, из которых я могу получить материал, а также добавить материал». Внедрите последнее так, чтобы оба использовали ClassLoader.getContextClassLoader().getResource() (для поиска пути к классам), и если это не удается, используется другой механизм для получения информации, которую программа могла добавить из некоторого местоположения.

6
ответ дан Luis Casillas 27 August 2018 в 17:29
поделиться

Следующий код записывается в каталог classes вместе с файлами классов.

Как отмечали другие, остерегайтесь перезаписывать файлы классов. Лучше всего поместить ваши новые файлы в отдельный каталог; однако этот каталог должен уже существовать. Чтобы создать его, создайте подкаталог в ресурсах источника, возможно, содержащий пустой файл. Например, src\main\resources\dir\empty.txt.

public class WriteResource {
    public static void main(String[] args) throws FileNotFoundException {
        String thing = "Text to write to the file";
        String dir = WriteResource.class.getResource("/").getFile();
        //String dir = WriteResource.class.getResource("/dir").getFile();
        OutputStream os = new FileOutputStream(dir + "/file.txt");
        final PrintStream printStream = new PrintStream(os);
        printStream.println(thing);
        printStream.close();
    }
}

Это делает трюк, но я бы нервничал из-за развертывания этого вне строго контролируемой среды. Мне не очень нравится идея несанкционированного доступа к моей директории classes!

0
ответ дан Steve Pitchers 27 August 2018 в 17:29
поделиться

Ресурсы загружаются через загрузчик классов, а загрузчик классов по умолчанию сильно кэшируется.

Для чтения ресурсов из нестатической файловой системы нужен ваш собственный загрузчик классов. / g1]

0
ответ дан Thorbjørn Ravn Andersen 27 August 2018 в 17:29
поделиться
Другие вопросы по тегам:

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