我知道这听起来像是一个愚蠢的问题,但有一种方法可以'模仿'WebAPI路由风格(即可能使用[HttpPost]装饰等)为MVC控制器。我的问题的关键是我有一个'容器'MVC网站。这包含在PreLoad中加载区域文件夹中的其他MVC站点并将它们合并到自身中。所以它基本上充当插件系统。这一切都很好但是我需要为这个网站添加一个API,我认为如果我把API作为另一个插件就会容易得多。
我在我的网站中使用Ninject,再一次很好地从插件中获取所有依赖项。问题是Ninject会自动检测MVC控制器而不是WebAPI控件,我发现你不能让一个项目同时使用Nijnect进行WebAPI和MVC。所以我的下一个选择是尝试在MVC中模仿WebAPI(毕竟,它们实际上基于相同的东西。)
我最初认为这很简单,默认路由中的“索引”操作名称,他们只是在每个方法上加上'AcceptVerbs'装饰。当然它没有用。
有没有人知道如何使用MVC方面(不转换为WebAPI)来创建像RestAPI这样的东西?
答案 0 :(得分:0)
您可以像往常一样使用控制器并让它们返回JsonResult
。我对我的一些视图使用这种方法,这些视图需要通过查找动态列表,但不需要转到web api。随着属性路由,我能够从我的MVC获得类似web api的功能
示例场景是我有一个表单根据从组合框中选择的值填充某些字段。当用户选择一个选项时,我使用JQuery在我的控制器中调用类似WebAPI的操作。
[RoutePrefix("Pickup")]
[Route("{action=Create}")]
public class PickupController : FrontOfficeAuthorizedController {
[HttpPost]
public JsonResult GetSenderAddress(Guid? addressId) {
if(addreddId != null) {
//Do something to get an address
if(address != null) {
//Only send required info over the wire
return Json(new {
success = true,
address = new {
Address1 = address.Address1,
Address2 = address.Address2,
AddressType = address.AddressType,
CompanyOrName = address.CompanyOrName,
Contact = address.Contact,
Country = address.Country,
PostalCode = address.PostalCode,
Telephone = address.Telephone,
TownCity = address.TownCity,
}
});
}
}
return Json(new { success = false });
}
}
以下是客户端的javascript片段。请注意,我正在使用Knockout
以及JQuery
//Shipfrom properties
self.ShipFromaddressid = ko.observable();
//Update shipfrom address based on id
self.ShipFromaddressid.subscribe(function () { getAddress(); });
var getAddress = function () {
var selectedAddressId = { addressId: self.ShipFromaddressid() };
$.ajax({
url: '@(Url.Action<PickupController>(c=>c.GetSenderAddress(null)))',
type: 'Post',
contentType: 'application/json',
dataType: 'json',
data: JSON.stringify(selectedAddressId),
success: handleResponse
});
};
var handleResponse = function (data) {
if (data.success) {
//console.log(data.address);
self.ShipFromCompanyOrName((data.address.CompanyOrName) ? data.address.CompanyOrName : "");
self.ShipFromContact((data.address.Contact) ? data.address.Contact : "");
self.ShipFromTelephone((data.address.Telephone) ? data.address.Telephone : "");
self.ShipFromAddress1((data.address.Address1) ? data.address.Address1 : "");
self.ShipFromAddress2((data.address.Address2) ? data.address.Address2 : "");
self.shipfromtowncity((data.address.TownCity) ? data.address.TownCity : "");
self.ShipFromPostalCode((data.address.PostalCode) ? data.address.PostalCode : "");
self.ShipFromCountry((data.address.Country) ? data.address.Country : "");
self.ShipFromAddressType((data.address.AddressType) ? data.address.AddressType : "");
}
};
答案 1 :(得分:0)
在RouteConfig.cs文件中,您可以通过传递HttpMethodContraint来指定哪个HTTP谓词进入哪个操作:
routes.MapRoute(
"route that matches only GETs for your url",
"your url",
new { controller = "some controller", action = "some action" },
new { httpMethod = new HttpMethodConstraint("GET") });
这将允许您定义模拟WebAPI的控制器路由。