3

私は MVC4 を使用した Web 開発への最初の取り組みの最中にあり、一般的な Web 開発の中心的な問題の 1 つであることがわかっている問題に遭遇しましたが、頭を悩ませているようには見えません。それ。

と の 2 つのモデルが EmployeeありCompanyます。 EmployeeがあるCompanyため/Employee/Create、既存の を選択するためのドロップダウン リストCompany、または存在しない場合はActionLinktoのいずれかであるフィールドが含まれ/Company/Createます。しかし、ここに問題があります。ユーザーが を作成する必要がある場合、両方のビューCompanyで既存のモデルを保持する必要があります。Employee/Company/Create/Employee/Create

したがって、私の最初のアプローチは、Employeeモデルをに渡すことでし/Company/Create@Html.ActionLink("Add...", "Create", "Organization", Model , null)が、その後 に到達すると、すべてのCompanyの値は になります。Create(Employee emp)empnull

2 番目の問題は、 に戻ろうとすると、 Actionに解決さ/Employee/Createれる を返すことになることです。EmployeePOST

基本的には、/Employee/Createページの状態を保存し、 にジャンプしてレコード/Company/Createを作成しCompany、 に戻っ/Employee/CreateEmployee. これには十分に理解された解決策があることは知っていますが、Google の良い結果を得るのに十分な段階に達していないようです。

私はセッションを使用することについて考えましたが、そうするのは少し面倒なようです。これに対するエレガントなソリューションが本当に欲しいです。

編集: この問題に対する標準的な解決策がないとは信じがたいです。これは、HTTP を扱う上で最も基本的な問題の 1 つであると思われます。

4

6 に答える 6

2

したがって、あなたの主な問題は、42 が言ったようにデータ ソースの欠如、またはより一般的にはある種の永続性の欠如であるように見えます。これは、モデルをサポートするデータ ソースとしてデータベースを使用することで実行できます。これは、永続的なソリューションで必要になる可能性が高いものです。別のオプションは、セッションを使用することです。これが本番コードではなく、「機能する」何かが必要な場合は、セッションが迅速な解決策になります。Entity Framework Code First アプローチを検討することをお勧めします (比較的単純で、現在のモデルに基づいてデータベースを作成できるため)。

あなたは MVC を初めて使用するということでしたので、[ASP.NET MVC 4 の概要][1] をお勧めします。初心者向けの非常にわかりやすいチュートリアルです。私もそれから始めました。

編集

ユーザーがページを放棄した場合に後でクリーンアップする必要がある、一種の「一時」エントリを DB に作成するのは奇妙であることに同意します。私が持っているアイデアの 1 つは、ajax を使用することです (通常、jQuery ライブラリの助けを借りてこれを行うのが好きです)。あなたのライブラリに関する知識はわかりませんが、私の基本的な前提は次のようなものです...

  1. ユーザーがいずれかのボタンをクリックします。
  2. コントローラーへの非同期呼び出しを使用して、必要な作業を行い、結果を返します。コントローラー メソッドは、おそらく JSONResult を返す必要があります。
  3. この結果を使用して、ビューを更新します。私の考えは、結果を使用してフォームに入力することです。
  4. これで、ユーザーは「送信」を押して、DB に更新/保存するメソッドに送信されます。

jQuery に慣れていない場合は、試してみることをお勧めします。

jQuery と JsonResult の使用に関する投稿: https://stackoverflow.com/a/9463272/1200520

于 2012-12-07T22:55:58.007 に答える
1

<input type="submit" name"createEmployee" value="Create Employee" />name 属性が POST リクエスト内でパラメーターとして渡され、デフォルトの ModelBinder がそれをバインドすることをご存知ですか?

つまり、1 つのフォームに複数の送信ボタンを配置できます。

次のような ViewModel があるとします。

public class CreateCompanyWithEmployeeModel
{
public Employee Employee { get; set; }
public Company Company { get; set; }

public string createEmployee { get; set; }
public string createCompany { get; set; }

public string State { get { return (String.IsNullOrEmpty(createCompany)) ? "createEmployee" : "createCompany"; }}
}

もちろん、Employee と Company のカスタム タイプは次のようになります。

public class Employee
{
   // Employee properties here
}

public class Company
{
   // Company properties here
}

次に、次のようなアクションを実行できます。

    public ActionResult CreateCompanyWithEmployee(CreateCompanyWithEmployeeModel model)
    {
        switch (model.State)
        {
            case "createEmployee":
                // Do your createEmployee Stuff
                break;
            case "createCompany":
                // Do your createCompany Stuff
                break;
            default:
                throw new NotImplementedException(String.Format("State {0} not implemented", model.State));
        }
        return View();
    }

