在ASP MVC中使用隐式运算符将字符串绑定到参数

Glu*_*bus 7 c# asp.net

我四处张望,因此无法找到问题的充分答案。

我有一个包装类,称为这样Title定义

public class Title
{
    private readonly string _title;

    public Title (string title) {
        _title = title;
    }

    public static implicit operator Title(string title)
    {
        return new Title(title);
    }
}
Run Code Online (Sandbox Code Playgroud)

我在ASP MVC项目中使用此类。现在,我定义了一个像这样的控制器:

public ActionResult Add(string title)
{
    //stuff
}
Run Code Online (Sandbox Code Playgroud)

而且效果很好。但是,我希望将发布的字符串值自动绑定到Title构造函数,从而接受a Title 而不是a string作为参数:

public ActionResult Add(Title title)
{
    //stuff
}
Run Code Online (Sandbox Code Playgroud)

但是,这不起作用,因为我会收到错误消息: 参数字典包含parameter的空条目,这意味着模型绑定程序无法将字符串绑定到Title参数。

负责发布标题数据的HTML:

<form method="post" action="/Page/Add" id="add-page-form">                
    <div class="form-group">
        <label for="page-title">Page title</label>
        <input type="text" name="title" id="page-title">
    </div>
</form>
Run Code Online (Sandbox Code Playgroud)

我的问题分为两个部分:

1.为什么不可能做到这一点,我希望bodel绑定程序使用定义的隐式运算符来创建Title实例。

2.是否有一种方法可以在不显式创建模型绑定器的情况下仍然完成所需的行为?

Her*_*Kan 6

尽管我来晚了,但是为了涵盖所有可用的选项:您可以实现自己的TypeConverter,如下所示:

public class TitleConverter : TypeConverter
{
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        return sourceType == typeof(string) ? true : base.CanConvertFrom(context, sourceType);
    }

    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    {
        if (value is string)
            return new Title((string)value);

        return base.ConvertFrom(context, culture, value);
    }
}

[TypeConverter(typeof(TitleConverter))]
public class Title
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

如果需要从不同类型实例化您的类,则此方法特别有用

  • 是的,它将“字符串”绑定到“标题”。可以将其视为使用完全不同的基于类型的机制的模型绑定器的替代。尽管它使您可以专注于输入** type **,但是在某些需要控制器或绑定上下文的场景中,您仍然不得不求助于绑定器。 (2认同)

A. *_*esa 5

根据您的问题:

  1. 模型绑定器将调用新的Title()。他不能。然后,他将尝试设置Title属性。他找不到。否,默认联编程序不调用隐式转换。他使用的算法不同。
  2. 不,如果您同意更改模型,则不需要自定义活页夹,根据默认模型活页夹的行为,这是完全错误的。

隐式转换对于Action绑定根本不重要。

默认的模型绑定器采用了一个很大的值字典,该值字典是从请求的各个部分收集来的,并尝试将它们插入属性中。

因此,如果您想将Title用作Action参数,那么最好的选择是使Title类对Binder友好,可以这么说:

/* We call the class TitleModel in order not to clash
 * with the Title property.
 */
public class TitleModel
{
    public string Title { get; set; }

    /* If you really need the conversion for something else...
    public static implicit operator Title(string title)
    {
        return new Title { Title = title };
    }
    */
}
Run Code Online (Sandbox Code Playgroud)

一切都应该在客户端上正常进行。

如果您不能(或不想)更改模型类,则可以选择自定义模型活页夹。但是我不认为您真的需要它。