5段階のウィザードがあり、各ステップにはIUserAddUpdateStep
Interface
を実装するビューモデルがあります。私のコントローラでインターフェイスで定義され、抽象クラスで実装されたプロパティを解析するための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>
}
あなたはおよそModel
UserAddUpdate
そんなにこの質問のために心配する必要はありません、それだけで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 />
の子である:
私も試してみました:
<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を導くかもしれない方法について解説していれば、彼らが解決策であるかどうかを知るのはすばらしいでしょう。
私は確かに思っていますが、私はあなたが 'input'タグに' id'ではなく 'name'属性を追加して、値を投稿することをお勧めします。 –
@ArturoMenchacaああ、あなたはそれについて正しいです!テスト –
@ArturoMenchacaそれはそれだった! –