2

私は次のような価格を計算しようとしています:

@{
    Model.Prices.total =
        ((Input == choice) ? a : b)
    +
        ((AnotherInput == anotherchoice) ? c : d)
    ;
}

これはビューファイル内でうまく機能し.cshtmlますが、言うまでもなく、実際のコードはかなり長くなります(3つのそのような異なる計算を適用したいことは言うまでもありません)。

そこで、次のように呼び出すことができるように、 in呼び出しで@helperファイルを作成することを考えました。App_CodeCalculatePricing.cshtml

@Pricing.Calculate()

ただし、これにより「null参照に対してランタイムバインディングを実行できません」というエラーがスローされます。

エラーが発生しますが、それが制限です。誰かが私がこれを達成するためにどのように行くことができるかを提案できますか?私はクラスファイルについて考えましたが、それを1つに変換する方法がわかりません(それがより良い代替手段である場合)。コードサンプルは非常に高く評価されています。

更新: 私が調査した他のオプションに変換できないため、この計算を一時的にビューに配置していました:

  1. ファイル内の@helper関数App_Code-しかし、これは私が遭遇した「null参照」エラーです。
  2. クラスファイル(または単にViewModelに追加する.csだけですが、コーディングを正しく行うことができません。
  3. それをコントローラーに入れるという提案-しかし、コードは長いです。
  4. カスタムHtmlHelperクラスを作成して、 `@ Html.Calculate([parameter?]、[parameter?])のように呼び出しますが、私にとっては、#2よりも少し複雑です。-コメントはきちんと記されています。

繰り返しになりますが、私が提供した例は、必要最低限​​の単純なものであることに注意してください。複数のオプション(たとえば、上記のa「s」と「」)を使用してそれぞれを探索するための30以上の条件があり、それらのいくつかはより複雑になります。b

() ? a : () ? b : c + () ? d : () ? e : () ? f : g + ....

そして、C#コード(独自の.csファイル、カスタムHtmlヘルパー、またはViewModelのいずれか)を使用すると、間違っているのはすべての宣言です。

念のために言っておきますが、これは私が問題を抱えている実際の計算ではありません。すぐ上のそのスニペットは、私の計算を実行するために機能します。私はそれを上にリストした適切なオプションに到達させるのに苦労しています。

更新2

これを独自のクラスに変換するのに多くの問題があります(私はプログラマーではありません-理解できず申し訳ありません)。これはビュー内の私の関数の一部です(単なるスニペットです。コードサンプルを提供すれば、残りの部分を理解できるといいのですが):

@{
    Model.Price.calculated
        =
        //below is the "base" price, all else would be "add-ons"
        Model.Price.priceOne //elsewhere would be priceTwo, etc.
        +
            ((Model.MyModelOne.MyRadioButtonOne == 
                MyModelOne.RB1Enum.RB1ChoiceOne)
            ?
            Model.Price.AddOnOne
            :
            (Model.MyModelOne.MyRadioButtonOne == 
                MyModelOne.RB1Enum.RB1ChoiceTwo)
            ?
            Model.Price.AddOnTwo
            :
            Model.Price.AddOnThree)
    +
        ((Model.MyModelTwo.MyRadioButtonTwo
            == MyModelTwo.RB2Enum.RB2ChoiceOne)
        ?
        Model.Price.AddOnFour
        :
        (Model.MyModelTwo.MyRadioButtonTwo
            == MyModelTwo.RB2Enum.RB2ChoiceTwo)
        ?
        Model.Price.AddOnFive
        :
        Model.Price.AddOnSix)
    ;
}

を使用するために私のボールをバストしないでくださいenums。:)

繰り返しになりますが、計算はビューで行うのに適切なことではありませんが、上記は機能します-ユーザーの選択に基づいて期待する計算結果が得られます。

私のPrice.csモデル(ここでも、基本的なものなので、アイデアが得られます):

public class Price
{
    //Leaving out [DataType] and [DisplayFormat] DataAnnotations
    // leaving out priceTwo, etc.
    // numbers are basic for simplicity
    public decimal calculated { get; set; }
    public decimal priceOne { get { return 100; } } 
    public decimal AddOnTwo { get { return 10; } } 
    public decimal AddOnThree { get { return 20; } }
    public decimal AddOnFour { get { return 30; } }
    public decimal AddOnFive { get { return 40; } }
    public decimal AddOnSix { get { return 50; } }
    // Others go here
}
4

1 に答える 1

1

Html ヘルパー関数は、ディスプレイの複製された部分を再利用する方法にすぎません。ここで行っているのは、モデルの状態に基づく計算です。MVC では、このデータ処理はモデルの一部と見なされます。

これが私がとる基本的なステップです。

  1. この計算を行うために必要なすべての情報を含むビジネス モデルを取得/作成します。
  2. ビジネスモデルで計算します。計算が内部プロパティのみを使用する 1 つのオブジェクトに基づいている場合は、ビジネス モデル自体に計算コードを含めることができます。それ以外の場合は、それを計算する別の計算クラスを作成します。
  3. 計算結果とビジネスモデルに基づいてViewモデルを作成します。ビューモデルには、ビュー内で表示/編集される状態のみを含める必要があります。

例えば:

public ActionResult YourAction(int userChoice)
{
    MyModel businessModel = createOrFetchModel(); //May be more than one object
    Calculations calcs = new Calculations(businessModel);
    var total = calcs.GetTotal(userChoice);
    MyViewModel viewModel = makeViewModel; //usually I'd use something like AutoMapper here
    return View(viewModel);
}

編集:更新に基づくサンプルコード。実際の計算に基づいて決定する必要がある最終的な設計。

 public class Calculations
 {
     MyModelOne modelOne; //Do you really need seperate models for radio buttons?
     MyModelTwo modelTwo;
     Price Price;

     //...

     public decimal GetTotal()
     {
         decimal total = price.priceOne;
         total += price.FirstAddOn(modelOne);
         total += price.SecondAddOn(modelTwo);
         return total;
     }
 } 

 public class Price
 {
     //...
     public decimal FirstAddOn(MyModelOne modelOne)
     {
       if(modelOne.MyRadioButtonOne == MyModelOne.RB1Enum.RB1ChoiceOne)
          return this.AddOnOne;
       else if(modelOne.MyRadioButtonOne == MyModelOne.RB1Enum.RB1ChoiceTwo)
          return this.AddOnTwo;
       else
         return this.AddOnThree;
     }
 }
于 2012-05-18T14:26:56.040 に答える