1

私はこれに対する答えを探してみましたが、一日の大半で立ち往生していたので、ここの良い人たちが私を助けてくれるかもしれないと思いました!

インデックス ページにリストする Monitor オブジェクトのリストがあります。各モニターには、詳細ページに表示する詳細情報があります。私が抱えている問題は

public List<KeyValuePair<int, int>> FaxcomMonitorData { get; set; }

下に示された。

監視クラス:

[DataContract]
public class Monitor
{
    [DataMember]
    public string MonitorType { get; set; }

    [DataMember]
    public string AtlasMonitorHeader { get; set; }

    [DataMember]
    public string AtlasMonitorData { get; set; }

    [DataMember]
    public List<KeyValuePair<int, int>> FaxcomMonitorData { get; set; }

    (...other attributes here...)

}

モニターには、ATLAS と FAXCOM の 2 種類があります。それらがどちらであるかに応じて、それぞれのデータ属性が適切な値で更新され、もう一方は null のままになります。(つまり、Atlas には AtlasMonitorHeader があり、Data は null ではありませんが、FaxcomMonitorData は null です)

インデックス アクション結果:

public ActionResult Index() 
    {
        MonitorServiceClient client = null;
        List<Monitor> monitors = null;
        try
        {
            client = new MonitorServiceClient("BasicHttpBinding_IMonitorService");
            monitors = new List<Monitor>(client.GetMonitors());
            if (monitors.Any(x => x.Status.Equals("red")))
                ViewData["OverallStatus"] = "red";
            else
                ViewData["OverallStatus"] = "green";
        }
        catch (Exception ex)
        {
            if (null != client)
                client.Abort();
        }
        return View(monitors);
    }

モニターのリストがここに来ると、リスト内のモニターは見栄えがします! KeyValuePair には正しい値があり、すべて問題ありません。

インデックス ビュー:

<div id="overallstatus">
    <table style="border-style:none">
        <tr>
            <td style="vertical-align:middle; font-size:30px; color:Black; border-style:none" >Overall Status:</td>
            <td style="border-style:none" >
                <% if (ViewData["OverallStatus"].Equals("red")) { %>
                    <img src="../../../Content/Images/RedStoplightRG.png" alt="" height="60px" width="140px"/>
                <% } %>
                <% else if (ViewData["OverallStatus"].Equals("green")) { %>
                    <img src="../../../Content/Images/GreenStoplightRG.png" alt="" height="60px" width="140px"/>
                <% } %>
            </td>
        </tr> 
    </table>
</div>

<br />
<br />

<table>
    <tr>
        <th></th>
        <th>
            Monitor
        </th>
        <th>
            Current Status
        </th>
        <th>
            Last Update
        </th>
    </tr>

<% foreach (var item in Model) { %>
    <tr>
        <td>
            <%: Html.ActionLink("Details", "Details", item)%>
        </td>
        <td>
            <%: item.MonitorName %>
        </td>
        <td>
            <% if (item.Status.Equals("green")) { %>
                <img alt="" src="../../../Content/Images/GreenStoplightRG.png" height="40px" width="95px"/> 
            <% } %>
            <%-- <% else if (Model.CurrentStatus.Equals("red")) { %>
                <img alt="" src="../../../Content/Images/RedStoplightRG.png" />
            <% } %> --%>
            <% else { %>
                <img alt="" src="../../../Content/Images/RedStoplightRG.png" height="40px" width="95px"/>
            <% } %>
        </td>
        <td>
            <%: String.Format("{0:g}", item.LastUpdated) %>
        </td>
    </tr>

<% } %>

</table>

ここの一番下の表には、各モニターといくつかのデータが表示されます。詳細ハイパーリンクをクリックすると、このコントローラー メソッドに移動します。

詳細アクション結果:

public ActionResult Details(Monitor monitor)
    {
        if (monitor.MonitorType.Equals("ATLAS"))
            return RedirectToAction("AtlasDetails", monitor);
        if (monitor.MonitorType.Equals("FAXCOM"))
            return RedirectToAction("FaxcomDetails", monitor);

        return RedirectToAction("Index");
    }

