2012-04-03 78 views
7

我的标题总结得很好。我首先提供了一些数据格式,其中一种是HTML,我可以分别使用Razor视图引擎和MVC3控制器操作来提供和使用这些数据格式。然后,可以通过自定义视图引擎提供其他数据格式。在很久以前,除了非常基本的Web服务之外,我从未在这方面工作过。我在这里有什么选择?我看到与MVC4相关的这个Web API是什么?如何编写一个既可以作为Web API又可以作为UI的MVC3/4应用程序?

注意:我的主HTML应用程序不需要直接在API上运行。我想首先编写API,这是由骨架HTML客户端的需求驱动的,它具有非常基本的用户界面,并且一旦API层层化,然后使用与API相同的服务编写功能齐全的UI客户端,但绕过实际的数据解析和演示API组件。

回答

8

一旦Web API的第一次谈话出现,我就有了同样的想法。简而言之,Web API是来自MS .NET Web Stack的新产品,它建立在WCF,OData和MVC之上,为创建RESTful Web API提供统一的手段。大量的资源,所以有一个谷歌。

现在到了问题..

的问题是,你当然可以使Web API返回HTML,JSON,XML等 - 但这里缺少的部分是由刀片提供的意见/模板/ ASPX/insertviewenginehere。这不是“API”的工作。

您当然可以编写客户端代码来调用Web API,并使用大量可用的插件来执行模板/ UI客户端。

我很确定Web API无法像ASP.NET MVC Web应用程序一样返回模板HTML。因此,如果您想“重复使用”应用程序(存储库,域等)的某些部分,最好将调用包装在各种外观/服务层中,并将Web API并将ASP.NET MVC Web应用程序调用分离以减少代码。

所有你应该结束的是一个ASP.NET MVC Web应用程序,它调用你的域并构建模板化的HTML,以及一个ASP.NET Web API应用程序,它调用你的域并返回各种资源(JSON,XML,等等)。

如果你有一个结构良好的应用程序,那么这种抽象形式应该不成问题。

+2

好的想法。也许我可以将一个MVC Web应用程序视为一个坚实的服务层作为开始,使用备用视图引擎来处理其他数据格式。 – ProfK 2012-04-03 05:56:22

1

如果您确实需要使用WebAPI返回HTML,例如允许用户点击并使用相同的URL浏览您的API,然后您可以使用routing \ html消息处理程序。

public class HtmlMessageHandler : DelegatingHandler 
{ 
    private List<string> contentTypes = new List<string> { "text/html", "application/html", "application/xhtml+xml" }; 

    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 
    {         
     if (request.Method == HttpMethod.Get && request.Headers.Accept.Any(h => contentTypes.Contains(h.ToString()))) 
     { 
      var response = new HttpResponseMessage(HttpStatusCode.Redirect); 

      var htmlUri = new Uri(String.Format("{0}/html", request.RequestUri.AbsoluteUri)); 
      response.Headers.Location = htmlUri; 

      return Task.Factory.StartNew<HttpResponseMessage>(() => response); 
     } 
     else 
     { 
      return base.SendAsync(request, cancellationToken); 
     } 
    } 
}  

对于一个完整的例子看看: - https://github.com/arble/WebApiContrib.MessageHandlers.Html

1

我这个想法之前播放。我通过MVC3将API暴露为不同控制器上的JSONResult方法。我使用控制器操作过滤器为API实现了自定义安全性。然后构建了一个使用JSON服务的AJAX沉重的HTML前端。它工作得很好,并且表现出色,因为所有为网络应用程序传输的数据都是通过AJAX。

+0

我喜欢我一些沉重的AJAX。我会看看。 – ProfK 2012-04-08 05:35:14

0

创建Html是Mvc控制器的一个工作,不适用于Web Api,因此如果您需要某些能够返回由某些视图引擎生成的jSon和Html的最佳选项,则为标准的Mvc控制器操作方法。内容协商,即返回的格式,可以通过Action Fiter实现。我有一个操作过滤器,使控制器能够以格式返回来自客户端的“提示”。客户端可以要求返回具有特定名称的视图,或者jSon。提示发送到查询字符串或隐藏字段(如果请求来自表单提交)。代码如下:

