9

我使用本教程中的示例代码构建了一个非常基本的 Web API 示例:

代码

相关的 Web.config 部分

  <system.webServer>
    <validation validateIntegratedModeConfiguration="false" />
    <handlers>
      <remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
      <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
      <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
  </system.webServer>

路由配置

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
}

查看模型

public class Survey
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
}

ApiController

public class SurveysController : ApiController
{
    public IEnumerable<Survey> All()
    {
        using (ITSurveyEntities model = new ITSurveyEntities())
        {
            return new List<Survey>(
                from s in model.Surveys
                select new Survey
                {
                    Id = s.Id,
                    Name = s.Name,
                    Description = s.Description,
                });
        }
    }
}

它正在利用ITSurveyEntities,这是从数据库中生成的 ADO.NET 实体数据模型,现在只包含一个表,Survey.

简而言之,我不认为我想在这里做任何特别的事情。

当前结果

当我尝试使用类似的东西导航到 APIhttp://localhost:1681/api/surveys时,我得到了响应,但文件的名称surveys没有扩展名。此外,如果我尝试并Save As给它说一个txt扩展名,下载就会失败。

预期结果

我希望 API 会返回一个文件名surveys.json,就像示例项目一样products,浏览器会要求我打开或保存文件。

我试过的

比较 Web.config 文件

我已经比较了Web.config我的项目和教程中的示例代码之间的文件。

比较路由

我已经比较了我的项目和教程中的示例代码之间的路由配置。

不包括 WebDav

我试图排除 WebDav,因为我的搜索表明这可能是原因。我通过以与此博客上的内容相匹配的方式修改 Web.config 来做到这一点。

更新 1

好的,在 Joe Enos 的指导下,我发现问题在于视图模型也被命名Survey,因此它引发了关于 CLR 类型和 EDM 类型之间歧义的错误。

我通过将视图模型重命名为 解决了这个问题SurveyViewModel,并且请求http://localhost:1681/api/surveys现在返回 aHTTP 200并按预期下载文件。

4

2 回答 2

2

如果您使用 Fiddler 或浏览器的开发工具查看原始请求和响应,您应该会找到一些有关问题的线索。

于 2013-08-08T18:44:47.597 回答
2

响应类型(xml、json 等)将由请求中的接受标头决定。您没有提及您用于调用服务的浏览器,但我相信浏览器之间的默认接受标头存在差异。如果您只想从 webapi 仅返回 Json 数据,请尝试将以下内容添加到 Global.Asax:

    GlobalConfiguration.Configuration.Formatters.Clear();

    GlobalConfiguration.Configuration.Formatters.Insert(0,new JsonMediaTypeFormatter());

媒体格式化程序本质上是如何为浏览器序列化来自 Webapi 方法的数据。

于 2013-08-08T16:27:56.120 回答