Можете ли вы вернуть проанализированный результат JSONProvider в качестве объекта модели для использования в представлении для MVC?

Итак, у меня есть следующий метод F #

static member ReadInstagramSearch() =
    let data = Http.Request( "https://api.instagram.com/v1/users/search?q=SomeUSer&client_id=someclientid" )
    let res = FsUserSearch.Parse(data)

    res.Data.[0]

Если у меня есть контроллер C#, с которым я вызываю этот метод, можно ли использовать этот результат в представлении? Я пробовал просто простой доступ с

@Model.FirstName

но это дает мне исключение

'FSharp.Data.RuntimeImplementation.JsonDocument' does not contain a definition for 'FirstName'

Является ли мой единственный вариант превратить этот JsonDocument в строго типизированный объект модели? А потом вернуть?

Это использует http://fsharp.github.io/FSharp.Data/library/JsonProvider.html

И мой JsonProvider определяется как

type FsUserSearch = JsonProvider<"""
{
    "data": [{
        "username": "jack",
        "first_name": "Jack",
        "profile_picture": "http://distillery.s3.amazonaws.com/profiles/profile_66_75sq.jpg",
        "id": "66",
        "last_name": "Dorsey"
    }]
}""">

person Shane Neuville    schedule 30.06.2013    source источник


Ответы (1)


К сожалению, на данный момент это не поддерживается. Поставщик типов JSON использует удаленные типы, что означает, что проанализированный документ представлен как значение типа JsonDocument, которое на самом деле не имеет ни одного из членов, которые вы видите в F#. Компилятор F# понимает это, но они отсутствуют в скомпилированном коде, а другие языки на данный момент не поддерживают поставщики типов.

Есть несколько способов исправить это, и это, безусловно, входит в список TODO. (Это немного сложно, реализация ICustomTypeDescriptor будет работать в некоторых сценариях, но не здесь. Генерация фактических типов может быть шагом вперед. Для получения дополнительной информации см. эта ошибка на странице F# Data GitHub.)

На данный момент вы можете использовать операции динамического доступа, предоставляемые библиотекой JSON. Дополнительные сведения см. на странице анализатора и средства чтения JSON. Я думаю, что @Model.FirstName можно было бы сделать, используя:

@Model.GetProperty("FirstName").AsString()

Конечно, не идеально, но, к сожалению, C# не поддерживает поставщиков типов, так что это, вероятно, лучший вариант. Другим обходным решением может быть определение простого типа записи F# и преобразование необходимых данных в тип записи, который затем можно будет легко использовать из C#.

person Tomas Petricek    schedule 01.07.2013
comment
Хорошо, это то, что я понял. Я нахожусь в процессе изучения F #, поэтому мне было любопытно, есть ли функция, о которой я не знал. Я немного попробовал метод расширения, и С#, похоже, они действительно не понравились. Я добавил использование в FSharp.Data.Json.Extensions, и он жаловался на то, что DLL ссылается как в FSharp.Data.DesignTime, так и в dll FSharp.Data. Это расширение отлично работает с F#, но не со стороны C#. Так что я, вероятно, выберу тип записи, но я надеялся быть ленивым :-) Но я думаю, что с моими новыми знаниями F # я могу сделать их быстрее и с меньшими церемониями. Спасибо за быстрый ответ!!! - person Shane Neuville; 01.07.2013
comment
Я думаю, что записи - это самый простой вариант... Что касается DLL, то часть C# должна нуждаться только в FSharp.Data.dll (DesignTime предназначена только для поставщиков типов и вообще не нужна в проекте C#, но, возможно, Visual Studio скопирует ее туда, что может как-то запутать ASP.NET...) - person Tomas Petricek; 04.07.2013
comment
Да, он появился вместе с пакетом nuget, когда я добавил его таким образом... Прекрасно компилируется без него. Записи оказались хорошими, и я также использовал ваши примеры JsonToXML F#, которые очень хорошо сработали для преобразования данных JSON в данные XML, которые я мог хранить в полях XML, так что ура для этого :-) - person Shane Neuville; 29.07.2013