首页 > 解决方案 > 控制器的方法(http get):可选参数不为空

问题描述

我有简单的控制器方法,它接受 Id 和ComplexObject可选的。

我正在id通过 URL 输入带有参数的此方法(下面是 URL 后面的代码),但是当我在该方法中设置断点时,optionalFormData它不为空,而是它是除(Guid)之外的所有 ( , , ) 的FormData实例为空。FirstNameSecondNameFileId

我希望optionalFormData在未发送时为空,而不是作为具有FormData属性null值的实例。

伪代码:

public IActionResult MyView(Guid? id, FormData optionalFormData = null)
{
    if (optionalFormData != null)
    {
        return View(optionalFormData);
    }

    return View(_context.Data.FirstOrDefault(x => x.Id == id.Value));
}


public class FormData
{
    public Guid Id { get; set; }

    public string FirstName { get; set; }

    public string SecondName { get; set; }

    public File File { get; set; }
}

@Html.ActionLink("Enter MyView", "MyView", "MyController", new { id = Model?.Id })

我试过做FormData? optionalFormData,但它需要 C# 8.0

我怎么能在 7.x 上做到这一点?

标签: c#asp.net-coreasp.net-core-mvc

解决方案


对于 Asp.Net Core Model Binding,它会在绑定过程中创建模型实例,并一一设置属性。如果未提供,则无法将模型设置为 null。

对于解决方法,您可以一一检查模型属性,以查看它们是否为不可空值的默认值和可空值的空值。

尝试

public static class Extensions
{
    public static bool IsNullOrDefault(this object obj)
    {
        if (Object.ReferenceEquals(obj, null))
            return true;

        return obj.GetType().GetProperties()
            .All(x => IsNullOrEmpty(x.GetValue(obj)));
    }

    private static bool IsNullOrEmpty(object value)
    {
        if (Object.ReferenceEquals(value, null))
            return true;

        var type = value.GetType();
        return type.IsValueType
            && Object.Equals(value, Activator.CreateInstance(type));
    }
}

并使用如下:

public IActionResult MyView(Guid? id, FormData optionalFormData = null)
{
    if (!optionalFormData.IsNullOrDefault())
    {
        return View(optionalFormData);
    }

    return View(_context.Data.FirstOrDefault(x => x.Id == id.Value));
}

推荐阅读