为什么与结构的模型绑定不起作用?

时间:2019-09-11 15:09:35

标签: asp.net-core asp.net-core-mvc model-binding

我试图了解为什么此绑定不起作用。
直到我将类型从struct更改为class,绑定才起作​​用。
这是设计使然还是我缺少什么?

我正在使用asp.net core 2.2 MVC

查看模型

不起作用

public class SettingsUpdateModel
{
    public DeviceSettingsStruct DeviceSettings  { get; set; }
}

工作

public class SettingsUpdateModel
{
    public DeviceSettingsClass DeviceSettings  { get; set; }
}
public class DeviceSettingsClass
{
    public bool OutOfScheduleAlert { get; set; }
// other fields removed for brevity
}

public struct DeviceSettingsStruct
{
    public bool OutOfScheduleAlert { get; set; }
// other fields removed for brevity
}

控制器

[HttpPost]
public IActionResult Update(SettingsUpdateModel newSettings)
{
    // newSettings.DeviceSettings.OutOfScheduleAlert always false on struct but correct on class
    return Index(null);
}

查看

<input class="form-check-input" type="checkbox" id="out_of_schedule_checkbox" asp-for="DeviceSettings.OutOfScheduleAlert">

预期:DeviceSettings.OutOfScheduleAlert绑定到与类相同的结构 实际:仅绑定了class参数

1 个答案:

答案 0 :(得分:1)

这是设计使然的复杂类型模型绑定。 struct类型是一种值类型,通常用于封装一小组相关变量,例如矩形的坐标或库存中物品的特征。

在ComplexTypeModelBinder.cs中,由于值类型具有按值复制的语义,CanUpdateReadOnlyProperty方法会将value-type模型的属性标记为只读,这会阻止我们进行更新

internal static bool CanUpdatePropertyInternal(ModelMetadata propertyMetadata)
    {
        return !propertyMetadata.IsReadOnly || CanUpdateReadOnlyProperty(propertyMetadata.ModelType);
    }

    private static bool CanUpdateReadOnlyProperty(Type propertyType)
    {
        // Value types have copy-by-value semantics, which prevents us from updating
        // properties that are marked readonly.
        if (propertyType.GetTypeInfo().IsValueType)
        {
            return false;
        }

        // Arrays are strange beasts since their contents are mutable but their sizes aren't.
        // Therefore we shouldn't even try to update these. Further reading:
        // http://blogs.msdn.com/ericlippert/archive/2008/09/22/arrays-considered-somewhat-harmful.aspx
        if (propertyType.IsArray)
        {
            return false;
        }

        // Special-case known immutable reference types
        if (propertyType == typeof(string))
        {
            return false;
        }

        return true;
    }

参考here了解更多详细信息。

BTY,如果要绑定结构类型模型,则可以尝试使用视图中的ajax请求发送json数据。