public class AcceptViewHintAttribute : ActionFilterAttribute 
{ 
    private JsonRequestBehavior jsBehavior; 
    public AcceptViewHintAttribute(JsonRequestBehavior jsBehavior = JsonRequestBehavior.DenyGet) 
    { 
     this.jsBehavior = jsBehavior; 
    } 
    public override void OnActionExecuted(ActionExecutedContext filterContext) 
    { 
     string hint = filterContext.RequestContext.HttpContext.Request.Params["ViewHint"]; 
     if (hint == null) hint = filterContext.RequestContext.RouteData.Values["ViewHint"] as string; 
     if (!string.IsNullOrWhiteSpace(hint) && hint.Length<=100 && new Regex(@"^\w+$").IsMatch(hint)) 
     { 


       ViewResultBase res = filterContext.Result as ViewResultBase; 
       if (res != null) 
       { 
        if (hint == "json") 
        { 
         JsonResult jr = new JsonResult(); 
         jr.Data = res.ViewData.Model; 
         jr.JsonRequestBehavior = jsBehavior; 
         filterContext.Result = jr; 
        } 
        else 
        { 
         res.ViewName = hint; 
        } 
       } 

     } 
     base.OnActionExecuted(filterContext); 
    } 
} 
2

我建议在您使用单台控制器的初始应用程序资产(HTML,JavaScript的,等等)返回到浏览器这样的方式开发应用程序。在WebAPI端点服务中创建您的API /逻辑并通过JavaScript访问这些服务。基本上创建一个单页面应用程序。使用MVC 4,我们的控制器可以根据设备(手机,台式机,平板电脑)返回不同的视图,但使用相同的JavaScript,所有客户端都可以访问该服务。

好的库寻找到包括KnockoutJSSammyJS,或BackBoneJS

0

现在已经过了一段时间,MS刚刚发布了MVC4/VS2012/etc的Release Candidate版本。谈到导航/帮助页面(由其他海报提到),他们添加了一个新的IApiExplorer类。我能够组建一个自我记录的帮助页面,它自动提取我的所有ApiController,并使用已经内联的注释来记录它们。正如其他人所说的,我的建议,架构明智的做法是将你的应用程序抽象成类似“MVCS”(模型,视图,控制器,服务)的东西,你可能知道它是别的东西。我所做的是将我的模型分为单独的类库,然后将我的服务分离到另一个库中。从那里,我使用Ninject/Ninject MVC3的依赖注入来根据需要挂钩我的实现,并简单地使用这些接口来获取我需要的数据。一旦我获得了我的数据(这当然是我的模型所代表的),我可以根据需要进行调整,然后将其发送回客户端。我有一个项目,我移植到MVC4,它使用“传统”Razor标记等,以及一个新的项目,这将是一个单一页面AJAX应用程序使用骨干+木偶和其他一些洒东西到目前为止,这种体验非常棒,使用起来非常简单。我在这里发现了一些关于Backbone + Marionette的好教程,虽然它们可能有些复杂,并且需要通过文档来挖掘一下才能将它们放在一起,一旦掌握了它就很容易:

Basic intro to Backbone.js的:http://arturadib.com/hello-backbonejs/docs/1.html

的用例木偶的意见(我发现这个有用的决定如何创建视图我复杂的模型时):https://github.com/derickbailey/backbone.marionette/wiki/Use-cases-for-the-different-views

1

弗雷德里克·诺门具有与ASP.NET一起使用剃刀好的帖子Web API: http://weblogs.asp.net/fredriknormen/archive/2012/06/28/using-razor-together-with-asp-net-web-api.aspx

精心设计的REST服务的一个重要限制是利用“超媒体作为应用程序状态的引擎”(HATEOAS - http://en.wikipedia.org/wiki/HATEOAS)。

在我看来,HTML是作为媒体格式之一支持的绝佳选择。这将允许开发人员和其他用户在没有专门构建的客户端的情况下浏览并与您的服务交互。反过来,这可能会导致客户对您服务的更快开发。 (当谈到开发实际的HTML客户端时,使用json或xml会更有意义)。它还会迫使开发团队进入更好设计的休息服务,因为您将被迫以便利的方式来构建您的表示最终用户使用浏览器导航。

我认为任何开发团队都应该考虑采用类似于Frederik示例的方法,并创建一个媒体类型格式化程序,该程序基于反射返回类型和使用约定来生成剩余服务的HTML UI类似的东西 - 考虑到反思,我会确保html媒体格式仅用于开发人员的探索,也许你只能在某些环境中使用它)。

我敢肯定,我最终会做这样的事情(如果有人还没有,或者如果没有一些其他功能在web api这样做。我是一个新的Web API )。也许它会成为我的第一个NuGet包。 :)如果是这样,我会在完成后发回。

+0

这里的好主意,谢谢@Stewart。 – ProfK 2012-07-05 07:15:55

相关问题