0

ユーザーの入力に基づいて、コントローラーのアクションに到達する前に、エンティティのいくつかのプロパティを無効にします。大まかな例(実際のモデルははるかに複雑です)で、クライアントに毎月請求するか隔週請求するかを定義するBillingTypeプロパティがエンティティにあるとします。

public class BillingMethod
{
    public int Id { get; set; }
    public int BillingTypeValue { get; set; }
    public BillingType BillingType
    {
        get
        {
            return (BillingType)BillingTypeValue;
        } 
        set
        {
            BillingTypeValue = (int)value;
        }
    }

    public int? DayOfMonth { get; set; }
    public int? DayOfFirstFortnight { get; set; }
    public int? DayOfSecondFortnight { get; set; }
}

public enum BillingType
{
    Monthly,
    Fortnightly
}

ここで、ユーザーが毎月請求することを選択し、DayOfMonthプロパティを15に設定するとします。次に、気が変わって請求タイプを2週間ごとに設定し、2つの2週間目のプロパティを設定して最後にフォームを送信します。必要なのは、未使用のプロパティ(この例ではDayOfMonth)をコントローラーのアクションに到達する前に無効にする方法です。

ユーザーが請求の種類を変更するとき、またはフォームのonSubmitイベントをインターセプトすることで、JavaScriptを介してこれを実行できることを私は知っています。または、アクション内でも、コンテキストに保存する前に、一度実行して忘れる方法が必要です。

これを行う最良の方法は、カスタムモデルバインダーを使用することだと思いますが、私はそれについての経験がありません。新しいオブジェクトを作成しようとしましたModelBindingContextが、新しいオブジェクト内のフォームデータを取得して解析する方法がわからなかったため、明らかにいくつかの指示が必要です。

4

2 に答える 2

1

カスタムバインダーを使用してオブジェクトを変更することができました。最初にbase.BindModelを呼び出し、次にプロパティを変更してから返します。

public class BillingMethodModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext cContext, ModelBindingContext bContext)
    {
        var newBillingMethod = (BillingMethod)base.BindModel(cContext, bContext);
        var bType = newBillingMethod.BillingTypeValue;
        if (bType == (int)BillingType.Monthly)
        {
            newBillingMethod.DayOfFirstFortnight = null;
            newBillingMethod.DayOfSecondFortnight = null;
        }
        else
        {
            newBillingMethod.DayOfMonth = null;
        }

        return newBillingMethod;
    }
}

そしてもちろん、global.asaxのApplication_Start()にカスタムバインダーを追加します。

ModelBinders.Binders.Add(typeof(BillingMethod), new BillingMethodModelBinder());

それは私にとってはうまくいきました。誰かがより良い解決策を見つけたり、この方法を使用しているときに遭遇する可能性のある問題を指摘したりした場合に備えて、この回答を受け入れる前に1日ほど待ちます

于 2012-12-04T15:36:15.677 に答える
1

カスタムモデルバインダーでこれを行う場合は注意が必要です。遭遇する問題の1つは、各プロパティが個別にバインドされており、順序をあまり制御できないことです。バインドが完了した後、オブジェクトの状態に基づいていくつかの決定を行う必要があるようです。

この場合、おそらくアクションフィルターを使用します。参照: http: //msdn.microsoft.com/en-us/library/system.web.mvc.controller.onactionexecuting (v = vs.98).aspx

public class BillMethodFilterAttribute : ActionFilterAttribute {

     protected override void OnActionExecuting(ActionExecutingContext filterContext) {
        base.OnActionExecuting(filterContext);
           if (filterContext.Controller.ViewData.ModelMetadata.ModelType == typeof(BillingMethod)) {
               var method = filterContext.Controller.ViewData.Model as BillingMethod;
               if (method != null) {
                  //assign appropriately - binding is complete, you have full state of the object
               }
           }
        }        
}

[BillMethodFilter]
public abstract class ProjectController : Controller {


}

public class SomeController : ProjectController {

      public ActionResult SomeAction(BillingMethod method) {
            //before this action runs, the BillMethodFilter should execute and your billing method will be fully initialized correctly
      }
}
于 2012-12-03T17:18:18.957 に答える