当我尝试使用 EF Core 5.0 实现时,.NET Core 5 odata 不工作
.NET Core 5 odata not working when I try to implement with EF Core 5.0
按照以下链接学习教程后:
https://devblogs.microsoft.com/odata/asp-net-core-odata-now-available/
https://devblogs.microsoft.com/odata/asp-net-odata-8-0-preview-for-net-5/
Microsoft.EntityFrameworkCore.InMemory一切正常。但是,当我更改为 SQL 连接时。当我尝试访问 http://localhost:57354/odata/Users 时,odata return 404 状态
这是我的文件配置:
Startup.cs:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<DataContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<User, Role>()
.AddEntityFrameworkStores<DataContext>()
.AddDefaultTokenProviders();
services.AddControllers();
services.AddOData(opt =>
opt.AddModel("odata", GetEdmModel())
.Select().Filter().Count().Expand().OrderBy());
services.AddScoped<IDataContext, DataContext>();
services.AddTransient<DbContext, DataContext>();
services.AddTransient<IUnitOfWorkAsync, UnitOfWork>();
services.AddTransient<IUserService, UserService>();
services.AddTransient(typeof(IRepository<>), typeof(Repository<>));
services.AddTransient(typeof(IRepositoryAsync<>), typeof(Repository<>));
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseODataBatching();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
private static IEdmModel GetEdmModel()
{
ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<User>("Users");
return builder.GetEdmModel();
}
}
我的UserController.cs
[Route("api/[controller]")]
[ApiController]
public class UsersController : ODataController
{
private readonly IUnitOfWorkAsync _unitOfWorkAsync;
private readonly IUserService _userService;
public UsersController(
IUserService userService,
IUnitOfWorkAsync unitOfWorkAsync
)
{
_userService = userService;
_unitOfWorkAsync = unitOfWorkAsync;
}
[HttpGet]
[EnableQuery]
public async Task<IQueryable<UserViewModel>> Get()
{
return await _userService.GetAllUserAsync();
}
[HttpPost]
public async Task<IActionResult> Post(UserViewModel model)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
try
{
var user = await _userService.InsertUserAsync(model);
_unitOfWorkAsync.Commit();
var returnUser = new UserViewModel()
{
Id = user.Id,
PhoneNumber = user.PhoneNumber,
Email = user.Email,
IsBanned = user.IsBanned
};
return Created("Created new user", returnUser);
}
catch (Exception ex)
{
throw;
}
}
[HttpPut]
public async Task<IActionResult> Put(UserViewModel model)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
try
{
await _userService.UpdateUserAsync(model);
_unitOfWorkAsync.Commit();
await TryUpdateModelAsync(model);
return Content("Updated User", "application/json", Encoding.UTF8);
}
catch (Exception ex)
{
throw;
}
}
[HttpDelete]
public IActionResult Delete([FromODataUri] Guid key)
{
_userService.Delete(key);
_unitOfWorkAsync.Commit();
return StatusCode(200, new { Deleted = "Success" });
}
}
这是我尝试过的方法,但到目前为止还没有奏效。
我尝试在 Startup.cs
中更改
public void ConfigureServices(IServiceCollection 服务)
{
//Code keep the same
services.AddControllers(mvcOptions => mvcOptions.EnableEndpointRouting = false);
services.AddMvc();
//Code keep the same.......
}
并且在配置部分我也改为喜欢 .net Core 3.1 及更早版本。但是,通知告诉我没有实现这些的方法或成员:
app.UseMvc(routeBuilder =>
{
routeBuilder.EnableDependencyInjection();
routeBuilder.Select().Filter().Count().Expand().OrderBy().MaxTop(null);
routeBuilder.MapODataServiceRoute("odata", "odata", GetEdmModel());
});
然后我也尝试在Configure中用另一种方式添加,结果一样:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapODataRoute("odata1", "odata", GetEdmModel());
});
我不知道它是如何在 Microsoft.EntityFrameworkCore.InMemory 库上完美运行的,但是当我更改为 SQL 服务器时,一切都不是 运行 如我所料。这是我的文件 appsettings.json 如果你想知道:
{
"ConnectionStrings": {
"DefaultConnection": "Server(localdb)\mssqllocaldb;Database=basenetcore;Trusted_Connection=True
;MultipleActiveResultSets=true"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}
感谢您抽出宝贵时间,希望您度过愉快的一天。
只需删除代码:
[Route("api/[controller]")]
[ApiController]
在你的 UsersController
.
按照以下链接学习教程后:
https://devblogs.microsoft.com/odata/asp-net-core-odata-now-available/
https://devblogs.microsoft.com/odata/asp-net-odata-8-0-preview-for-net-5/
Microsoft.EntityFrameworkCore.InMemory一切正常。但是,当我更改为 SQL 连接时。当我尝试访问 http://localhost:57354/odata/Users 时,odata return 404 状态
Startup.cs:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<DataContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<User, Role>()
.AddEntityFrameworkStores<DataContext>()
.AddDefaultTokenProviders();
services.AddControllers();
services.AddOData(opt =>
opt.AddModel("odata", GetEdmModel())
.Select().Filter().Count().Expand().OrderBy());
services.AddScoped<IDataContext, DataContext>();
services.AddTransient<DbContext, DataContext>();
services.AddTransient<IUnitOfWorkAsync, UnitOfWork>();
services.AddTransient<IUserService, UserService>();
services.AddTransient(typeof(IRepository<>), typeof(Repository<>));
services.AddTransient(typeof(IRepositoryAsync<>), typeof(Repository<>));
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseODataBatching();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
private static IEdmModel GetEdmModel()
{
ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<User>("Users");
return builder.GetEdmModel();
}
}
我的UserController.cs
[Route("api/[controller]")]
[ApiController]
public class UsersController : ODataController
{
private readonly IUnitOfWorkAsync _unitOfWorkAsync;
private readonly IUserService _userService;
public UsersController(
IUserService userService,
IUnitOfWorkAsync unitOfWorkAsync
)
{
_userService = userService;
_unitOfWorkAsync = unitOfWorkAsync;
}
[HttpGet]
[EnableQuery]
public async Task<IQueryable<UserViewModel>> Get()
{
return await _userService.GetAllUserAsync();
}
[HttpPost]
public async Task<IActionResult> Post(UserViewModel model)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
try
{
var user = await _userService.InsertUserAsync(model);
_unitOfWorkAsync.Commit();
var returnUser = new UserViewModel()
{
Id = user.Id,
PhoneNumber = user.PhoneNumber,
Email = user.Email,
IsBanned = user.IsBanned
};
return Created("Created new user", returnUser);
}
catch (Exception ex)
{
throw;
}
}
[HttpPut]
public async Task<IActionResult> Put(UserViewModel model)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
try
{
await _userService.UpdateUserAsync(model);
_unitOfWorkAsync.Commit();
await TryUpdateModelAsync(model);
return Content("Updated User", "application/json", Encoding.UTF8);
}
catch (Exception ex)
{
throw;
}
}
[HttpDelete]
public IActionResult Delete([FromODataUri] Guid key)
{
_userService.Delete(key);
_unitOfWorkAsync.Commit();
return StatusCode(200, new { Deleted = "Success" });
}
}
这是我尝试过的方法,但到目前为止还没有奏效。
我尝试在 Startup.cs
中更改public void ConfigureServices(IServiceCollection 服务) {
//Code keep the same services.AddControllers(mvcOptions => mvcOptions.EnableEndpointRouting = false); services.AddMvc(); //Code keep the same....... }
并且在配置部分我也改为喜欢 .net Core 3.1 及更早版本。但是,通知告诉我没有实现这些的方法或成员:
app.UseMvc(routeBuilder =>
{
routeBuilder.EnableDependencyInjection();
routeBuilder.Select().Filter().Count().Expand().OrderBy().MaxTop(null);
routeBuilder.MapODataServiceRoute("odata", "odata", GetEdmModel());
});
然后我也尝试在Configure中用另一种方式添加,结果一样:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapODataRoute("odata1", "odata", GetEdmModel());
});
我不知道它是如何在 Microsoft.EntityFrameworkCore.InMemory 库上完美运行的,但是当我更改为 SQL 服务器时,一切都不是 运行 如我所料。这是我的文件 appsettings.json 如果你想知道:
{
"ConnectionStrings": {
"DefaultConnection": "Server(localdb)\mssqllocaldb;Database=basenetcore;Trusted_Connection=True
;MultipleActiveResultSets=true"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}
感谢您抽出宝贵时间,希望您度过愉快的一天。
只需删除代码:
[Route("api/[controller]")]
[ApiController]
在你的 UsersController
.