API 找不到控制器 - ASP.NET
API Controller not being found - ASP.NET
背景知识:
我正在为我们的一个笨重的旧系统添加一项功能,以使其一直运行到新版本系统达到可以将此功能提升到可以支持的级别为止这个功能。
该系统是 C# 和 VB 的组合(是的,我知道,我正在慢慢淘汰 VB)。本质上,我正在添加这个简单的 API 控制器(完成后还会有一个或两个以上的方法,这只是我开始工作的第一部分):
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Web.Http;
[RoutePrefix("/Utilities/LaptopTrolleyBooking/LaptopAPI/")]
public class LaptopBookingsController : ApiController
{
[Route("GetLaptopBookings"), HttpGet]
public async Task<HttpResponseMessage> GetLaptopBookings()
{
using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["NGConnectionString"].ConnectionString))
{
connection.Open();
using (SqlCommand command = connection.CreateCommand())
{
command.CommandText = "FR_TT_GetUpcomingLaptopBookingsForJson";
command.CommandType = CommandType.StoredProcedure;
var result = await command.ExecuteScalarAsync();
var response = Request.CreateResponse(HttpStatusCode.OK);
response.Content = new StringContent(result.ToString(), Encoding.UTF8, "application/json");
return response;
}
}
}
}
然而,当我尝试从这个 javascript 块调用它时:
$(document).ready(function () {
init();
function createElement(tag) {
return $('<' + tag + '>');
}
function createElement(tag, className) {
return $('<' + tag + '>').addClass(className);
}
function init() {
var headerElem = createElement('div', 'panHeader')
.text('Laptop Trolley Bookings');
$('.content')
.append(headerElem);
GetBookings();
function GetBookings() {
$.ajax({
url: '/Utilities/LaptopTrolleyBooking/LaptopApi/GetLaptopBookings',
method: 'get',
contentType: 'json',
dataType: 'json',
success: function (response) {
debugger;
},
error: function () {
debugger;
}
});
}
}
});
我收到错误 404。我是不是在这里做错了什么,还是我在某处遗漏了一些设置?
如果有帮助,这里是Global.asax
<%@ Application Language="VB" %>
<script runat="server">
Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
' Code that runs on application startup
' License Aspose.Words & Aspose.PDF
Dim licenseWords As New Aspose.Words.License()
licenseWords.SetLicense("Aspose.Total.lic")
Dim licensePDF As New Aspose.Pdf.License()
licensePDF.SetLicense("Aspose.Total.lic")
Dim licenseOCR As New Aspose.OCR.License()
licenseOCR.SetLicense("Aspose.Total.lic")
Dim licenseBarCode As New Aspose.BarCode.License()
licenseBarCode.SetLicense("Aspose.Total.lic")
Dim licenseBarCodeRecognition As New Aspose.BarCodeRecognition.License()
licenseBarCodeRecognition.SetLicense("Aspose.Total.lic")
Dim licenceCells As New Aspose.Cells.License()
licenceCells.SetLicense("Aspose.Total.lic")
End Sub
Sub Application_End(ByVal sender As Object, ByVal e As EventArgs)
' Code that runs on application shutdown
End Sub
Sub Application_Error(ByVal sender As Object, ByVal e As EventArgs)
' Code that runs when an unhandled error occurs
End Sub
Sub Session_Start(ByVal sender As Object, ByVal e As EventArgs)
' Get session data
End Sub
Sub Session_End(ByVal sender As Object, ByVal e As EventArgs)
' Code that runs when a session ends.
' Note: The Session_End event is raised only when the sessionstate mode
' is set to InProc in the Web.config file. If session mode is set to StateServer
' or SQLServer, the event is not raised.
End Sub
</script>
经过大量研究和进一步实验,我发现了问题所在。从本质上讲,代码库太旧了,以至于它不支持在 Web 项目中使用 API 控制器。为了解决这个问题,我创建了一个 WebService,如下所示:
using Newtonsoft.Json.Linq;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Web.Script.Serialization;
using System.Web.Script.Services;
using System.Web.Services;
[WebService(Namespace = "mySillyUrl")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ScriptService]
public class LaptopBookingController : WebService
{
public LaptopBookingController()
{
}
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json, UseHttpGet = true)]
public void CancelLaptopBooking(int RSBH_ISN)
{
using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["NGConnectionString"].ConnectionString))
{
connection.Open();
using (SqlCommand command = connection.CreateCommand())
{
List<LaptopBooking> bookings = new List<LaptopBooking>();
command.CommandText = "FR_TT_CancelLaptopBooking";
command.Parameters.AddWithValue("RSBH_ISN", RSBH_ISN);
command.CommandType = CommandType.StoredProcedure;
var unused = command.ExecuteScalar();
}
}
}
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public void GetLaptopBookings()
{
using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["NGConnectionString"].ConnectionString))
{
connection.Open();
using (SqlCommand command = connection.CreateCommand())
{
List<LaptopBooking> bookings = new List<LaptopBooking>();
command.CommandText = "FR_TT_GetUpcomingLaptopBookingsForJson";
command.CommandType = CommandType.StoredProcedure;
var result = command.ExecuteScalar();
var jArr = JArray.Parse(result.ToString());
foreach (JObject jObj in jArr)
{
bookings.Add(new LaptopBooking(jObj));
}
JavaScriptSerializer serializer = new JavaScriptSerializer();
Context.Response.Write(serializer.Serialize(bookings));
}
}
}
}
然后,从 javascript 开始,调用非常简单:
function GetBookings() {
$.ajax({
url: '/Utilities/LaptopTrolleyBooking/LaptopBookingController.asmx/GetLaptopBookings',
method: 'POST',
//contentType: "application/json; charset=utf-8",
//dataType: "json",
data: '{ }',
success: function (response) {
//debugger;
bookings = JSON.parse(response);
ShowBookings();
}
});
}
背景知识:
我正在为我们的一个笨重的旧系统添加一项功能,以使其一直运行到新版本系统达到可以将此功能提升到可以支持的级别为止这个功能。
该系统是 C# 和 VB 的组合(是的,我知道,我正在慢慢淘汰 VB)。本质上,我正在添加这个简单的 API 控制器(完成后还会有一个或两个以上的方法,这只是我开始工作的第一部分):
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Web.Http;
[RoutePrefix("/Utilities/LaptopTrolleyBooking/LaptopAPI/")]
public class LaptopBookingsController : ApiController
{
[Route("GetLaptopBookings"), HttpGet]
public async Task<HttpResponseMessage> GetLaptopBookings()
{
using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["NGConnectionString"].ConnectionString))
{
connection.Open();
using (SqlCommand command = connection.CreateCommand())
{
command.CommandText = "FR_TT_GetUpcomingLaptopBookingsForJson";
command.CommandType = CommandType.StoredProcedure;
var result = await command.ExecuteScalarAsync();
var response = Request.CreateResponse(HttpStatusCode.OK);
response.Content = new StringContent(result.ToString(), Encoding.UTF8, "application/json");
return response;
}
}
}
}
然而,当我尝试从这个 javascript 块调用它时:
$(document).ready(function () {
init();
function createElement(tag) {
return $('<' + tag + '>');
}
function createElement(tag, className) {
return $('<' + tag + '>').addClass(className);
}
function init() {
var headerElem = createElement('div', 'panHeader')
.text('Laptop Trolley Bookings');
$('.content')
.append(headerElem);
GetBookings();
function GetBookings() {
$.ajax({
url: '/Utilities/LaptopTrolleyBooking/LaptopApi/GetLaptopBookings',
method: 'get',
contentType: 'json',
dataType: 'json',
success: function (response) {
debugger;
},
error: function () {
debugger;
}
});
}
}
});
我收到错误 404。我是不是在这里做错了什么,还是我在某处遗漏了一些设置?
如果有帮助,这里是Global.asax
<%@ Application Language="VB" %>
<script runat="server">
Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
' Code that runs on application startup
' License Aspose.Words & Aspose.PDF
Dim licenseWords As New Aspose.Words.License()
licenseWords.SetLicense("Aspose.Total.lic")
Dim licensePDF As New Aspose.Pdf.License()
licensePDF.SetLicense("Aspose.Total.lic")
Dim licenseOCR As New Aspose.OCR.License()
licenseOCR.SetLicense("Aspose.Total.lic")
Dim licenseBarCode As New Aspose.BarCode.License()
licenseBarCode.SetLicense("Aspose.Total.lic")
Dim licenseBarCodeRecognition As New Aspose.BarCodeRecognition.License()
licenseBarCodeRecognition.SetLicense("Aspose.Total.lic")
Dim licenceCells As New Aspose.Cells.License()
licenceCells.SetLicense("Aspose.Total.lic")
End Sub
Sub Application_End(ByVal sender As Object, ByVal e As EventArgs)
' Code that runs on application shutdown
End Sub
Sub Application_Error(ByVal sender As Object, ByVal e As EventArgs)
' Code that runs when an unhandled error occurs
End Sub
Sub Session_Start(ByVal sender As Object, ByVal e As EventArgs)
' Get session data
End Sub
Sub Session_End(ByVal sender As Object, ByVal e As EventArgs)
' Code that runs when a session ends.
' Note: The Session_End event is raised only when the sessionstate mode
' is set to InProc in the Web.config file. If session mode is set to StateServer
' or SQLServer, the event is not raised.
End Sub
</script>
经过大量研究和进一步实验,我发现了问题所在。从本质上讲,代码库太旧了,以至于它不支持在 Web 项目中使用 API 控制器。为了解决这个问题,我创建了一个 WebService,如下所示:
using Newtonsoft.Json.Linq;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Web.Script.Serialization;
using System.Web.Script.Services;
using System.Web.Services;
[WebService(Namespace = "mySillyUrl")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ScriptService]
public class LaptopBookingController : WebService
{
public LaptopBookingController()
{
}
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json, UseHttpGet = true)]
public void CancelLaptopBooking(int RSBH_ISN)
{
using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["NGConnectionString"].ConnectionString))
{
connection.Open();
using (SqlCommand command = connection.CreateCommand())
{
List<LaptopBooking> bookings = new List<LaptopBooking>();
command.CommandText = "FR_TT_CancelLaptopBooking";
command.Parameters.AddWithValue("RSBH_ISN", RSBH_ISN);
command.CommandType = CommandType.StoredProcedure;
var unused = command.ExecuteScalar();
}
}
}
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public void GetLaptopBookings()
{
using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["NGConnectionString"].ConnectionString))
{
connection.Open();
using (SqlCommand command = connection.CreateCommand())
{
List<LaptopBooking> bookings = new List<LaptopBooking>();
command.CommandText = "FR_TT_GetUpcomingLaptopBookingsForJson";
command.CommandType = CommandType.StoredProcedure;
var result = command.ExecuteScalar();
var jArr = JArray.Parse(result.ToString());
foreach (JObject jObj in jArr)
{
bookings.Add(new LaptopBooking(jObj));
}
JavaScriptSerializer serializer = new JavaScriptSerializer();
Context.Response.Write(serializer.Serialize(bookings));
}
}
}
}
然后,从 javascript 开始,调用非常简单:
function GetBookings() {
$.ajax({
url: '/Utilities/LaptopTrolleyBooking/LaptopBookingController.asmx/GetLaptopBookings',
method: 'POST',
//contentType: "application/json; charset=utf-8",
//dataType: "json",
data: '{ }',
success: function (response) {
//debugger;
bookings = JSON.parse(response);
ShowBookings();
}
});
}