2016-03-05 75 views
2

我有这个ASP.NET MVC 5项目,我正在使用MS Web Api将其转换为AngularJS。将Asp.Net MVC控制器转换为Web API的最佳方法

现在在旧项目中,我有这些类型为Controller的c#控制器,但是在我的新项目中,我创建了一些新的Web Api控制器,类型为ApiController

现在我想在我的新项目中重用旧的控制器代码。这是我的困惑。

当我试图将旧的控制器代码移植到我的Web Api控制器时,我得到一些前端$http请求错误。

下面是从我的角度dataService工厂的功能,这使得一个HTTP REQ到'api/Whatif/SummaryPortfolios'

function getCurrPortfoliosLIst() { 
 
    var deferred = $q.defer(); 
 

 
    var url = 'api/Whatif/SummaryPortfolios'; 
 
    var req={ 
 
    method: 'POST', 
 
    url: url, 
 
    headers: { 
 
     'Content-Type': 'application/json', 
 
    }, 
 
    data:{} 
 
    }; 
 
    $http(req).then(function (resp){ 
 
    deferred.resolve(resp.data); 
 
    }, function(err){ 
 
    console.log('Error from dataService: ' + resp); 
 
    }); 
 
}

$http误差部分返回此异常:

data: Object 
 
ExceptionMessage: "Multiple actions were found that match the request: 
 
↵SummaryPortfolios on type MarginWorkbenchNG.Controllers.WhatifController 
 
↵Post on type MarginWorkbenchNG.Controllers.WhatifController" 
 
ExceptionType: "System.InvalidOperationException" 
 
Message: "An error has occurred." 
 
StackTrace: " at System.Web.Http.Controllers.ApiControllerActionSelector.ActionSelectorCacheItem.SelectAction(HttpControllerContext controllerContext) 
 
↵ at System.Web.Http.Controllers.ApiControllerActionSelector.SelectAction(HttpControllerContext controllerContext) 
 
↵ at System.Web.Http.ApiController.ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken) 
 
↵ at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()

这里的C#API控制器我打电话到,但我需要弄清楚如何创造出比直get()和邮政(其它方法)方法:

using System; 
 
using System.Collections.Generic; 
 
using System.Linq; 
 
using System.Net; 
 
using System.Net.Http; 
 
using System.Web; 
 
using System.Web.Http; 
 
using Microsoft.AspNet.Identity; 
 
using NLog; 
 
using Microsoft.AspNet.Identity.Owin; 
 
using MarginWorkbenchNG.Models; 
 
using Rz.DAL; 
 
using Rz.DAL.Integration; 
 
using Rz.DAL.Models; 
 
using Rz.DAL.Models.Rz; 
 

 
namespace MarginWorkbenchNG.Controllers 
 
{ 
 
    public class WhatifController : ApiController 
 
    { 
 
\t \t public IEnumerable<string> Get() 
 
\t \t \t { \t \t \t \t \t \t 
 
\t \t \t \t return new string[] { "value1", "value2" }; 
 
\t \t \t } 
 
\t \t [HttpPost] 
 
     public List<WhatifSummaryViewModel> SummaryPortfolios(string filterValue = "", int? whatIfBatchNumber = null, bool includeBaseline = true) 
 
     { 
 
      // Get portfolios from Rz 
 
      IEnumerable<Portfolio> portfolios = GetPortfolios(filterValue, whatIfBatchNumber, includeBaseline) 
 
       .Where(x => x.PortfolioKeys.Any(k => k.Type == Settings.Whatif.SidebarPortfolioKey && k.DisplayValue == filterValue)); 
 

 
      // View Model 
 
      List<WhatifSummaryViewModel> model = new List<WhatifSummaryViewModel> { }; 
 

 
      /// additional code here... 
 

 
      return model; 
 
     } 
 
\t } 
 
}

