将参数传递给动作参数上的modelbinder

时间:2009-01-08 08:35:19

标签: asp.net asp.net-mvc

我希望使用我直接在动作方法参数上创建的模型。如:

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

但是,我需要将一个字符串传递给绑定器本身,所以我想知道你是否可以按照以下方式做一些事情:

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

有可能吗?

3 个答案:

答案 0 :(得分:2)

不,您不能通过属性声明传递参数。如果查看ModelBinderAttribute的源代码,您将看到它的构造函数只接受一个类型参数,它没有其他属性,并且它是一个密封类。所以这条路走到了尽头。

获取我所知道的ModelBinder信息的唯一方法是FormCollection本身。

但是,您可以为您要使用的每个参数值创建父绑定器类型并对其进行子类型化。这很麻烦,但它会在你给出的例子中起作用。

答案 1 :(得分:0)

只是一个想法,我正在考虑需要类似的要求,我想传递一个带石头的服务。

我想知道你是否可以使用传递给Binder的ControllerContext并通过属性公开服务/属性或者转移?

只是一个想法,我现在要尝试这个,我会反馈

答案 2 :(得分:0)

是的,有可能。您应该创建一个由System.Web.Mvc.CustomModelBinder驱动的create类,并覆盖方法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;
    }
}