Как присвоить значение Orchard ContentPickerField из кода?

Я работаю над сайтом Orchard, который должен иметь возможность использовать некоторые настраиваемые формы для создания новых элементов контента.

Чтобы справиться с этим, я использую контроллер для отображения формы, а затем пытаюсь создать новые элементы контента при отправке обратно, заполняя динамические элементы и затем отправляя их через функцию ContentManagerService Create().

Это работает нормально, пока я не доберусь до поля выбора контента, которое у меня есть как часть моего элемента контента.

В моем проекте у меня есть тип контента «Запись вопроса», который имеет поле «SubmittedBy», которое является полем выбора контента.

Вот что я вижу в ближайшем окне при обработке поста:


    > dynamic q = _questionService.NewQuestion("Why doesn't this work?");
    {Custom.Website.Models.Question}
        base {Orchard.ContentManagement.ContentPart}: {Custom.Website.Models.Question}
        IsNew: true
        OriginalQuestion: "Why doesn't this work?"
        Summary: null
    > q.QuestionRecord
    {Orchard.ContentManagement.ContentPart}
        base {System.Dynamic.DynamicObject}: {Orchard.ContentManagement.ContentPart}
        ContentItem: {Orchard.ContentManagement.ContentItem}
        Fields: Count = 5
        Id: 0
        PartDefinition: {Orchard.ContentManagement.MetaData.Models.ContentPartDefinition}
        Settings: Count = 0
        TypeDefinition: {Orchard.ContentManagement.MetaData.Models.ContentTypeDefinition}
        TypePartDefinition: {Orchard.ContentManagement.MetaData.Models.ContentTypePartDefinition}
        Zones: {Orchard.UI.ZoneCollection}
    > q.QuestionRecord.SubmittedBy
    {Orchard.ContentPicker.Fields.ContentPickerField}
        base {Orchard.ContentManagement.ContentField}: {Orchard.ContentPicker.Fields.ContentPickerField}
        ContentItems: null
        Ids: {int[0]}

Свойство ContentItems доступно только для чтения, а идентификаторы при назначении нового int[] массиву Ids я получаю System.ObjectDisposedException с сообщением: экземпляры не могут быть разрешены, а вложенные времена жизни не могут быть созданы из этого LifetimeScope, поскольку он уже был удален .

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

Спасибо.


person CtrAltDel    schedule 31.07.2013    source источник
comment
Использование непосредственного окна иногда может быть сложным, поэтому кажется, что вы добавляете проблем, используя его в этом случае. Вы можете получить доступ к полю после приведения элемента к динамическому: item.ContentTypeName.FieldName   -  person Bertrand Le Roy    schedule 01.08.2013
comment
Спасибо за ваш ответ. Я могу получить доступ к полю в порядке, будь то через непосредственное окно или код, в данном случае поле SubmittedBy. Я застреваю в том, что поле является частью ContentPickerField, и я не могу найти способ программно присвоить ему значение.   -  person CtrAltDel    schedule 01.08.2013


Ответы (1)


Если у вас есть ссылка на ContentPickerField, вы можете присвоить ему значение с помощью свойства Ids. В примере (при условии, что ваш тип контента имеет часть с именем Question, которая имеет поле с именем SubmittedBy):

var submittedByField = ((dynamic)q.ContentItem).Question.SubmittedBy;
sbmittedByField.Ids = new[] { submittedById };

Как упомянул Бертран, доступ к полю содержимого имеет следующий формат: contentItem.PartName.FieldName. Если вы прикрепили поле к типу напрямую через администратора, имя части будет совпадать с именем типа, следовательно, contentItem.TypeName.FieldName (где TypeName — это имя неявно созданной части).

person Sipke Schoorstra    schedule 02.08.2013
comment
Спасибо, Сипке. Я попробовал приведенный выше код в своем проекте с парой настроек. submitByField получает правильное назначенное ему поле, и я вижу, что его свойства имеют Ids = {int[0]} и нулевой ContentItem. Как только я пытаюсь присвоить собственное значение int[] свойству .Ids, я получаю System.ObjectDisposedException с сообщением: Экземпляры не могут быть разрешены, а вложенные времена жизни не могут быть созданы из этого LifetimeScope, поскольку он уже был удален. . Я использую Orchard 1.7, созданный из репозитория hg. Я делаю что-то не так, думая, что могу присвоить здесь значение, или это ошибка? - person CtrAltDel; 07.08.2013
comment
Обновление. По-прежнему генерируется ObjectDisposedException при назначении .Ids, но впоследствии я заметил в отладчике, что поле Ids все равно содержит новое значение! Я обернул это в try/catch для ObjectDisposedException, и он проходит весь код контроллера. По завершении элемент содержимого имеет правильное значение, сохраненное в этом поле в базе данных. - person CtrAltDel; 07.08.2013
comment
Вот рабочий код int[] contact_ids = new int[] { viewModel.Contact.Id }; var submittedByField = ((dynamic)viewModel.Question.ContentItem).QuestionRecord.SubmittedBy; try { submittedByField.Ids = contact_ids; } catch (System.ObjectDisposedException ex) { /* value still assigned and saved in spite of exception being thrown. */ } - person CtrAltDel; 07.08.2013
comment
Это не должно вызывать исключения. Что кажется странным, так это то, что вы получаете доступ к QuestionRecord непосредственно как к части элемента содержимого. Обычно можно было бы сделать что-то вроде этого (при условии, что ваш элемент контента имеет часть с именем QuestionPart: var submittedByField = ((dynamic)viewModel.Question.ContentItem).QuestionPart.SubmittedBy; - person Sipke Schoorstra; 08.08.2013