c# - 如何获取 ASP.NET MVC 操作方法来解析在接口(interface)中定义并在抽象类中实现的属性

标签 c# asp.net-mvc asp.net-mvc-4 razor

我有一个包含 5 个步骤的向导,每个步骤都有一个实现 IUserAddUpdateStep 的 View 模型Interface .

我的 Controller 中的操作方法如下所示

[HttpPost]
public ActionResult AddUpdate(IUserAddUpdateStep step)

还有一个 DefaultModelBinder覆盖让 ASP.NET 知道如何处理 IUserAddUpdateStep并获取上述 Controller 操作方法的 HTTP post 反序列化的具体类型,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;
        }
    }

我发布了“IUserAddStep”类型的 View 模型,就像在我的 AddUpdate.cshtml 中一样查看:

@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 的具体实现 View 模型相匹配.

此设置一切正常!

然后我希望在所有实现 IUserAddUpdateStep 的 View 模型之间共享一个公共(public)值我将公共(public)属性添加到 IUserAddUpdateStep :

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

然后我的 View 模型继承自一个新的抽象基类而不是 IUserAddUpdateStep :

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

然后具体具体实现View Models类型是这样的:

public class UserAddUpdateOverview: UserAddUpdateStepBase 
{
}

UserAddUpdateOverview 的类型仍然是 IUserAddUpdateStep但现在继承自抽象基类UserAddUpdateStepBase .

最后我添加到我的 AddUpdate.cshtml View ,当然是我的形式:

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

除了 UserId 之外,一切仍然正常属性,当表单发布到我的 Controller 方法时,我无法反序列化 public ActionResult AddUpdate(IUserAddUpdateStep step) . UserId为空。

我可以在 DOM 中使用浏览器 F12 Developer Tools Inspector 查看隐藏的输入值,它是我的 <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)"/>

目前,我的解决方案是删除抽象基类并只实现 UserId每个具体实现中的属性 View 模型类型 IUserAddUpdateStep .但是,如果有人对我如何指导 ASP.NET 正确反序列化映射到我的抽象类的隐藏输入 UserId 有解释,那么知道他们是否是一个解决方案会很棒。

最佳答案

您需要在 input 标签上添加 name 属性以在帖子中发送值。在你的情况下:

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

关于c# - 如何获取 ASP.NET MVC 操作方法来解析在接口(interface)中定义并在抽象类中实现的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41045014/

相关文章:

c# - 搜索全局地址列表/书籍

javascript - 如何同时使用AngularJS作为前端框架和ASP.NET MVC作为后端框架?

javascript - 如何将 Java 脚本移动到自定义文件,然后从 MVC 应用程序调用它?

c# - 在不使用数据库的情况下存储和查询数据的最简单方法是什么?

c# - ASP.NET IIS 用户角色认证

c# - 调用 Activator.GetObject 后检查对象是否存在

asp.net-mvc - ASP.NET MVC DDD 应用程序中的组合根

javascript - 当屏幕中的某些内容发生更改时启用按钮

c# - 如何通过 ADOMD.NET 访问 KPI 值隐藏度量?

javascript - Angularjs:在http请求 header 上设置授权