Применение RazorEngine только к некоторым ответам WebApi

У меня есть приложение, которое использует WebApi + signalR + самостоятельный хостинг. И я добавил RazorEngine, чтобы разрешить использование представлений cshtml с синтаксисом бритвы.

Это работает (см. упрощенный код ниже), но это приводит к тому, что все вызовы WebApi пытаются сгенерировать HTML через views+razor. Я хочу иметь какой-нибудь WebAPi, который просто отправляет обычный XML или JSON на запросы от клиента. Например. возможно, один контроллер API для использования обычного XML/JSON и один контроллер API для генерации ответов с использованием vews/razor/cshtml

Есть идеи, как мне это сделать?

    class Program  {
        static void Main(string[] args)  {  
            using (WebApp.Start<Startup>(url: "http://localhost:8080/")) {
                Console.WriteLine("Started");
                Console.ReadKey();
            }
        }
    }


    public class Startup {
        public void Configuration(IAppBuilder app)  {
            HttpConfiguration config = new HttpConfiguration();
            config.Routes.MapHttpRoute(
                  name: "DefaultApi",
                  routeTemplate: "api/{controller}/{id}",
                  defaults: new { id = RouteParameter.Optional }
              );
            app.UseWebApi(config);
            app.UseCors(CorsOptions.AllowAll);
            app.MapSignalR();

            // RazorEngine - so WebApi can use views+razor
            GlobalConfiguration.Configuration.Formatters.Add(new HtmlMediaTypeViewFormatter());
            GlobalViews.DefaultViewParser = new RazorViewParser();
            GlobalViews.DefaultViewLocator = new RazorViewLocator();
            config.Formatters.Add(new HtmlMediaTypeViewFormatter());
        }
    }



    public class HomeController : ApiController {

        //http://localhost:8080/api/home
        public Value GetValues()  {
            return new Value() { Numbers = new int[] { 1, 2, 3 } };
        }

        //want to return just XML and not go via the view+razor+cshtml
        //Works ok for normal self-hosted webapi, but cant get to work for views+razor
        //http:localhost:8080/api/home/1
        public String Get2(int id)  {
            return "Get2() returns a string";
        }

    }


    [View("Home")]     //need this line to get the webApi views+razor to work
    public class Value  {
        public int[] Numbers { get; set; }
    }

Главная.cshtml...

<html>
<head>
    <title>Hello World!</title>
</head>
<body>
    <h1>Hello World! ..</h1>
    <ul>
        @foreach (var value in Model.Numbers)
        {
            <li>@value</li>
        }
    </ul>
</body>
</html> 

person spiderplant0    schedule 03.02.2014    source источник


Ответы (1)


Есть несколько способов.

A) Вы можете просто заставить клиента отправить правильный заголовок принятия, чтобы веб-API согласовывал правильные средства форматирования.

б) Вы можете настроить конфигурацию для каждого контроллера отдельно. Это позволит вам определить средство форматирования HTML только для тех контроллеров, которым вы хотите вернуть HTML. Вот ссылка о том, как это сделать для каждого контроллера: http://blogs.msdn.com/b/jmstall/archive/2012/05/11/per-controller-configuration-in-webapi.aspx

c) Не используйте обратный конвейер conneg для контроллеров HTML. Верните HttpResposeMessage и явно задайте свойство Content.

 public class HomeController : ApiController {

    //http://localhost:8080/api/home
    public HttpResponseMessage GetValues()  {
        var value = Value() { Numbers = new int[] { 1, 2, 3 } };

        return new HttpResponseMessage() {
                 Content = new ObjectContent<Value>(value, new HtmlMediaTypeViewFormatter())
             };
    }

    //want to return just XML and not go via the view+razor+cshtml
    //Works ok for normal self-hosted webapi, but cant get to work for views+razor
    //http:localhost:8080/api/home/1
    public String Get2(int id)  {
        return "Get2() returns a string";
    }

}
person Darrel Miller    schedule 04.02.2014
comment
Спасибо. Да, я думал о чем-то вроде (b), но я не знал, как это сделать. Я не понимаю (с). - person spiderplant0; 04.02.2014
comment
Спасибо, я не мог заставить (c) работать (он просто возвращал html через представление как обычно). Я посмотрю на (б), а пока перейду к (а). - person spiderplant0; 06.02.2014