C# VisualStudio调试WebApi

C# VisualStudio调试WebApi,c#,asp.net-mvc-4,asp.net-web-api,visual-studio-debugging,C#,Asp.net Mvc 4,Asp.net Web Api,Visual Studio Debugging,我在VS2013中编写了一个WebApi项目。我还编写了一个MVC4应用程序,在同一台机器上用VS2013对其进行测试 我在VS2013中运行WebApi项目,它使用localhost:49494作为服务器:端口 然后我在VS2013中运行测试项目,它使用localhost:49319作为server:port 我从测试项目中调用WebApi中的一个路由,得到的响应是401(未经授权)。我没有在WebApi函数上使用Authorize属性。我也不从我的测试项目发送WWW认证头 为什么我会得到这个

我在VS2013中编写了一个WebApi项目。我还编写了一个MVC4应用程序,在同一台机器上用VS2013对其进行测试

我在VS2013中运行WebApi项目,它使用localhost:49494作为服务器:端口 然后我在VS2013中运行测试项目,它使用localhost:49319作为server:port

我从测试项目中调用WebApi中的一个路由,得到的响应是401(未经授权)。我没有在WebApi函数上使用Authorize属性。我也不从我的测试项目发送WWW认证头

为什么我会得到这个?我就是不明白。当我在浏览器中运行WebApi调用的URL时,我得到了期望的结果

这是调用MVC4操作的HTML:

<!DOCTYPE html>
<html>
    <head>
        <title>Webinar Registration Test </title>
    </head>
    <body>
        <div class="document">
        <form name="LoginForm" action="/Home/WBLogin" method="post">
            <input type="submit" value="Login" />
        </form>
        </div>
    </body>
</html>
public ActionResult WBLogin()
{
    string uri = "http://localhost:49494/api/Webinar/WBLogin";
    AuthModel auth = new AuthModel();
    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri);
    request.Accept = "application/json";
    request.Method = "GET";
    try
    {
        var response = request.GetResponse();

        //the following lines duplicate the response stream so we can read it for
        //deserialization and also re-read it and write it out.

        using (MemoryStream ms = new MemoryStream())
        {
            var stream = response.GetResponseStream();
            stream.CopyTo(ms);
            ms.Position = 0;
            stream.Close();

            DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(ResponseDirectLogin));
            var deserialized = (ResponseDirectLogin)ser.ReadObject(ms);
            auth.OauthToken = deserialized.AccessToken;
            auth.OrganizerKey = deserialized.OrganizerKey;
        }
    }
    catch (WebException e)
    {
        if (e.Response != null) {
            using (var sr = new StreamReader(e.Response.GetResponseStream()))
                ViewBag.Error = sr.ReadToEnd();
        }
        else
        {
            ViewBag.Error = String.Concat("Message: ", e.Message, " Status: ", e.Status);
        }
    }
    Registrant User = new Registrant();
    User.OauthToken = auth.OauthToken;
    User.OrganizerKey = auth.OrganizerKey;                              
    User.WebinarKey = "9999999999999999999";
    return RedirectToAction("WBRegister", "Home", User);
}
public class WebinarController : ApiController
{

    [HttpGet, Route("api/Webinar/WBLogin")]
    public IHttpActionResult WBLogin()
    {
        // The Login Model contains the Login credentials for our GTW account
        LoginModel lg = new LoginModel();

        // first we need to create the uri for the web request
        string uri = String.Format("https://api.citrixonline.com/oauth/access_token?grant_type=password&user_id={0}&password={1}&client_id={2}",
                         lg.UserId, lg.Password, lg.APIKey);

        // then the request to login is created and sent. From the response
        // we need to store at least the access token and the organizer key
        // to use for further calls

        HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri);
        request.Accept = "application/json";
        request.ContentType = "application/json";

        try
        {
            var response = request.GetResponse();

            //the following lines duplicate the response stream so we can read it for
            //deserialization and also re-read it and write it out.

            using (MemoryStream ms = new MemoryStream())
            {
                var stream = response.GetResponseStream();
                stream.CopyTo(ms);
                ms.Position = 0;
                stream.Close();

                DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(ResponseDirectLogin));
                var deserialized = (ResponseDirectLogin)ser.ReadObject(ms);
                LoginResponse lr = new LoginResponse();
                lr.OauthToken = deserialized.AccessToken;
                lr.OrganizerKey = deserialized.OrganizerKey;
                string json_result = JsonConvert.SerializeObject(lr);
                return Ok(json_result);
            }
        }
        catch (WebException e)
        {
            using (var sr = new StreamReader(e.Response.GetResponseStream()))
            {
                LoginErrorResponse ler = new LoginErrorResponse();
                ler.Message = sr.ReadToEnd();
                string json_result = JsonConvert.SerializeObject(ler);
                return BadRequest(json_result);
            }
        }
    }

    // other methods here...

}
这是WebApi方法:

