有关ActionResult的文档告诉我们可以从action方法返回任何对象,并选择ActionResult的框架选择右下划线来执行它。
https://msdn.microsoft.com/en-us/library/system.web.mvc.actionresult(v=vs.118).aspx
您可以创建返回任何类型对象的操作方法,例如字符串,整数或布尔值。这些返回类型在呈现给响应流之前包装在适当的ActionResult类型中。
问题是所有可能的以及选择一个的规则。
以下代码不会导致编译错误。
public ActionResult MyAction()
{
return new MyClass(); //not inherited from ActionResult
}
我试图在Asp Mvc源代码中找到答案,希望找到隐含的转换操作符,声明从对象转换为ActionResult但是我失败了。
也许某人更幸运,可以解释一下发生了什么。
答案 0 :(得分:2)
问题是如何做到这一切以及选择一个的规则。
不是,你应该点击F5 / F6(编译/重建)。
以下代码不会导致编译错误。
The following code will never compile.
public ActionResult MyAction()
{
return new MyClass(); //not inherited from ActionResult
}
例外:
无法将类型'HelloWorldMvcApp.MyClass'隐式转换为'System.Web.Mvc.ActionResult'
您需要再次阅读:
您可以创建返回任何类型的对象的操作方法 ,例如字符串,整数或布尔值。这些返回类型在呈现给响应流之前包装在适当的ActionResult类型中。
它没有声明MVC框架会自动为你包装它,它说明你可以在一个包装的ActionResult中返回任何对象,这是所有ActionResult返回类型所做的。这绝对是措辞不好,MVC没有做任何关于允许方法返回与其签名(当前)不匹配的类型的魔法。
您可以创建自己的操作结果,例如XmlResult。
答案 1 :(得分:0)
例如,您可以返回JSON对象而不是ActionResult。
你错过了下一个陈述中的观点。在将这些返回类型呈现给响应流之前,将包装在适当的ActionResult类型中。
public JsonResult GetProductDataJson()
{
IEnumerable<Product> data = GetData();
return Json(data, JsonRequestBehavior.AllowGet);
}
JsonResult属于ActionResult类型,因此您可以从Controller返回该类型。
答案 2 :(得分:0)
它清楚地说明了
这些返回类型包装在适当的ActionResult类型中 在它们呈现给响应流之前。
因此您无法直接将对象返回到视图中。它应该包含在View(),Json()或任何其他Helper方法中。
请参阅链接:https://msdn.microsoft.com/en-us/library/dd410269(v=vs.100).aspx
如果要创建您自己的 ActionResult,请创建一个继承自ActionResult类的类。
链接
答案 3 :(得分:0)
正如文档所说,您可以从操作方法返回任何类型。您需要适当地声明方法,以便编译:
public MyClass MyAction()
{
return new MyClass();
}
您可以将方法声明为返回object
,它仍然是MVC框架乐意调用的有效操作方法。
当您返回无法转换为ActionResult
的内容时,会将其转换为String
(如果不为空)并在Content
上设置为ContentResult
;您的返回值的String
表示将直接发送给客户端。 CreateActionResult
类的ControllerActionInvoker
方法处理此问题:
protected virtual ActionResult CreateActionResult(ControllerContext controllerContext, ActionDescriptor actionDescriptor, object actionReturnValue)
{
if (actionReturnValue == null)
{
return new EmptyResult();
}
ActionResult actionResult = (actionReturnValue as ActionResult) ??
new ContentResult { Content = Convert.ToString(actionReturnValue, CultureInfo.InvariantCulture) };
return actionResult;
}
通过创建一个扩展ControllerActionInvoker
并实现所需行为的类,可以覆盖此行为(这是我试图找出当我遇到此问题时该怎么做)。然后覆盖控制器中的CreateActionInvoker
方法或指定ActionInvoker属性:
public class MyActionInvoker: ControllerActionInvoker
{
protected override ActionResult CreateActionResult(ControllerContext controllerContext, ActionDescriptor actionDescriptor, object actionReturnValue)
{
// Your behaviour
}
}
public class MyController: Controller
{
protected override void Initialize(RequestContext requestContext)
{
ActionInvoker = new MyActionInvoker();
}
protected override IActionInvoker CreateActionInvoker()
{
return new MyActionInvoker();
}
}