Отображение данных из одного массива JSON (Azure Cosmos db) с использованием C # ASP.NET MVC - PullRequest
1 голос
/ 08 июля 2019

Я пытаюсь показать данные из Azure Cosmos DB (данные JSON) с помощью веб-приложения C # MVC.Данные JSON вложены, как показано ниже.Я хочу отображать информацию в массиве записей в виде таблицы, используя c # MVC.Я не могу отобразить данные.

Я пытаюсь показать данные из базы данных Azure Cosmos DB (данные JSON).Я проверил несколько постов в сети, которые делают это, но они используют данные Json прямо, а не Azure Jason.Данные JSON вложены, как показано ниже.Я хочу отобразить информацию в массиве Entries ("dateTime": "2019-07-04T00: 00: 00", "precisCode": "showers-rain", "min": 10, "max": 19) в виде таблицыиспользуя c # MVC.Я новичок в Azure и C # MVC Я не могу отобразить данные.Пожалуйста, проверьте код ниже и дайте мне знать, что не так и что можно сделать.

Данные Json:

"id": "302620190704",
    "LocationId": "3026",
    "CreatedAt": "2019-07-04T21:42:53",
    "DateTime": "2019-07-04T00:00:00",
    "Entries": {
        "0": {
            "dateTime": "2019-07-04T00:00:00",
            "precisCode": "showers-rain",
            "min": 10,
            "max": 19
        }
    },
    "_rid": "sklTAKvKt1MBAAAAAAAAAA==",
    "_self": "dbs/sklTAA==/colls/sklTAKvKt1M=/docs/sklTAKvKt1MBAAAAAAAAAA==/",
    "_etag": "\"020002c6-0000-1a00-0000-5d1e906d0000\"",
    "_attachments": "attachments/",
    "_ts": 1562284141
}

Модель:

namespace PelicanboatRamp.Models
{
    public class Weather
    {

        [JsonProperty(PropertyName = "id")]
        public string Id { get; set; }
        [JsonProperty(PropertyName = "DateTime")]
        public DateTime Datetime { get; set; }

        public static DateTime Today { get; }

        [JsonProperty(PropertyName = "LocationId")]
        public string LocationId { get; set; }

        [JsonProperty(PropertyName = "Entries")]
        public Entries entries { get; set; }
    }

    public class Entries
    {
        [JsonProperty(PropertyName = "precisCode")]
        public string Forecast { get; set; }

        [JsonProperty(PropertyName = "min")]
        public int MinTemp { get; set; }

        [JsonProperty(PropertyName = "max")]
        public int MaxTemp { get; set; }
    }
}

Контроллер:

 public class WeatherController : Controller
    {
        // GET: Weather
        [ActionName("Index")]
        public async Task<ActionResult> IndexAsync()

        {
            DateTime thisDay = DateTime.Today;
            var items = await DocumentDBRepository<Weather>.GetWeatherAsync(d => d.Id != null);
            items.Select(t => new Entries
            { Datetime = t.Datetime,
            Forecast = t.entries.Forecast,
            MinTemp = t.entries.MinTemp,
            MaxTemp = t.entries.MaxTemp
            }).ToList();
            return View(items);
        }
    }

DocumentDBRepository:

 public static async Task<IEnumerable<T>> GetWeatherAsync(Expression<Func<T, bool>> predicate)
        {
            IDocumentQuery<T> query = client.CreateDocumentQuery<T>(
                UriFactory.CreateDocumentCollectionUri(DatabaseId, CollectionId),
                new FeedOptions { MaxItemCount = 10, EnableCrossPartitionQuery = true })
                .Where(predicate)
                .AsDocumentQuery();

            List<T> results = new List<T>();
            while (query.HasMoreResults)
            {
                results.AddRange(await query.ExecuteNextAsync<T>());

            }

            return results;
        }
        public static async Task<T> GetWeatherAsync(string LocationId, string id)
        {
            try
            {
                //RequestOptions feedOptions = new RequestOptions { PartitionKey = new PartitionKey(Year) };
                Document document = await client.ReadDocumentAsync(UriFactory.CreateDocumentUri(DatabaseId, CollectionId, id), new RequestOptions { PartitionKey = new PartitionKey(LocationId) });

                return (T)(dynamic)document;
            }
            catch (DocumentClientException e)
            {
                if (e.StatusCode == System.Net.HttpStatusCode.NotFound)
                {
                    return null;
                }
                else
                {
                    throw;
                }
            }
        }


    }

