2016-12-08 16 views
2

5段階のウィザードがあり、各ステップにはIUserAddUpdateStepInterfaceを実装するビューモデルがあります。私のコントローラでインターフェイスで定義され、抽象クラスで実装されたプロパティを解析するためのASP.NET MVCアクションメソッドを取得する方法

アンアクションメソッドは、ASP.NETがIUserAddUpdateStepに対処し、上記のコントローラのアクションにHTTPの記事のために、逆シリアル化のための具体的な種類を取得する方法を知っているように、この

[HttpPost] 
public ActionResult AddUpdate(IUserAddUpdateStep step) 

そしてDefaultModelBinderオーバーライドのように見えます方法、AddUpdate

public class StepViewModelBinder : DefaultModelBinder 
    { 
     protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) 
     { 
      ValueProviderResult stepTypeValue = bindingContext.ValueProvider.GetValue("StepType"); 
      Type stepType = Type.GetType((string)stepTypeValue.ConvertTo(typeof(string)), true); 
      object step = Activator.CreateInstance(stepType); 
      bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => step, stepType); 
      return step; 
     } 
    } 

私は私のAddUpdate.cshtmlビューのようなタイプのビューモデル "IUserAddStep"、ポスト:

@model UserAddUpdate 

@{ 
    IUserAddUpdateStepcurrentStep = Model.Steps[Model.CurrentStepIndex]; 
} 

@using (Html.BeginForm("AddUpdate", "Employee", FormMethod.Post, new { @role = "form" })) 
{ 
    @Html.Hidden("StepType", currentStep.GetType()) 
    @Html.EditorFor(x => currentStep, null, "") 

    <button type="submit">Submit</button> 
} 

あなたはおよそModelUserAddUpdateそんなにこの質問のために心配する必要はありません、それだけでIUserAddUpdateStepのリストが含まれていますが、ここでそれは

public class UserAddUpdate 
    { 
     public int CurrentStepIndex { get; set; } 
     public IList<IUserAddUpdateStep> Steps { get; set; } 

     public void Initialize() 
     { 
      Steps = typeof(IUserAddUpdateStep) 
       .Assembly 
       .GetTypes() 
       .Where(t => !t.IsAbstract && typeof(IUserAddUpdateStep).IsAssignableFrom(t)) 
       .Select(t => (IUserAddUpdateStep)Activator.CreateInstance(t)) 
       .ToList(); 

     } 
    } 

@Html.EditorForのように見えるもので、特定のステップのために、ロードされます具体的な実装に一致する.cshtmlエディタテンプレートIUserAddUpdateStepのモデルを表示します。

この設定はすべて素晴らしいです!

は、それから私は私がIUserAddUpdateStepに共通するプロパティを追加IUserAddUpdateStepを実装するすべてのビューモデルの間で共有される共通の値を求めていました:

public interface IUserAddUpdateStep 
{ 
    string UserId { get; set; } 
} 

そして、私のビューモデルではなくIUserAddUpdateStepの新しい基本抽象クラスを継承します:

public abstract class UserAddUpdateStepBase: IUserAddUpdateStep 
{ 
    public string UserId { get; set; } 
} 

そしてタイプの特定の具体的な実施のビューモデルは次のようになります。

public class UserAddUpdateOverview: UserAddUpdateStepBase 
{ 
} 

UserAddUpdateOverviewはまだタイプIUserAddUpdateStepですが、抽象基本クラスUserAddUpdateStepBaseから継承しました。

そして最後に、私はもちろん、私の形にして、私のAddUpdate.cshtmlビューに追加:まだUserIdプロパティを除いて素晴らしい作品

<input type="hidden" id="UserId" value="@(((UserAddUpdateStepBase) currentStep).UserId)"/> 

すべてが、私はときに、フォームの投稿をデシリアライズすることを得ることができません私のコントローラのメソッドpublic ActionResult AddUpdate(IUserAddUpdateStep step)UserIdはnullです。

私はDOMでブラウザのF12開発者ツールインスペクタを使用して非表示の入力値を見ることができ、それは私の<form />の子である:

enter image description here

私も試してみました:

<input type="hidden" id="UserAddUpdateStepBase_UserId" value="@(((UserAddUpdateStepBase) currentStep).UserId)"/> 

および:

<input type="hidden" id="UserAddUpdateStepBase.UserId" value="@(((UserAddUpdateStepBase) currentStep).UserId)"/> 

そして:

<input type="hidden" id="IUserAddUpdateStep.UserId" value="@(((UserAddUpdateStepBase) currentStep).UserId)"/> 

そして:

<input type="hidden" id="IUserAddUpdateStep_UserId" value="@(((UserAddUpdateStepBase) currentStep).UserId)"/> 

私のソリューションは、今のところ、抽象基本クラスを削除し、ちょうどタイプIUserAddUpdateStepの各具体的な実施のビューモデルにUserIdプロパティを実装することになります。しかし、もし誰かが私の抽象クラスにマッピングされている私の隠された入力UserIdを正しく逆直列化するようにASP.NETを導くかもしれない方法について解説していれば、彼らが解決策であるかどうかを知るのはすばらしいでしょう。

+1

私は確かに思っていますが、私はあなたが 'input'タグに' id'ではなく 'name'属性を追加して、値を投稿することをお勧めします。 –

+1

@ArturoMenchacaああ、あなたはそれについて正しいです!テスト –

+1

@ArturoMenchacaそれはそれだった! –

答えて

1

name属性をinputタグに追加して、ポストの値を送信する必要があります。あなたの場合:

<input type="hidden" name="UserId" id="UserId" value="@(((UserAddUpdateStepBase) currentStep).UserId)"/> 
関連する問題