旧控制器(从MVC5项目)看上去稍有不同,当然,因为_Summary方法是ActionResult型的,并返回一个Partial

public class WhatifController : Controller 
 
    { 
 
     
 
     [HttpPost] 
 
     [ValidateAntiForgeryToken] 
 
     public ActionResult _Summary(string filterValue = "", int? whatIfBatchNumber = null, bool includeBaseline = true) 
 
     { 
 
      // Get portfolios from Razor 
 
      IEnumerable<Portfolio> portfolios = GetPortfolios(filterValue, whatIfBatchNumber, includeBaseline) 
 
       .Where(x => x.PortfolioKeys.Any(k => k.Type == Settings.Whatif.SidebarPortfolioKey && k.DisplayValue == filterValue)); 
 

 
      // View Model 
 
      List<WhatifSummaryViewModel> model = new List<WhatifSummaryViewModel> { }; 
 

 
      // additional code removed for brevity... 
 

 
      return PartialView(model.OrderBy(x => x.Title).ThenBy(x => x.SubTitle)); 
 
     }

RouteConfig.cs

using System; 
 
using System.Collections.Generic; 
 
using System.Linq; 
 
using System.Web; 
 
using System.Web.Mvc; 
 
using System.Web.Routing; 
 

 
namespace MarginWorkbenchNG 
 
{ 
 
    public class RouteConfig 
 
    { 
 
    public static void RegisterRoutes(RouteCollection routes) 
 
    { 
 
     routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 
 

 
     routes.MapRoute(
 
     name: "Default", 
 
     url: "{controller}/{action}/{id}", 
 
     defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } 
 
    ); 
 
    } 
 
    } 
 
}

老项目也使用HTML表单拉URL,例如:

<form id="whatif-summary-form" action="@Url.Action("_Summary", "WhatIf")" method="POST"></form> 

然后再换action ATTRIB得到URL建立外出时在JavaScript Ajax请求(非角):提前

url: form.prop("action") 

谢谢...

鲍勃

+0

请发表您的路由配置 –

+0

@lrb - ?我贴我的'RouteConfig.cs'在底部我 –

回答

1

这是你的整个ApiController?您收到的错误消息是因为您的ApiController具有几个相同类型的方法,并且无法分辨哪一个要路由到哪个方法。要测试这个:注释掉你所调用的控制器的所有方法。你不应该再收到那个错误了。

这是一个简单的修复,只需告诉web api如何映射您的路线。添加属性“[路线(“yourroute‘)]’你的方法,它应该工作

public class WhatifController : ApiController 
    { 
     [HttpPost, Route("Your Route Goes here 'SummaryPortfolios'")] 
     public IHttpActionResult SummaryPortfolios(string filterValue = "", int? whatIfBatchNumber = null, bool includeBaseline = true) 
     { 
      // Get portfolios from Rz 
      IEnumerable<Portfolio> portfolios = GetPortfolios(filterValue, whatIfBatchNumber, includeBaseline) 
       .Where(x => x.PortfolioKeys.Any(k => k.Type == Settings.Whatif.SidebarPortfolioKey && k.DisplayValue == filterValue)); 

      // View Model 
      List<WhatifSummaryViewModel> model = new List<WhatifSummaryViewModel> { }; 

      /// additional code here... 

      return Ok(model); 
     } 
    } 
+0

在阅读这篇文章,http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2,我相信我装饰我的SummaryPortfolios(0方法使用'[HttpPost,Route(“WhatIfController/GetSummaryPortfolios”)]'。它看起来是否正确? –

+0

@bob如果它是一个GET方法,那么你不应该用HttpPost来修饰它,只需删除HttpPost属性。 –

+0

我希望所有的东西都是POST,我也看到WebApi 2在命名你的路由方面有更多的灵活性,这是相当有用的FUL。当我从Asp.Net MVC“Web Pages”转换为AngularJS/WebApi时,我会有很多方法可以调用。 –

相关问题