2016-03-05 59 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時,我會有很多方法可以調用。 –

相關問題