Ajax 调用 Web Api 的方法使用 gRPC 服务(如何从数据库中获取列表?):错误 415 和 400
Ajax method calling a Web Api who its consuming a gRPC Service (how to get a list from a db?): Errors 415 and 400
我的 Web 控制台有问题,首先它在 ajax 方法中没有 contentType: 'application/json; charset=UTF-8',
时给我错误 415,然后给我错误 400。
如果错误出现在后端代码中,我也会尝试进行调试,但它从未发生并且会跳出(这没有任何意义,调试器应该 运行...)
我的目标是 return 用户列表和他们的电子邮件,类似这样
//在我的服务中尝试这样做
IEnumerable()
//classc#
显示用户:
(字符串)用户名:User1
(字符串)电子邮件:user1@example.com
但我在 gRPC 中执行此操作,因此我将有一个 Web API 控制器调用 gRPC 方法
由于gRPC中没有IEnumerable,所以我的proto和method是这样的:
原型:
syntax = "proto3";
option csharp_namespace = "GrpcService1.Protos";
package UserAuth;
service UserAuth {
rpc GetAllUsers(MessageRequest) returns(ListUsersResponse);
}
message ListUserResponse{
string username = 1;
string email = 2;
}
message ListUsersResponse{
repeated ListUserResponse lstUsers = 1;
}
message MessageRequest{
string message = 1;
}
gRPC 方法服务 c#
public override Task<ListUsersResponse> GetAllUsers(MessageRequest request, ServerCallContext context)
{
//This gives me an IEnumerable<ShowUsers> (this is
correct)
var a = _userBll.getAllUsers();
//Here in this lines maybe be the problem but I don't
//know where (maybe be because of json type or something into a list)
//here im trying to put separate list of users and emails
var names = a.Select(x => x.Username);
var emails = a.Select(y => y.Email);
//here im trying to put the lists into a Response
var all = new ListUserResponse
{
Username = names.ToString(),
Email = emails.ToString()
};
//the above will give the same but the
ListUsersResponse is a repeated attribute
var response = new ListUsersResponse
{
LstUsers = { all }
};
//all ok
request.Message = "Sucess";
return Task.FromResult(response);
}
下面的代码是正确的(我用 POST 方法测试控制器和 ajax 我在没有 gRPC 的情况下测试并且工作正常)但是你会明白我的意思我正在做(它的控制器和 ajax 方法)
控制器[HTTPGET]:
[HttpGet("getAllUserInfo_2"), Authorize]
public async Task<ActionResult<ListUsersResponse>> GetAll_2([FromBody] MessageRequest message)
{
_logger.Log(LogLevel.Information, "Request Received for AuthController::Register");
var results = await _userClient.GetAllUsersAsync(message);
_logger.Log(LogLevel.Information, "Sending Response from AuthController::Register");
return Ok(results);
}
Ajax方法:
$(function b() {
debugger;
var $users_A = $('#users_A');
$.ajax({
contentType: 'application/json; charset=UTF-8', //if I comment this gives me 415
url: uri_3_2,
type: 'GET',
dataType: 'json',
beforeSend: function(request) {
request.setRequestHeader("Authorization", 'Bearer ' + localStorage.getItem("key"));
},
success: function(date) {
$.each(data, function (i, rice) {
$users_A.append('<li>Name: ' + arroz.username + ' Email: ' + arroz.email + ' </li>');
});
},
error: function (xhr, textStatus, errorThrown) {
console.log('XHR:' + xhr + '\nTextStatus:' + textStatus + '\nErrorThrown:' + errorThrown); //this should give me more info about the error but don't works... But it
//works fine the implementation code
$users_A.append('<h4>ERRRROORRRR</h4>');
}
});
});
欢迎任何帮助
A bi-directional 流式 RPC 将是更好的选择,因为它将
显着提高您的表现并可能解决您的问题。
您需要按以下方式更改原型:
syntax = "proto3";
option csharp_namespace = "GrpcService1.Protos";
package UserAuth;
service UserAuth {
rpc GetAllUsers(MessageRequest) returns(stream UserResponse);
}
message UserResponse{
string username = 1;
string email = 2;
}
message MessageRequest{
string message = 1;
}
gRPC 方法服务 c#
public override async Task GetAllUsers(MessageRequest request, IServerStreamWriter<UserResponse> responseStream, ServerCallContext context)
{
var users = _userBll.getAllUsers();
foreach (user in users)
{
await responseStream.WriteAsync(new UserResponse
{
Username = user.Username.ToString(),
Email = user.Email.ToString()
});
}
}
在客户端:
public async Task<List<UserResponse> GetAllUsers()
{
var userResponseList = new List<UserResponse>();
using var call = client.GetAllUsers(new MessageRequest());
while (await call.ResponseStream.MoveNext())
{
var userResponse = new UserResponse
{
Username = call.ResponseStream.Current.Username,
Email = call.ResponseStream.Current.Email
});
userResponseList.Add(userResponse);
}
return userResponseList;
}
客户端对象来自从 gRPC 服务创建的通道 URL(我假设您知道)。
现在你可以把它变成一个服务,并通过你的控制器的依赖注入来调用它。
我没有测试它,所以它可能有一些编译错误,但方法是正确的。
我的 Web 控制台有问题,首先它在 ajax 方法中没有 contentType: 'application/json; charset=UTF-8',
时给我错误 415,然后给我错误 400。
如果错误出现在后端代码中,我也会尝试进行调试,但它从未发生并且会跳出(这没有任何意义,调试器应该 运行...)
我的目标是 return 用户列表和他们的电子邮件,类似这样
//在我的服务中尝试这样做
IEnumerable()
//classc#
显示用户:
(字符串)用户名:User1
(字符串)电子邮件:user1@example.com
但我在 gRPC 中执行此操作,因此我将有一个 Web API 控制器调用 gRPC 方法
由于gRPC中没有IEnumerable,所以我的proto和method是这样的:
原型:
syntax = "proto3";
option csharp_namespace = "GrpcService1.Protos";
package UserAuth;
service UserAuth {
rpc GetAllUsers(MessageRequest) returns(ListUsersResponse);
}
message ListUserResponse{
string username = 1;
string email = 2;
}
message ListUsersResponse{
repeated ListUserResponse lstUsers = 1;
}
message MessageRequest{
string message = 1;
}
gRPC 方法服务 c#
public override Task<ListUsersResponse> GetAllUsers(MessageRequest request, ServerCallContext context)
{
//This gives me an IEnumerable<ShowUsers> (this is
correct)
var a = _userBll.getAllUsers();
//Here in this lines maybe be the problem but I don't
//know where (maybe be because of json type or something into a list)
//here im trying to put separate list of users and emails
var names = a.Select(x => x.Username);
var emails = a.Select(y => y.Email);
//here im trying to put the lists into a Response
var all = new ListUserResponse
{
Username = names.ToString(),
Email = emails.ToString()
};
//the above will give the same but the
ListUsersResponse is a repeated attribute
var response = new ListUsersResponse
{
LstUsers = { all }
};
//all ok
request.Message = "Sucess";
return Task.FromResult(response);
}
下面的代码是正确的(我用 POST 方法测试控制器和 ajax 我在没有 gRPC 的情况下测试并且工作正常)但是你会明白我的意思我正在做(它的控制器和 ajax 方法)
控制器[HTTPGET]:
[HttpGet("getAllUserInfo_2"), Authorize]
public async Task<ActionResult<ListUsersResponse>> GetAll_2([FromBody] MessageRequest message)
{
_logger.Log(LogLevel.Information, "Request Received for AuthController::Register");
var results = await _userClient.GetAllUsersAsync(message);
_logger.Log(LogLevel.Information, "Sending Response from AuthController::Register");
return Ok(results);
}
Ajax方法:
$(function b() {
debugger;
var $users_A = $('#users_A');
$.ajax({
contentType: 'application/json; charset=UTF-8', //if I comment this gives me 415
url: uri_3_2,
type: 'GET',
dataType: 'json',
beforeSend: function(request) {
request.setRequestHeader("Authorization", 'Bearer ' + localStorage.getItem("key"));
},
success: function(date) {
$.each(data, function (i, rice) {
$users_A.append('<li>Name: ' + arroz.username + ' Email: ' + arroz.email + ' </li>');
});
},
error: function (xhr, textStatus, errorThrown) {
console.log('XHR:' + xhr + '\nTextStatus:' + textStatus + '\nErrorThrown:' + errorThrown); //this should give me more info about the error but don't works... But it
//works fine the implementation code
$users_A.append('<h4>ERRRROORRRR</h4>');
}
});
});
欢迎任何帮助
A bi-directional 流式 RPC 将是更好的选择,因为它将 显着提高您的表现并可能解决您的问题。
您需要按以下方式更改原型:
syntax = "proto3";
option csharp_namespace = "GrpcService1.Protos";
package UserAuth;
service UserAuth {
rpc GetAllUsers(MessageRequest) returns(stream UserResponse);
}
message UserResponse{
string username = 1;
string email = 2;
}
message MessageRequest{
string message = 1;
}
gRPC 方法服务 c#
public override async Task GetAllUsers(MessageRequest request, IServerStreamWriter<UserResponse> responseStream, ServerCallContext context)
{
var users = _userBll.getAllUsers();
foreach (user in users)
{
await responseStream.WriteAsync(new UserResponse
{
Username = user.Username.ToString(),
Email = user.Email.ToString()
});
}
}
在客户端:
public async Task<List<UserResponse> GetAllUsers()
{
var userResponseList = new List<UserResponse>();
using var call = client.GetAllUsers(new MessageRequest());
while (await call.ResponseStream.MoveNext())
{
var userResponse = new UserResponse
{
Username = call.ResponseStream.Current.Username,
Email = call.ResponseStream.Current.Email
});
userResponseList.Add(userResponse);
}
return userResponseList;
}
客户端对象来自从 gRPC 服务创建的通道 URL(我假设您知道)。 现在你可以把它变成一个服务,并通过你的控制器的依赖注入来调用它。 我没有测试它,所以它可能有一些编译错误,但方法是正确的。