0

モデルをエクスポートするハイパーリンクをページに作成したいのですが、エクスポートする必要があるモデルごとにメソッドを記述したくありません。モデルをパラメーターの 1 つとして取り、そのモデルでエクスポート ロジックを実行できるメソッドを作成したいと考えています。ビューに送信したモデルをコントローラー アクションに戻す方法はありますか?

編集:

次のコントローラーアクションがあります-

    public ViewResult PenDaily(Nullable<DateTime> startDate = null, Nullable<DateTime> endDate = null, string listName = "")
    {
        //Removed code for brevity/clarity

        PenDailyViewModel penDailyView = new PenDailyViewModel();
        penDailyView.startDate = startDate;
        penDailyView.endDate = endDate;
        penDailyView.listNames = GetLists(m_db);
        penDailyView.penDaily = GeneratePenDaily(m_db, listName, startDate, endDate);
        penDailyView.penSummary = GeneratePenSummary(m_db, startDate, endDate, "").Where(a => a.listName == listName);

        return View(penDailyView);
    }

PenDailyViewModel は、Razor ビューに渡すモデル オブジェクトです。PenDaily と PenSummary はどちらも、結果ページのテーブルで使用される IQueryable オブジェクトです。PenDaily はデータのメイン セットであり、PenSummary はテーブル フッターの合計行に使用されます。

この一連のデータを取得して、ファイルにエクスポートしたいと考えています。そのために書かれた関数がありますが、自分のページからそれを利用する方法がわかりません。ユーザーがハイパーリンクをクリックすると、エクスポートを保存するように求められるように設定したいと思います。

それが役立つ場合、私の Razor ビュー:

@model WebTools.Models.PenDailyViewModel

<table>
    <thead>Header Stuff</thead>
    <tbody>
    @foreach (var item in Model.penDaily)
    {
        //Generate table body
    }
    </tbody>
    <tfoot>
    @foreach (var item in Model.penSummary)
    {
        //Generate table footer
    }
    </tfoot>
</table>
4

2 に答える 2

1

GET個人的には、ビュー (つまり a ) または any に対して常に別々のモデルを作成しますPOSTS

  • IndexViewModel
  • IndexInputModel

多くの場合、これらのポコは非常に似ています。

ここでの秘訣はAutoMapper、左から右へのコード (例: foo = viewmodel.Foo) を大量に使用する代わりに、コードのサポート/保守を容易にするためにおそらく活用することです。

アイデアは次のとおりです。コントローラーで使用される基本クラス ライブラリ オブジェクトがあります。これはメインの POCO オブジェクトです。次に、この POCO のスキーマ/構造に直接関連するビュー モデルと入力モデルがあります。AutoMapper (または、このプログラミングにまだ慣れていない場合は、左から右への多数のコード) を使用すると、関連するオブジェクト間でデータを簡単に「コピー」できます。

例えば。

サンプル ビュー。

ビュー モデル。

public class IndexViewModel
{
    public string Name { get; set; }
    public string Description { get; set; }
    public Uri InfoUrl { get; set; }
}

(View) アクション メソッド (エラー チェックなどを取り除きます)。

// product/{id}   eg /products/5
public Action Index()
{
    // Load the Product.
    var product = YourRepository.Load(id);
    if (product == null)
    {
        return NotFound("Product can't be found.");
    }

    // Convert the product to this view requirements.
    // This will copy over the Name and the Uri.
    var model = Mapper.Map<Product, IndexViewModel>(product);

    return View(model);
}

ここで重要なことは、その 1 つのビューのモデルを明確かつ明確に表現することです。各ビューは一意であるため、各ビューには独自のモデルが必要です。

ここで、「2 つのモデルは必要ありません」と言うかもしれません。まあ、私はあなたがすることをお勧めします。実際、ここには3つのモデルがあります。コントローラー/サービス/ビジネス ロジックの主要な 1 つ。他の 2 つは、入力 (オプション) またはビュー (各アクションには何らかのタイプの結果が必要です) 用です。

アップデート

DBへの複数回の旅行を避けたいとおっしゃいました。フェアコール!:) 秘訣は、代わりにCACHINGを活用することです。クライアントにデータを保存しませんか? なんで?まず、クライアント データを 1 秒でハッキングできます。2nd キャッシュは (一般的に) 安価で (一般的に) 非常に高速です。

初期コードを更新しましょう...

// product/{id}   eg /products/5
public Action Index()
{
    // Load the Product from your cache
    var product = YourCache.Load(id);
    if (product == null)
    {
        return NotFound("Product can't be found.");
    }

    // Convert the product to this view requirements.
    // This will copy over the Name and the Uri.
    var model = Mapper.Map<Product, IndexViewModel>(product);

    return View(model);
}

.. そして、ここにいくつかのサンプル Cache 疑似コードがあります..

public class YourCache
{
    private static ObjectCache cache = MemoryCache.Default; 

    private IRepository Repository { get; set; }

    public YourCache(IRepository repository)
    {
        Repository = repository;
    }

    public Product Load(int id)
    {
        var product = cache["Product-" + id] as Product;
        if (product == null)
        {
            // Grab it and remember it.
            product = repository.Load(id);

            if (product != null)
            {
                cache.Set("Product-" + id, product, ....);
            }
        }

        return product;
    }
}
于 2012-09-16T23:34:38.933 に答える
0

取得したいデータを非表示のフォーム フィールドに渡し、単純なハイパーリンクの代わりにフォームを使用してコントローラーにコールバックします。次に、隠しフィールドからデータを受け取ります。

これは真のページ状態であり、ページ状態と同期していない可能性があるセッション状態ではありません (戻るボタンを使用する、別のタブ/ウィンドウを開くなど)。

とはいえ、クエリが低コスト (したがって高速) であれば、DB へのアクセスは必ずしも悪いことではありません。

于 2012-09-16T23:28:56.390 に答える