尝试使用F#控制器与Web API

3
在我的C# MVC项目中,我遇到了一个错误提示:“无法从程序集MyApp.Api中加载类型为MyApp.Api.App”,这个项目引用了一个F# Web API库。C#项目MyApp.Web将F#项目MyApp.Api作为项目引用,并且没有编译错误。可能出现了什么问题?
MyApp.Api项目中的App.fs文件。
namespace MyApp.Api

open System
open System.Web
open System.Web.Mvc
open System.Web.Routing
open System.Web.Http
open System.Data.Entity
open System.Net.Http.Headers

open System.Net.Http.Headers

type Route = { controller : string; action : string; id : UrlParameter }
type ApiRoute = { id : RouteParameter }

type App() =
    inherit System.Web.HttpApplication() 

    static member RegisterGlobalFilters (filters:GlobalFilterCollection) =
        filters.Add(new HandleErrorAttribute())

    static member RegisterRoutes(routes:RouteCollection) =
        routes.IgnoreRoute( "{resource}.axd/{*pathInfo}" )
        routes.MapHttpRoute( "DefaultApi", "api/{controller}/{id}", 
            { id = RouteParameter.Optional } ) |> ignore
        routes.MapRoute("Default", "{controller}/{action}/{id}", 
            { controller = "Home"; action = "Index"; id = UrlParameter.Optional } ) |> ignore

    member this.Start() =
        AreaRegistration.RegisterAllAreas()
        App.RegisterRoutes RouteTable.Routes
        App.RegisterGlobalFilters GlobalFilters.Filters

我的MyApp.Web中的global.asax.cs文件

using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using MyApp.Api;

namespace MyApp.Web
{
    public class WebApiApplication :  MyApp.Api.App// System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            base.Start();
        }

    }
}

你是否"清理"了你的解决方案? 你甚至可以尝试关闭VS, 删除每个项目文件夹中的'bin'和'obj'文件夹,然后重新启动VS并重建解决方案。可能是因为C#项目能够解析对 MyApp.Api.App 的引用,因此构建正常,但当C#网站运行时,它使用旧版本(缓存)的F# DLL,在该DLL中 MyApp.Api.App 不存在(或名称/命名空间不同)。 - Jack P.
尝试清理、关闭VS并删除所有bin文件,仍然出现相同的错误... - MonkeyBonkey
嗯...我看不出任何立即失败的原因。您可以将项目上传到某个地方吗? - Tomas Petricek
我会尝试在这个周末上传一些东西。 - MonkeyBonkey
嗯,我刚刚创建了一个新的MVC Web项目,并将引用添加到相同的F#项目中,看起来运行良好。原始旧的MVC Web项目中肯定有一些问题,但没有编译时错误。 - MonkeyBonkey
1个回答

2
您正在错误地注册API路由。虽然这些API看起来相似,但它们实际上并不相同。您需要使用HttpConfiguration实例注册Web API路由:
GlobalConfiguration.Configuration.Routes.MapHttpRoute("", "", ...)

您正在尝试将Web API路由映射到MVC的RouteTable中。我很惊讶您没有收到编译错误。
所以上述情况似乎并非如此。我之前尝试过没有引入Dan Mohl的项目模板,可能没有包含适当的命名空间。
您已经在Global.asax.cs中对MyApp.Api.App类型进行了子类化。但是,Dan的模板不包括这个步骤。相反,他的模板修改了Global.asax中的标记,如下所示:
<%@ Application Inherits="MyApp.Api.App" Language="C#" %>
<script Language="C#" RunAt="server">

  protected void Application_Start(Object sender, EventArgs e) {
      base.Start();
  }

</script>

这看起来完全没问题。我还让以下内容正常工作了:

<%@ Application Inherits="MyApp.Web.WebApiApplication" Language="C#" %>
<!-- The following seems to be optional; just an extra, duplicate event handler.
     I was able to run the app with this script and without. -->
<script Language="C#" RunAt="server">

  protected void Application_Start(Object sender, EventArgs e) {
      base.Start();
  }

</script>

请注意需要全命名空间,而不仅仅是类型名称。如果这样能正常工作,那么我认为还需要更多的代码,因为我找不到其他有问题的地方。


这是我从默认的F# Web API模板中复制的代码,似乎在模板中运行正常。 - MonkeyBonkey
啊,我以为你没有使用模板,因为你有一个Global.asax.cs。然而,你是正确的;模板似乎工作正常。 - panesofglass

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接