Controller返回列表对象的类型名称,而不是列表中的内容

Ska*_*nda 3 c# asp.net-mvc

我有简单的代码,我试图从控制器方法返回列表对象,并在浏览器上显示它.相反,浏览器将列表类型显示为:

System.Collections.Generic.List`1[System.String]
Run Code Online (Sandbox Code Playgroud)

以下是我的代码:

控制器:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Net;
using System.Web.Http;
using System.Web.Script.Serialization;
using MvcApplication2.Models;
using Newtonsoft.Json;

namespace MvcApplication2.Controllers
{
    public class CodesController : Controller
    {
        WebClient myclient = new WebClient();

        public IEnumerable<Codes> Get()
        {
            string data = myclient.DownloadString("URL");
            List<Codes> myobj = (List<Codes>)JsonConvert.DeserializeObject(data, typeof(List<Codes>));
            return myobj;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

DataModel中:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace MvcApplication2.Models
{
    public class Codes
    {
        public string hr { get; set; }
        public string ps { get; set; }
    }
}
Run Code Online (Sandbox Code Playgroud)

任何人都可以让我知道丢失的地方,我希望测试列表中的代码显示在浏览器而不是类型上System.Collections.Generic.List`1[System.String].我对MVC很新,是否可以返回简单列表并从控制器在浏览器上呈现它而不是使用视图.

lor*_*ond 5

控制器操作不用于返回POCO对象.你最好返回一个继承自的类的实例ActionResult,它负责以所需的方式用HTML表示你的实际结果.

例如,如果要执行某些视图并呈现HTML,则应使用Controller.View返回的方法ViewResult.

目前尚不清楚你想如何代表你的收藏,但我想它可能是JSON.在这种情况下,您可以使用默认Controller.Json方法,或返回一些自定义实现ActionResult.

如果你返回一些不继承的东西ActionResult,asp.net mvc会尝试将其转换为string并将转换后的字符串作为纯文本返回而不做任何修改.这种ControllerActionInvoker类的方法负责处理您在操作中返回的内容.进一步的代码只适用于ActionResult继承者,所以如果你不返回其中一个,它将被转换:

/// <summary>Creates the action result.</summary>
/// <returns>The action result object.</returns>
/// <param name="controllerContext">The controller context.</param>
/// <param name="actionDescriptor">The action descriptor.</param>
/// <param name="actionReturnValue">The action return value.</param>
protected virtual ActionResult CreateActionResult(ControllerContext controllerContext, ActionDescriptor actionDescriptor, object actionReturnValue)
{
  if (actionReturnValue == null)
    return new EmptyResult();
  var actionResult = actionReturnValue as ActionResult;
  if (actionResult == null)
  {
    actionResult = new ContentResult()
    {
      Content = Convert.ToString(actionReturnValue, (IFormatProvider) CultureInfo.InvariantCulture)
    };
  }
  return actionResult;
}
Run Code Online (Sandbox Code Playgroud)

键入Listnot overrides ToString方法,因此它的默认实现是返回完整类型名称.在你的情况下它是System.Collections.Generic.List`1[System.String].

尝试这样的事情:

public class CodesController : Controller
{
    public ActionResult GetListJson()
    {
        var list = new List<string> { "AA", "BB", "CC" };
        return this.Json(list , JsonRequestBehavior.AllowGet);
    }

    public ActionResult GetListText()
    {
        var list = new List<string> { "AA", "BB", "CC" };
        return this.Content(string.Join(",", list));
    }

    public ActionResult GetListView()
    {
        var list = new List<string> { "AA", "BB", "CC" };
        return this.View(list);
    }
}
Run Code Online (Sandbox Code Playgroud)

第一个方法将返回application/json:["AA", "BB", "CC"]

第二种方法将返回text/plain:AA,BB,CC

第三种方法将返回text/html,但您必须创建名为的视图GetListView.cshtml:

@using System.Collections.Generic.List<string>
<!DOCTYPE html>
<html>
<head>
    <title>page list</title>
</head>
<body>
    @foreach(var item in this.Model)
    {
        <p>@item</p>
    }
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

根据您的评论更新,您只想返回一些文字.见下面的代码.它会返回你想要的东西:[AA,BB],[AA,BB],[AA,BB].请注意结果类型和手动数据序列化的需要.

public ActionResult Get()
{
    string data = myclient.DownloadString("URL");
    List<Codes> myobj = (List<Codes>)JsonConvert.DeserializeObject(data, typeof(List<Codes>));

    // Let's convert it into what you want.
    var text = string.Join(",", list.Select(x => string.Format("[{0},{1}]", x.hr, x.ps)));
    return this.Content(text);
}
Run Code Online (Sandbox Code Playgroud)

或者你可以创建自己的ActionResult:

public class CodesResult : ActionResult
{
    private readonly List<Codes> _list;

    public CodesResult(List<Codes> list)
    {
        this._list = list;
    }

    public override void ExecuteResult(ControllerContext context)
    {
        if (context == null)
            throw new ArgumentNullException("context");

        var response = context.HttpContext.Response;

        response.ContentType = "text/plain";
        if (this._list != null)
        {
            // You still have to define serialization
            var text = string.Join(",", this._list.Select(x => string.Format("[{0},{1}]", x.hr, x.ps)));
            response.Write(text);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后使用它:

public ActionResult Get()
{
    string data = myclient.DownloadString("URL");
    List<Codes> myobj = (List<Codes>)JsonConvert.DeserializeObject(data, typeof(List<Codes>));
    return new CodesResult(myobj);
}
Run Code Online (Sandbox Code Playgroud)

我不知道你的任务是什么,为什么你需要返回自定义纯文本.但是我建议你从这个答案使用NewtonsoftJsonNetResult.启用意图后,它将生成非常易读的json.此外,它可以很容易地重用于任何类型的任何复杂性.

此外,如果您需要返回数据,没有任何GUI等,请查看ASP.NET Web API.