首页 > 解决方案 > 使用 C# ASP.NET MVC 显示来自单个数组 JSON(azure Cosmos db) 的数据

问题描述

我正在尝试使用 C# MVC Web 应用程序显示来自 Azure Cosmos DB(JSON 数据)的数据。Json 数据嵌套如下。我想使用 c# MVC 将 Entries 数组中的信息显示为表格。我无法显示数据。

我正在尝试显示来自 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);
        }
    }

文档数据库存储库:

 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>

    }

我想显示:(当前日期和时间 Forecaste:“showers-rain”,minTemp:10,maxTemp:19

它不显示预测、最低温度和最高温度

标签: c#jsonasp.net-mvcazure-cosmosdb

解决方案


第一个问题

模型类错误地反映了 JSON 结构。这里:

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

Entries是一个包含数字键的对象,0我猜可能包含1,2等。在每个数字键下都有一个条目对象。

为了在 C# 中表示这样的结构,我们应该使用字典,例如Dictionary<string, Entry>(让我们重命名EntriesEntry,因为它应该表示单个条目对象)。下面是正确的模型:

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 对象

然后在视图中,将模型改为 type 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);
}


推荐阅读