我是 odata 新手,正在尝试按照教程进行操作
https://learn.microsoft.com/en-us/odata/webapi-8/fundamentals/routing-overview?tabs=net60
我正在尝试创建一个可访问的操作 http://localhost:5207/odata/Customers/Get12345
但它给出“找不到本地主机页面”
我遇到的一个选项是添加
[Route("odata/Customers/Get12345")] 在操作之上,但我不希望这样,因为我觉得如果“odata”发生变化,我将不得不进行多次更改,并感觉可能有更好的选择。
我遇到的另一个选择是使用 Action,但我无法使其工作,因为我完全不理解它。有人可以帮忙吗?
var customersType = modelBuilder.EntitySet<Customer>("Customers").EntityType;
customersType.Collection.Action("Get12345")
.ReturnsFromEntitySet<Customer>("Customers");
// 程序.cs
// Program.cs
using Lab01.Models;
using Microsoft.AspNetCore.OData;
using Microsoft.OData.ModelBuilder;
using Microsoft.VisualBasic;
var builder = WebApplication.CreateBuilder(args);
var modelBuilder = new ODataConventionModelBuilder();
modelBuilder.EntityType<Order>();
modelBuilder.EntitySet<Customer>("Customers");
// It means if you have an entity set named Customers based on Customer entity type
// Odata type returned here returns the data in the form of Customer entity type as is named as "Customers" in the odata context
// It indicates that this payload comes from Customer entity set
var customersType = modelBuilder.EntitySet<Customer>("Customers").EntityType;
customersType.Collection.Action("Get12345")
.ReturnsFromEntitySet<Customer>("Customers");
builder.Services.AddControllers().AddOData(
options => options.Select().Filter().OrderBy().Expand().Count().SetMaxTop(null).AddRouteComponents("odata", modelBuilder.GetEdmModel()));
var app = builder.Build();
app.UseRouting();
app.UseEndpoints(endpoints => endpoints.MapControllers());
// Customers is being defined as the name of the entity set
// so seeing if changing the controller to Customer gives the data - No it does not give the data
app.Run();
CustomersController.cs
using Lab01.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.OData.Query;
using Microsoft.AspNetCore.OData.Routing.Controllers;
namespace Lab01.Controllers
{
public class CustomersController : ODataController
{
private static Random random = new Random();
private static List<Customer> customers = new List<Customer>(
Enumerable.Range(1, 3).Select(idx => new Customer
{
Id = idx,
Name = $"Customer {idx}",
Orders = new List<Order>(
Enumerable.Range(1, 2).Select(dx => new Order
{
Id = (idx - 1) * 2 + dx,
Amount = random.Next(1, 9) * 10
}))
}));
[EnableQuery]
public ActionResult<IEnumerable<Customer>> Get()
{
return Ok(customers);
}
[EnableQuery]
public ActionResult<string> Get([FromRoute] int key)
{
var item = customers.SingleOrDefault(d => d.Id.Equals(key));
if (item == null)
{
return NotFound();
}
return Ok("abcd");
}
// Create an action to be accessible at the odata endpoint for Get1234567
// For this the endpoint localhost:5207/Customers
// /Get12345 is working - But it is not Odata compatible as odata is not coming in response
// The endpoint this is not working - "http://localhost:5207/odata/Customers/Get12345"
[EnableQuery]
public ActionResult<Customer> Get12345()
{
var item = customers.SingleOrDefault(d => d.Id.Equals(1));
if (item == null)
{
return NotFound();
}
return Ok(item);
}
[EnableQuery]
[Route("odata/Customers/Get1234567")]
public ActionResult<Customer> Get1234567()
{
return new Customer();
}
}
}
客户.cs
namespace Lab01.Models
{
using System.Collections.Generic;
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
public List<Order> Orders { get; set; }
}
}
订单.cs
namespace Lab01.Models
{
using System.Collections.Generic;
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
public List<Order> Orders { get; set; }
}
}
问题在于操作仅支持
HttpPost
请求。要解决此问题,您需要使用 [HttpPost]
属性标记您的方法。
在 Microsoft 文档 中描述的操作如下
操作是一种添加不易定义的服务器端逻辑的方法 作为对实体的 CRUD(创建、读取、更新和删除)操作。一个 动作可能会产生副作用,这就是为什么它们是用 HTTP POST 方法。操作可以针对单个实体或集合 的实体。在 OData 术语中,这是具有约束力的。您还可以拥有 “未绑定”操作,基本上是 OData 上的静态操作 服务。
[EnableQuery]
[HttpPost]
public ActionResult<Customer> Get12345()
{
...
}
此外,请注意,在浏览器中输入 URL 将导致
HttpGet
请求。