ビューでは、次のようなフォームが表示されます。

<% using(Html.BeginForm()) { %>

    <%=(Model.State == "createEmployee") ? Html.EditorFor(Model.Employee) : Html.DisplayFor(Model.Employee) %>
    <%=(Model.State == "createCompany") ? Html.EditorFor(Model.Company) : Html.DisplayFor(Model.Company) %>

    <input type="submit" name="<%=Model.State%>" value="Submit" />

<% } %>

EditorFor次に、状況に応じてandDisplayForコントロールを構築するだけです。会社の作成中に従業員を表示したくない場合はHiddenFor、会社の編集が完了するまで従業員データをフォームに永続化するために使用します。従業員が完全に有効になる前に会社のデータを表示しない場合と同じです。

この例が完全にきれいではないことはわかっていますが、アプローチを明確にするために、このように単純にする必要がありました。基本的に、このアプローチを頻繁に使用する場合は、ViewModel にビューモデルの状態処理を処理するインターフェイスを継承させ、状態などに応じてフォームをレンダリングするカスタム Html ヘルパーを用意します。

私たちはこのアプローチをよく使います。また、世界中のすべてのブラウザで動作します。

于 2012-12-12T09:53:20.487 に答える
0

TempDataを使用して、次のリクエストまでデータを保存できます。http://www.devcurry.com/2012/05/what-is-aspnet-mvc-tempdata.html

POSTリクエストを使用することもできます。これも非常に優れた一般的なソリューションです。

また、ajaxモーダルに会社を追加し、後でドロップダウン値を更新することを検討することもできます。

于 2012-12-11T07:20:29.780 に答える
0

これを実現する唯一の方法は、ある種の永続化戦略を使用することです。どの方法で行うかはあなた次第です。ボリュームが準拠している場合は、InProc セッションをお勧めします。

ここには多くの優れた提案があります. ASP.NET MVC のセッション変数

ここにも抽象的な実装の非常に良い例があります.. http://blogs.planetcloud.co.uk/mygreatdiscovery/post/Abstracting-session-in-ASPNET-MVC.aspx

于 2012-12-07T22:53:54.960 に答える
0

URL (GET リクエスト) でオブジェクトを渡すことはできません。そのため、最初のアプローチでは値がすべて null でした。通常、EmployeeId を使用してパラメーターとして渡し、コントローラーのデータ ソースから Employee オブジェクトを再フェッチします。

だからあなたのリンクは

@Html.ActionLink("Add...", "Create", "Organization", new { id = Model.EmployeeId }, null)

そしてアクションメソッド

public ActionResult Create(int id)
{
  //hit the db to grab the Employee by id
}

これは、asp.net mvc でこのシナリオを処理する一般的な方法です。

于 2012-11-29T20:14:40.260 に答える
0

次のような回避策を講じる必要があります。

  1. EncodedEmployee という名前の文字列プロパティを Company モデルに追加します。
  2. 従業員の作成ビューを現在行っている方法で表示します。ユーザーは「会社の作成」リンクをクリックする場合があります。
  3. ユーザーが「会社の作成」を選択すると、「CreateCompanyFirst」などの名前のアクションが呼び出されることを確認します。このアクションは次のようになります。

    public ActionResult CreateCompanyFirst(Employee emp)
    {
        string jsonemp = Json(emp);
    
        Company emptyCompany = new Company{};
    
        emptyCompany.EncodedEmployee =  jsonemp ;
    
        return View(emptyCompany);
    }
    
  4. 「企業ビューの作成」が表示されたら、EncodedEmployee プロパティを隠しフィールドに保存してください。

  5. 会社を作成するためのアクションが既に実装されていると思います。ここで、このコードを少し変更する必要があります。

    public ActionResult CreateCompany(Company cmp)
    {
        // Save your company
    
        // if cmp.EncodedEmployee  is not null
    
            // De serialize the employee, return View(employee)
    
        // else return what you were returning before
        // (maybe "thanks for creating a company, come back soon")
    }
    
  6. 前と同じようにフィールドが入力された従業員画面に戻ります。

明らかにこれは、ビュー/アクション/ルートが機能していて、魔法の調整を期待または実行していなかったことを意味します。そうでなければ、機能しません。

于 2012-12-13T11:34:40.200 に答える