Как да върна множество типове обекти за ApiControllers

Надградих проекта си, за да използвам ASP.NET MVC4 от MVC3. Сега моят контролер използва ApiController вместо Controllers. Преди това използвах функция като:

 public JsonResult GetPermissions(string portfolioId)
 {
     //DO THE DATA FETCH
     return Json(new { PermissionValues = permissionValues,       UserPermissions = userPermissions, OwnerValues = ownerList },JsonRequestBehavior.AllowGet);
 } 

Бих искал да направя подобна операция с помощта на ApiControllers. Не искам да създавам отделен обект, където обектът ще има 3 свойства [тъй като връщам 3 списъка]. Опитвах се да използвам HttpResponseMessage<Object> като тип връщане на функцията, но изглежда не работи.

    public HttpResponseMessage<Object> GetPermissions(string portfolioId)
    {
      //DO THE DATA FETCH
      HttpResponseMessage<Object> response = new HttpResponseMessage<Object>(new { Users = listedUsers, PermissionValues = permissionValues });
      return response;
    }

Някакви идеи ?


person Anirban    schedule 24.05.2012    source източник


Отговори (1)


Основният проблем, който имате, е, че сериализаторът по подразбиране за json отговори в бета битовете не може да сериализира анонимни типове. Трябва да използвате средство за форматиране, което може, като например базирано на Json.NET (което ще бъде вградено в следващата капка). За да работи това с бета версията, вашият код ще се промени на нещо подобно:

public HttpResponseMessage Get()
{
    var content = new { Users = new List<string> { "John", "Mary" }, Permissions = new List<string> { "User", "Admin" } };
    return new HttpResponseMessage<object>(content, new[] { new JsonNetFormatter() });
}

Което би дало отговор като този:

{"Users":["John","Mary"],"Permissions":["User","Admin"]}

След като RC е наличен, вашият съществуващ код трябва да работи добре.

Актуализация:

За да може този код да се компилира, имате нужда от реализация за JsonNetFormatter. Можете да намерите внедряване, предоставено от Henrik (MSFT) на http://code.msdn.microsoft.com/Using-JSONNET-with-ASPNET-b2423706#content или от проекта WebApiContrib на https://github.com/WebApiContrib/WebAPIContrib/blob/master/src/WebApiContrib.Formatting.JsonNet/JsonNetFormatter.cs .

Имайте предвид, че и двамата страдат от една и съща грешка в метода OnWriteToStreamAsync. Тези реализации затварят основния поток. Трябва да промените изразите за използване, за да изглеждат така:

using (var jsonTextWriter = new JsonTextWriter(new StreamWriter(stream, Encoding)) { CloseOutput = false })

Хенрик отбеляза това в блога си, но нито неговата проба, нито този за принос са актуализирани и просто нямах време да ангажирам корекцията в проекта за принос. ;)

person David Peden    schedule 24.05.2012
comment
Благодаря ви за отговора. Имам въпрос относно това - добавих препратка към Newtonsoft.Json, но когато се опитвам да изградя, тя хвърля изключението Типът или името на пространството от имена „JsonNetFormatter“ не може да бъде намерено. - person Anirban; 24.05.2012
comment
Толкова е лоша идея да поставите форматиращо устройство вътре в HttpResponseMessage. Conneg няма да работи с тази реализация. Ако OP не се нуждае от Conneg, защо да си правите труда да използвате Web API? просто го върнете с MVC JsonResult. От друга страна, този код ще се повреди при следващото използване на продукта, който не съдържа общи съобщения за отговор и заявка. - person tugberk; 27.05.2012
comment
@tugberk Съгласен съм с вас, че най-общо казано е за предпочитане да се възползвате от договарянето на съдържанието. Въпреки това, OP очевидно възнамерява изрично да върне json отговор. - person David Peden; 27.05.2012
comment
@DPeden тогава, нищо лошо в JsonResult, тъй като OP използва MVC. този пример е напълно против основния принцип на ASP.NET Web API. Ако намерението е само връщане на Json отговор за всяка заявка, тогава предлагам да премахнете всички други програми за форматиране с изключение на JsonMediaTypeFormatter. - person tugberk; 28.05.2012