Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Controller returns the type name of the list object instead of contents in the list

Tags:

c#

asp.net-mvc

I have the simple code through which i am trying to return list object from a controllers method and display it on browser. Instead browser displays the type of list as:

System.Collections.Generic.List`1[System.String]

Below is my code:

Controller:

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;
        }
    }
}

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; }
    }
}

Can anyone please let me know where am missing, I want those codes in the testlist to be displayed on the browser instead of the type System.Collections.Generic.List`1[System.String]. I am very new to MVC, Is it possible to return simple list and render it on browser from the controller instead of using a view.

like image 509
Skanda Avatar asked Dec 01 '25 04:12

Skanda


1 Answers

Controller actions does not intended to return POCO objects. You would better return instance of a class, inherited from ActionResult, which is responsible to represent your actual result in HTML in desired way.

For example, if you want to execute some view and render HTML, you would use Controller.View method, which return ViewResult.

It is not clear how you would like to represent your collection, but I guess it could be JSON. In this case you can use default Controller.Json method, or return some custom implementation of ActionResult.

If you return something not inherited from ActionResult, asp.net mvc will try to convert it to string and return converted string as plain text without any modification. This method of ControllerActionInvoker class responsible for handling what you return in your actions. Further code will work only with ActionResult inheritors so if you return not one of them, it will be converted:

/// <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;
}

Type List not overrides ToString method, so it's default implementation is to return full type name. In your case it is System.Collections.Generic.List`1[System.String].

Try something like this:

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);
    }
}

First method will return application/json: ["AA", "BB", "CC"]

Second method will return text/plain: AA,BB,CC

Third method will return text/html, but you have to create view named 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>

Update according to your comments you want to return just some text. See code below. It will return what you want: [AA,BB],[AA,BB],[AA,BB]. Note the result type and the need of manual data serialization.

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);
}

Alternately you can create your own 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);
        }
    }
}

And then use it:

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

I don't know what you task is and why you need to return custom plain text. However I would advise you to use Newtonsoft-based JsonNetResult from this answer. With intendation enabled it will produce pretty readable json. Also it much easy to reuse it for any types of any complexity.

Also, if you need to return data, no any GUI and so on, take a look on ASP.NET Web API.

like image 109
lorond Avatar answered Dec 02 '25 16:12

lorond