ATLAS タイプ (KeyValuePair を持たない) のモニターをクリックすると、すべての属性に問題はありません。

ただし、FAXCOM タイプには、KeyValuePair を除いて、ほとんどの属性が正しく設定されています。オブジェクトが最初に (Index ActionResult で) 受信されたときではありませんでしたが、現在は null です。

ビューで KeyValuePair を null にするために何かをしているとは思いませんが、以前は使用したことがないので、現在とは別の方法で情報を渡す必要があるかもしれません。

追加のコードまたは説明が役立つかどうか教えてください。ありがとうございました!

編集:私はデータベースをまったく使用しておらず、インデックスページで使用するサービスのみが Monitor オブジェクトのリストを提供します。モニターが多いと時間がかかるため、サービスを再度呼び出す (そして待機する) ことは避けたいと思います。

編集: 私たちが試みていたことがうまくいかなかった理由についての fan711 の説明のおかげで、時間の制約のために別の (やや醜い) 回避策を採用することにしました。もっと時間があれば、Jonathan の回答を参考にして、可能であればこれらの優れたコーディング プラクティスに従う必要があります。他の誰かがそれを使用したい場合に備えて、私たちが行ったことを少なくともここに投稿すると思いました.

最終的に、FaxcomMonitorData をコンマとニンジン (, と ^) で区切られた文字列にして、キーをその値から、キー値を他のキー値から分離しました。次に、この文字列を解析し、データを List> に格納しました。

List<KeyValuePair<int,int>> FaxcomData = new List<KeyValuePair<int,int>>();

        List<string> keyvaluepairs = monitor.FaxcomMonitorData.Split('^').ToList();
        foreach (var pair in keyvaluepairs)
        {
            List<string> stringData = pair.Split(',').ToList();
            FaxcomData.Add(new KeyValuePair<int,int>(Convert.ToInt32(stringData[0]), Convert.ToInt32(stringData[1])));
        }

お手伝いありがとう!

4

2 に答える 2

2

「モニター」オブジェクト全体を通過する代わりに、ID を通過し、詳細アクションでオブジェクトを再構築する方がよいでしょうか?

于 2012-07-23T21:25:54.933 に答える
1

ActionLink() の 3 番目の引数は、あなたのケースでは RouteValues です。このパラメーターに複雑なオブジェクトを渡すことはできません。むしろ、ルート値のキー/値のコレクションです。最初のビューの結果の html で、アイテム オブジェクトの各プロパティで .ToString が返されることがわかります。

Jonathan が言ったように、推奨される方法は、サービスから監視オブジェクトをリロードすることです。これが不可能な場合は、オブジェクト全体をフォームにラップし、各プロパティを非表示フィールドとして渡すことができます。何かのようなもの:

<% for (item = 0; item<Model.Count; item++) { %>
    <% using(Html.BeginForm("Details",Nothing, FormMethod.Post)) { %>
        <%= Html.HiddenFor(m => m(item).MonitorType) %>
        <%= Html.HiddenFor(m => m(item).AtlasMonitor) %>
        <%= Html.HiddenFor(m => m(item).AtlasMonitorData) %>
        <% for (var i = 0; i<item.FaxcomMonitorData.Count; i++) { %>
            <% Html.HiddenFor(Function(m) m(item).Data(i).Key) %>
            <% Html.HiddenFor(Function(m) m(item).Data(i).Value) %>
        <% } %>
        <input type="submit" value="Search" />
    <% } %>
<% } %>

ただし、アイテムを部分ビューに配置する必要がある場合があります (このコードはテストしていません)。これは複雑に聞こえるかもしれませんが、MVC はコントローラー アクションからコントローラー アクションにオブジェクトを渡すようには設計されていません。

私が考えることができる別の解決策は、モニター項目をセッション状態に保存することです。次に、インデックスのみを「詳細」アクション メソッドに渡します。セッション状態から取得します。もちろん、これはしばしば推奨されない状態を追加します。

于 2012-07-24T05:15:12.517 に答える