调试时HTTP请求出现webbeexception

本文关键字:webbeexception 请求 HTTP 调试 | 更新日期: 2023-09-27 18:10:19

我有一个ASP。它涉及到通过Web-API框架发送HTTP请求。以下异常仅在调试时引发:

服务器违反了协议。节= ResponseStatusLine

如果我"Start Without Debugging",项目运行完美。

如何解决这个异常?

任何帮助都是感激的!


问题似乎与ASP有关。. NET MVC身份框架。

要访问其他Web-API方法,客户端应用程序必须首先POST一个登录请求(登录请求不需要是安全的,所以我直接将用户名和密码字符串发送给Web-API POST方法)。如果我注释掉登录请求,则不会再引发异常。

下面是相关的代码片段:

Post方法:

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;
} 

Account Access类(模拟MVC模板中的默认AccountController):

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);
    }
}

下面是相关的代码片段:

在客户端应用程序中:

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;
}

在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;
}

我有一些观察:

  1. 我认为我可能需要异步发送请求(使用async-await语法),但异常仍然持续存在。
  2. 如果我步进代码,请求确实进入HTTP方法,但是在返回响应之前代码在随机行中断(为什么?!),所以我假设没有响应被发送回来。
  3. 我尝试了以下解决方案,如回答类似问题所建议的,这些都不适合我:
    • 设置useUnsafeHeaderParsingtrue
    • 添加标题Keep-Alive: false
    • 更改Skype的端口设置(我没有Skype,端口80和443未被占用)

附加信息,如果它们很重要:

  • Mac OS运行Windows 8.1 with VMware Fusion
  • Visual Studio 2013
  • 。. NET Framework 4.5
  • IIS Express Server

更新2

异常被解决了,但是我不确定是哪个修改解决了这个问题。我敢说,下面的一个或两个都可以解决这个问题:

  • 我有一个checkConnection()方法,它基本上发送一个GET请求并在成功时返回true。我将await添加到HttpClient.SendAsync()方法中,并强制异步一直向上
  • 我收回了MainWindow构造函数中的所有代码,除了InitializeComponent()方法,到Window Initialized事件处理程序。

任何想法?

下面是上述修改的相关代码:

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;
    }
}

窗口初始化事件处理程序(从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.";
    }
}

更新3

虽然这可能有点偏离主题,但我想添加一个旁注,以防其他人陷入这种情况- 我一直在使用错误的身份验证方法来开始Web-API。 Web-API项目模板已经有一个内置的身份框架,我不知何故"取代"它与一个相当简单但破碎的方法…

这个视频是一个很好的入门教程。

本文提供了更全面的解释。

调试时HTTP请求出现webbeexception

在客户端应用程序中,您没有等待task。不等待就访问Result可能会导致不可预测的错误。如果它只是在调试模式下失败,我不能肯定,但它肯定不是同一个程序(添加了额外的检查,通常没有启用优化)。不管什么时候调试是激活的,如果你有一个代码错误,你应该修复它,它应该在两种模式下工作。

因此,要么使该函数异步并使用await修饰符调用任务,要么在任务上调用task.WaitAndUnwrapException(),这样它将同步阻塞,直到结果从服务器返回。

确保URL具有ID查询字符串,其值为项目A或项目b。否则,您将返回没有Http状态码200的内容,这可能导致违反协议。

当您使用SendAsync时,您需要自己提供所有相关的消息头,例如包括message.Headers.Authorization = new AuthenticationHeaderValue("Basic", token);
您可能希望使用GetAsync(并在服务器上调用特定的get方法)。
另外,您确定异常已经解决了吗?如果您有一些高级async方法返回Task而不是void,则该异常可能会被静默忽略。