Tôi có một dự án ASP.NET liên quan đến việc gửi yêu cầu HTTP qua khung Web-API. Ngoại lệ sau chỉ được nâng lên khi gỡ lỗi:WebException về yêu cầu HTTP trong khi gỡ lỗi
Máy chủ đã vi phạm giao thức. Section = ResponseStatusLine
Dự án chạy hoàn hảo nếu tôi "Bắt đầu không gỡ lỗi".
Tôi nên giải quyết ngoại lệ này như thế nào?
Mọi trợ giúp đều được đánh giá cao!
Cập nhật
Vấn đề dường như có liên quan đến ASP.NET MVC nhận dạng khung.
Để truy cập các phương pháp Web-API khác, ứng dụng khách phải POST lần đầu tiên yêu cầu đăng nhập (Yêu cầu đăng nhập không cần bảo mật và vì vậy tôi gửi chuỗi tên người dùng và mật khẩu trực tiếp tới Web -API POST method). Nếu tôi nhận xét yêu cầu đăng nhập, không có ngoại lệ nào được nêu ra.
Dưới đây là các đoạn mã liên quan:
Phương pháp mới gởi:
UserManager<ApplicationUser> UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));
AccountAccess ac = new AccountAccess();
public async Task<HttpResponseMessage> Post()
{
string result = await Request.Content.ReadAsStringAsync();
LoginMessage msg = JsonConvert.DeserializeObject<LoginMessage>(result);
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
var user = UserManager.Find(msg.username, msg.password);
if (user == null)
return response;
if (user.Roles == null)
return response;
var role = from r in user.Roles where (r.RoleId == "1" || r.RoleId == "2") select r;
if (role.Count() == 0)
{
return response;
}
bool task = await ac.LoginAsync(msg.username, msg.password);
response.Content = new StringContent(task.ToString());
return response;
}
Lớp Tài khoản Access (mô phỏng AccountController mặc định trong MVC mẫu):
public class AccountAccess
{
public static bool success = false;
public AccountAccess()
: this(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext())))
{
}
public AccountAccess(UserManager<ApplicationUser> userManager)
{
UserManager = userManager;
}
public UserManager<ApplicationUser> UserManager { get; private set; }
public async Task<bool> LoginAsync(string username, string password)
{
var user = await UserManager.FindAsync(username, password);
if (user != null)
{
await SignInAsync(user, isPersistent: false);
return true;
}
else
{
return false;
}
}
~AccountAccess()
{
if (UserManager != null)
{
UserManager.Dispose();
UserManager = null;
}
}
private IAuthenticationManager AuthenticationManager
{
get
{
return HttpContext.Current.GetOwinContext().Authentication;
}
}
private async Task SignInAsync(ApplicationUser user, bool isPersistent)
{
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity);
}
}
Dưới đây là những đoạn có liên quan mã:
Trong ứng dụng client:
public static async Task<List<T>> getItemAsync<T>(string urlAction)
{
message = new HttpRequestMessage();
message.Method = HttpMethod.Get;
message.RequestUri = new Uri(urlBase + urlAction);
HttpResponseMessage response = await client.SendAsync(message);
string result = await response.Content.ReadAsStringAsync();
List<T> msgs = JsonConvert.DeserializeObject<List<T>>(result);
return msgs;
}
Trong điều khiển Web API:
public HttpResponseMessage Get(string id)
{
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
if (id == "ItemA")
{
List<ItemAMessage> msgs = new List<ItemAMessage>();
// some code...
response.Content = new StringContent(JsonConvert.SerializeObject(msgs));
}
else if (id == "ItemB")
{
List<ItemBMessage> msgs = new List<ItemBMessage>();
// some code...
response.Content = new StringContent(JsonConvert.SerializeObject(msgs));
}
return response;
}
Một số quan sát tôi có:
- Tôi tôi nghĩ rằng tôi có thể cần phải gửi yêu cầu không đồng bộ (với cú pháp
async-await
), nhưng ngoại lệ vẫn tồn tại theo cách đó. - Nếu tôi bước qua mã, yêu cầu làm nhập phương thức HTTP, nhưng mã ngắt ở dòng ngẫu nhiên (Tại sao ?!) trước khi trả lời, vì vậy tôi cho rằng không có phản hồi nào được gửi lại.
- Tôi đã thử các giải pháp sau đây, như đề xuất trong câu trả lời cho câu hỏi tương tự, không ai trong số đó làm việc cho tôi:
- Thiết
useUnsafeHeaderParsing
đểtrue
- Thêm tiêu đề
Keep-Alive: false
- Thay đổi cài đặt cổng của Skype (Tôi không có Skype và cổng 80 và 443 không bị chiếm đóng)
- Thiết
Thông tin bổ sung rmation, trong trường hợp họ có vấn đề:
- Mac OS chạy Windows 8.1 với VMware Fusion
- Visual Studio 2013
- .NET Framework 4.5
- IIS tốc máy chủ
Cập nhật 2
Trường hợp ngoại lệ được giải quyết, nhưng tôi không chắc chắn về việc sửa đổi nào đã thực hiện thủ thuật. AFAIK, một trong hai hoặc cả hai điều sau đây đã sửa lỗi:
- Tôi có phương thức
checkConnection()
, về cơ bản gửi yêu cầu GET và trả về thành công. Tôi đã thêmawait
vào phương phápHttpClient.SendAsync()
và được thực thi không đồng bộ tất cả các cách thức lên. - Tôi đã rút lại tất cả mã trong hàm tạo MainWindow, ngoại trừ phương thức
InitializeComponent()
, vào trình xử lý sự kiện Windows Initializedized.
Bất kỳ ý tưởng nào?
Dưới đây là mã có liên quan đến những sửa đổi được minh họa ở trên:
phương pháp checkConnectionAsync:
public static async Task<bool> checkConnectionAsync()
{
message = new HttpRequestMessage();
message.Method = HttpMethod.Get;
message.RequestUri = new Uri(urlBase);
try
{
HttpResponseMessage response = await client.SendAsync(message);
return (response.IsSuccessStatusCode);
}
catch (AggregateException)
{
return false;
}
}
Window xử lý sự kiện khởi tạo (rút từ các nhà xây dựng MainWindow):
private async void Window_Initialized(object sender, EventArgs e)
{
if (await checkConnectionAsync())
{
await loggingIn();
getItemA();
getItemB();
}
else
{
logMsg.Content = "Connection Lost. Restart GUI and try again.";
}
}
Cập nhật 3
Mặc dù đây có thể là một chút off-topic, tôi muốn thêm một mặt lưu ý trong trường hợp bất cứ ai khác rơi vào này - Tôi đã sử dụng phương pháp xác thực sai cho Web-API để bắt đầu. Mẫu dự án Web-API đã có sẵn một khuôn khổ Identity tích hợp, và bằng cách nào đó tôi đã "thay thế" nó bằng một cách tiếp cận khá đơn giản nhưng bị hỏng ...
This video là một hướng dẫn tốt để bắt đầu.
This article cung cấp giải thích toàn diện hơn.
Điều gì sẽ xảy ra nếu bạn xóa cuộc gọi ngủ trong LoginAsync? –
@Brianfromstatefarm Tôi thực sự đã thêm dòng đó để kiểm tra nội dung khác và quên xóa nó khi đăng mã. Cảm ơn bạn đã chỉ ra! –
Có thể VM đang thêm vào vấn đề này không? –