<!DOCTYPE html>
<html>
    <head>
        <title>Webinar Registration Test </title>
    </head>
    <body>
        <div class="document">
        <form name="LoginForm" action="/Home/WBLogin" method="post">
            <input type="submit" value="Login" />
        </form>
        </div>
    </body>
</html>
public ActionResult WBLogin()
{
    string uri = "http://localhost:49494/api/Webinar/WBLogin";
    AuthModel auth = new AuthModel();
    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri);
    request.Accept = "application/json";
    request.Method = "GET";
    try
    {
        var response = request.GetResponse();

        //the following lines duplicate the response stream so we can read it for
        //deserialization and also re-read it and write it out.

        using (MemoryStream ms = new MemoryStream())
        {
            var stream = response.GetResponseStream();
            stream.CopyTo(ms);
            ms.Position = 0;
            stream.Close();

            DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(ResponseDirectLogin));
            var deserialized = (ResponseDirectLogin)ser.ReadObject(ms);
            auth.OauthToken = deserialized.AccessToken;
            auth.OrganizerKey = deserialized.OrganizerKey;
        }
    }
    catch (WebException e)
    {
        if (e.Response != null) {
            using (var sr = new StreamReader(e.Response.GetResponseStream()))
                ViewBag.Error = sr.ReadToEnd();
        }
        else
        {
            ViewBag.Error = String.Concat("Message: ", e.Message, " Status: ", e.Status);
        }
    }
    Registrant User = new Registrant();
    User.OauthToken = auth.OauthToken;
    User.OrganizerKey = auth.OrganizerKey;                              
    User.WebinarKey = "9999999999999999999";
    return RedirectToAction("WBRegister", "Home", User);
}
public class WebinarController : ApiController
{

    [HttpGet, Route("api/Webinar/WBLogin")]
    public IHttpActionResult WBLogin()
    {
        // The Login Model contains the Login credentials for our GTW account
        LoginModel lg = new LoginModel();

        // first we need to create the uri for the web request
        string uri = String.Format("https://api.citrixonline.com/oauth/access_token?grant_type=password&user_id={0}&password={1}&client_id={2}",
                         lg.UserId, lg.Password, lg.APIKey);

        // then the request to login is created and sent. From the response
        // we need to store at least the access token and the organizer key
        // to use for further calls

        HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri);
        request.Accept = "application/json";
        request.ContentType = "application/json";

        try
        {
            var response = request.GetResponse();

            //the following lines duplicate the response stream so we can read it for
            //deserialization and also re-read it and write it out.

            using (MemoryStream ms = new MemoryStream())
            {
                var stream = response.GetResponseStream();
                stream.CopyTo(ms);
                ms.Position = 0;
                stream.Close();

                DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(ResponseDirectLogin));
                var deserialized = (ResponseDirectLogin)ser.ReadObject(ms);
                LoginResponse lr = new LoginResponse();
                lr.OauthToken = deserialized.AccessToken;
                lr.OrganizerKey = deserialized.OrganizerKey;
                string json_result = JsonConvert.SerializeObject(lr);
                return Ok(json_result);
            }
        }
        catch (WebException e)
        {
            using (var sr = new StreamReader(e.Response.GetResponseStream()))
            {
                LoginErrorResponse ler = new LoginErrorResponse();
                ler.Message = sr.ReadToEnd();
                string json_result = JsonConvert.SerializeObject(ler);
                return BadRequest(json_result);
            }
        }
    }

    // other methods here...

}

我有一种强烈的感觉,它是一个全球性的过滤器。检查
App\u Start\FilterConfig.cs
,确保没有附加
authorized属性

,这是一个证书问题。我的系统管理员必须在我们的服务器上安装他们的证书才能允许这样做。

听起来像是CORS问题。你能为你的api编写一个Fiddler请求吗?我不是用javascript来调用,我是用HttpWebRequest。API不是公共的。我们可以在WebAPI中看到路由以及在测试项目中对此路由的调用吗?测试项目在调试时,由于401错误,永远无法访问WebAPI函数。但是如果我在浏览器中运行,它显然会进入WebApi函数。(我的意思是,我们能看到代码吗)不,只有
HandleErrorAttribute