【问题标题】:How is ASP.NET Core able to convert any type to ActionResult<T> return type of controller actions?ASP.NET Core 如何将任何类型转换为控制器操作的 ActionResult<T> 返回类型?
【发布时间】:2019-04-02 14:47:21
【问题描述】:

我在 ASP.NET Core 2.2 的 WebApi 控制器中有一个简单的操作,如下所示:

[HttpGet("test123")]
public ActionResult<string> Test123()
{
    return new OkResult();
}

这编译得很好,但我想知道OkResult 对象如何转换为ActionResult&lt;string&gt;

这些类有不同的继承链: OkResult -&gt; StatusCodeResult -&gt; ActionResultActionResult&lt;TValue&gt; 只实现IConvertToActionResult 换句话说,ActionResult&lt;string&gt; 不是 OkResult 类的基类型。

如果我手动执行此操作并将代码更改为:

[HttpGet("test123")]
public ActionResult<string> Test123()
{
    var a = new OkResult();
    var b = a as ActionResult<string>;  // Error CS0039

    return b;
}

代码无法编译并出现转换错误:

错误 CS0039:无法通过引用转换、装箱转换、拆箱转换、包装转换或空类型转换将类型“Microsoft.AspNetCore.Mvc.OkResult”转换为“Microsoft.AspNetCore.Mvc.ActionResult”

怎么可能第一个代码有效而第二个无效?如何从没有公共基类型的对象转换返回类型?

【问题讨论】:

标签: c# asp.net-core


【解决方案1】:

以下两个来自ActionResult&lt;TValue&gt;的隐式运算符

/// <summary>
/// Implictly converts the specified <paramref name="value"/> to an <see cref="ActionResult{TValue}"/>.
/// </summary>
/// <param name="value">The value to convert.</param>
public static implicit operator ActionResult<TValue>(TValue value)
{
    return new ActionResult<TValue>(value);
}

/// <summary>
/// Implictly converts the specified <paramref name="result"/> to an <see cref="ActionResult{TValue}"/>.
/// </summary>
/// <param name="result">The <see cref="ActionResult"/>.</param>
public static implicit operator ActionResult<TValue>(ActionResult result)
{
    return new ActionResult<TValue>(result);
}

Source

允许在操作中使用多种返回类型。

[HttpGet("test123")]
public ActionResult<string> Test123() {
    if(someCondition) return "String value"; //<--String
    return Ok(); //<-- OkResult
}

当字符串返回时,ActionResult&lt;TValue&gt;(TValue value) 运算符被调用,返回一个有效的ActionResult&lt;TValue&gt;,反之亦然。

【讨论】:

    【解决方案2】:

    您的第一个示例利用了一个隐式的用户定义类型转换运算符,类似于this

    public static implicit operator ActionResult<TValue>(ActionResult result)
    {
        return new ActionResult<TValue>(result);
    }
    

    您的第二个示例使用as,无法使用隐式转换运算符according to the docs,它:

    ...仅执行引用转换、可空转换和装箱转换。 as 运算符不能执行其他转换,例如用户定义的转换,而应使用强制转换表达式来执行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-26
      • 1970-01-01
      • 2021-04-03
      • 1970-01-01
      • 1970-01-01
      • 2019-04-23
      相关资源
      最近更新 更多