0

説明するだけで2時間かかる非常に具体的で厳格なエンドユーザー要件のため、ASP.NETで動的フィールドを使用しています。言うまでもなく、私は要件をなくすことはできません。

とにかく、私には実用的な解決策があります。コントロールのViewStateのロード、レンダリング、または維持に問題はありません。これは私のOnLoadがどのように見えるかです:

public void override OnLoad(EventArgs e){
    //don't need to check IsPostback, we have to load the controls on every POST    
 FormDefinition initialFormDefinition = ServiceLayer.GetFormDefinition(id);
 BuildControls(initialFormDefinition);
}

動的フィールドが必須、無効、またはオプションであるいくつかのbizロジックを実装するには、動的コントロールの投稿された値(つまり、ViewState)を取得してから、実際にページコントロール階層に追加する必要があります。

それは私が推測する鶏が先か卵が先かという問題のようなものです。ASP.NETは、すべてをページに追加するまで、ViewStateを適切な動的コントロールに自動的に関連付けません。一方、サービスレイヤーが現在の値に依存するビジネスルールを適用するまで、これらのコントロールをページに追加することはできません。私はこのかなり不快な問題を回避するために、この疑似コードを少し書いてみました。

public void override OnLoad(EventArgs e){
 FormDefinition initialFormDefinition = ServiceLayer.GetFormDefinition(id);
 BuildControls(initialFormDefinition);
 if (IsPostBack){
  PushControlValuesIntoForm(initialFormDefinition);
  var updatedFormDefinition = ServiceLayer.ApplyBizRules(initialFormDefinition);
  ReBuildControls(updatedFormDefinition); //remove controls and re-add them
 }
}

残念ながら、コントロールをクリアして再度追加すると、コントロールの種類とControlIDがまったく同じであっても、ViewStateが失われるため、このソリューションは無効です。私が求めていることを達成する方法についての合理的なアイデアは大歓迎です!

4

1 に答える 1

1

1 つの方法は、コントロールをロードしてから、フォーム定義を更新する必要があるかどうかを判断し、必要な場合はページのライフ サイクルを再度開始することです。以下のサンプル コードを参照してください。

public void override OnLoad(EventArgs e){

 var updatedFormDef = Context.Items["UpdatedDef"] as FormDefinition;
 if (null != updatedFormDef)
 {
    // Updated form def, rebuild controls
    BuildControls(updatedFormDef);
 } 
 else
 {
    // load initial form def
    var initialFormDefinition = ServiceLayer.GetFormDefinition(id);
    BuildControls(initialFormDefinition);
    // check whether we need to update form def
    if (IsPostBack){
       PushControlValuesIntoForm(initialFormDefinition);
       var updatedFormDefinition = ServiceLayer.ApplyBizRules(initialFormDefinition);
       if (null != updatedFormDefinition)
       {
          // we have to update UI, transfer to self
          Context.Items["UpdatedDef"] = updatedFormDefinition;
          try
          {
              Server.Transfer(this.Request.RawUrl, true);
          }
          catch(ThreadAbortException)
          {
             // Do nothing
          }
       }
 }
}
于 2010-10-22T08:13:22.950 に答える