English 中文(简体)
将参数传递给操作参数的模型绑定器
原标题:
  • 时间:2009-01-08 08:35:19
  •  标签:

我希望直接在操作方法参数上使用我所制作的模型绑定器。例如:

public ActionResult MyAction([ModelBinder(typeof(MyBinder))] string param1)

然而,我需要将一个字符串传递给绑定器本身,所以我想知道你是否可以做一些类似于以下的事情:

public ActionResult MyAction([MyBinder("mystring")] string param1)

可以吗?

最佳回答

不,您不能通过属性声明传递参数。如果您查看ModelBinderAttribute的源代码,您会发现它的构造函数仅接受一个类型参数,没有其他属性,且它是一个密封类。因此,这条路是一个死胡同。

我所知道的将信息传递到ModelBinder的唯一方式是通过FormCollection本身。

但是,您可以创建一个父文件夹类型,并对每个您打算使用的参数值进行子类型划分。这很麻烦,但在您给出的示例中可以使用。

问题回答

是的,这是可能的。你应该创建一个派生自System.Web.Mvc.CustomModelBinder类的类,并重写GetBinder方法。例如,下面是一个实现,除了Type对象外,还需要一个对象数组作为模型绑定器构造函数参数:

public sealed class MyModelBinderAttribute : CustomModelBinderAttribute
{
    /// <summary>
    /// Gets or sets the type of the binder.
    /// </summary>
    /// <returns>The type of the binder.</returns>
    public Type BinderType { get; }
    /// <summary>
    /// Gets or sets the parameters for the model binder constructor.
    /// </summary>
    public object[] BinderParameters { get; }

    /// <summary>
    /// Initializes a new instance of the <see cref="T:System.Web.Mvc.ModelBinderAttribute" /> class.
    /// </summary>
    /// <param name="binderType">The type of the binder.</param>
    /// <param name="binderParameters">The parameters for the model binder constructor.</param>
    /// <exception cref="T:System.ArgumentNullException">The <paramref name="binderType" /> parameter is null.</exception>
    public MyModelBinderAttribute(Type binderType, params object[] binderParameters)
    {
        if (null == binderType)
        {
            throw new ArgumentNullException(nameof(binderType));
        }

        if (!typeof(IModelBinder).IsAssignableFrom(binderType))
        {
            throw new ArgumentException(string.Format(CultureInfo.CurrentCulture,
                "An error occurred when trying to create the IModelBinder  {0} . Make sure that the binder has a public parameterless constructor.",
                binderType.FullName), nameof(binderType));
        }
        this.BinderType = binderType;
        this.BinderParameters = binderParameters ?? throw new ArgumentNullException(nameof(binderParameters));
    }

    /// <summary>Retrieves an instance of the model binder.</summary>
    /// <returns>A reference to an object that implements the <see cref="T:System.Web.Mvc.IModelBinder" /> interface.</returns>
    /// <exception cref="T:System.InvalidOperationException">An error occurred while an instance of the model binder was being created.</exception>
    public override IModelBinder GetBinder()
    {
        IModelBinder modelBinder;
        try
        {
            modelBinder = (IModelBinder)Activator.CreateInstance(this.BinderType, this.BinderParameters);
        }
        catch (Exception ex)
        {
            throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture,
                "An error occurred when trying to create the IModelBinder  {0} . Make sure that the binder has a public parameterless constructor.",
                this.BinderType.FullName), ex);
        }
        return modelBinder;
    }
}

只是一个想法,我正在寻找类似的需求,我想传递一个能够打开的服务。

我想知道您是否可以使用传递到绑定器中的ControllerContext,并通过属性公开服务/属性或任何东西?

只是一个想法,我现在要尝试一下,然后反馈。

Rich (富有)





相关问题
热门标签