Индекс:

@model IEnumerable<PelicanboatRamp.Models.Weather>

@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Todays Weather</h2>

 @foreach (var item in Model)
    {
        DateTime mydatetime = DateTime.Now;
       <h3>
            DateTime: @mydatetime
        </h3>
        <h3>
            Forecast:@Html.DisplayFor(modelItem => item.entries.Forecast)
        </h3>
        <h3>
            MinTemp:  @Html.DisplayFor(modelItem => item.entries.MinTemp)
        </h3>
        <h3>
            MaxTemp  @Html.DisplayFor(modelItem => item.entries.MaxTemp)
        </h3>

    }

Я хотел бы отобразить: (Текущая дата и прогноз времени: "showers-rain", minTemp: 10, maxTemp: 19

Не отображается прогноз, минимальная температура и максимальная температура

1 Ответ

1 голос
/ 08 июля 2019

Первая проблема

Классы моделей неправильно отражают структуру JSON. Здесь:

"Entries": {
    "0": {
        "dateTime": "2019-07-04T00:00:00",
        "precisCode": "showers-rain",
        "min": 10,
         "max": 19
    }
}

Entries - это объект, который содержит числовой ключ 0, и я думаю, он может содержать 1, 2 и т. Д. Под каждым числовым ключом есть один объект ввода.

Для представления такой структуры в C # мы должны использовать словарь, например, Dictionary<string, Entry> (давайте переименуем Entries в Entry, так как он должен представлять один объект записи). Ниже приведена правильная модель:

public class Weather
{
    // ... other properties

    // this property was declared incorrectly
    [JsonProperty(PropertyName = "Entries")]
    public Dictionary<string, Entry> Entries { get; set; }
}

// renamed from Entries
public class Entry 
{
    // ... properties
}        

Вторая проблема

В представлении модель объявлена ​​как IEnumerable<...>, в то время как вы, похоже, хотите получить доступ к одному экземпляру Weather. Чтобы получить список всех записей из всех Weather объектов, возвращаемых запросом, вы должны зациклить Model следующим образом:

@{
    DateTime mydatetime = DateTime.Now;
    var allEntries = Model.SelectMany(m => m.Entries.Values);
}
@foreach (var entry in allEntries)
{
    <h3>
        DateTime: @mydatetime
    </h3>
    <h3>
        Forecast:@Html.DisplayFor(modelItem => entry.Forecast)
    </h3>
    <h3>
        MinTemp:  @Html.DisplayFor(modelItem => entry.MinTemp)
    </h3>
    <h3>
        MaxTemp  @Html.DisplayFor(modelItem => entry.MaxTemp)
    </h3>
}

Кстати, этот код в вашем контроллере:

items.Select(t => new Entries { 
    Datetime = t.Datetime,
    Forecast = t.entries.Forecast,
    MinTemp = t.entries.MinTemp,
    MaxTemp = t.entries.MaxTemp
}).ToList();

полностью избыточен и не имеет никакого эффекта.

Если вы хотите отобразить только один объект погоды

Затем в представлении измените модель на тип Weather и измените цикл соответственно, как показано ниже:

@model PelicanboatRamp.Models.Weather
@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
@{
    DateTime mydatetime = DateTime.Now;
}
@foreach (var entry in Model.Entries.Values)
{
    <h3>
        DateTime: @mydatetime
    </h3>
    <h3>
        Forecast:@Html.DisplayFor(modelItem => entry.Forecast)
    </h3>
    <h3>
        MinTemp:  @Html.DisplayFor(modelItem => entry.MinTemp)
    </h3>
    <h3>
        MaxTemp  @Html.DisplayFor(modelItem => entry.MaxTemp)
    </h3>
}

В контроллере выберите один Weather объект для передачи в представление:

[ActionName("Index")]
public async Task<ActionResult> IndexAsync()
{
    DateTime thisDay = DateTime.Today;
    var items = await DocumentDBRepository<Weather>.GetWeatherAsync(d => d.Id != null);

    // select a single Weather object according to your business logic
    // for example like this:
    var todaysWeather = items.Single(weather => weather.DateTime.Date == thisDay);

    // pass the single Weather to the view
    return View(todaysWeather);
}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...