我有一个包含5个步骤的向导,每个步骤都有一个实现IUserAddUpdateStep
Interface
的视图模型。
我的控制器中的操作方法如下所示
[HttpPost]
public ActionResult AddUpdate(IUserAddUpdateStep step)
还有一个
DefaultModelBinder
重写,使ASP.NET知道如何处理IUserAddUpdateStep
并为上述控制器操作方法AddUpdate
的HTTP帖子获取反序列化的具体类型: 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
将加载与IUserAddUpdateStep
类型的具体实现视图模型匹配的.cshtml编辑器模板。此设置非常有效!
然后,我希望在实现
IUserAddUpdateStep
的所有视图模型之间共享一个公共值,我在IUserAddUpdateStep
中添加了common属性: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视图中:
<input type="hidden" id="UserId" value="@(((UserAddUpdateStepBase) currentStep).UserId)"/>
除了
UserId
属性之外,其他所有东西都运行良好,当表单发布到我的控制器方法public ActionResult AddUpdate(IUserAddUpdateStep step)
时,我无法进行反序列化。 UserId
为空。我可以使用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)"/>
目前,我的解决方案是删除抽象基类,并仅在类型为
UserId
的每个具体实现视图模型中实现IUserAddUpdateStep
属性。但是,如果有人对我如何指导ASP.NET正确地反序列化隐藏的输入UserId(该ID映射到我的抽象类的信息)有很好的了解,这将使他们知道这是一个解决方案,那么对此进行解释。 最佳答案
您需要在name
标记上添加input
属性,以在帖子中发送该值。在您的情况下:
<input type="hidden" name="UserId" id="UserId" value="@(((UserAddUpdateStepBase) currentStep).UserId)"/>
关于c# - 如何获取ASP.NET MVC操作方法以解析在接口(interface)中定义并在Abstract类中实现的属性,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41045014/