【问题标题】:StatusCode: 401, ReasonPhrase: 'Unauthorized' gets displayed when calling a Post Method through HTTPClient using C#StatusCode:401,ReasonPhrase:使用 C# 通过 HTTPClient 调用 Post 方法时显示“未授权”
【发布时间】:2017-08-11 16:37:14
【问题描述】:

我正在尝试通过 HTTP 客户端访问 API 的 Post 方法并传递 AuthToken。当我尝试在 post man 中访问时,我能够得到响应,但是当我在 C# 中运行时,我得到了 StatusCode: 401, ReasonPhrase: 'Unauthorized' 错误。我正在共享 Postman 的请求和响应屏幕以及我的代码。谁能告诉我我在代码中犯的错误以及如何解决这个问题。

Postman Request Header and Response Body

Postman Request Body

下面是我的 C# 代码。

    public class PostEmpData
{
    public string cExternalGUID = "10134", 
    cEmployeeID = "10134", cLastName = "Anderson", cFirstName = "Derek", cAccessGroup = "", cActive = "A";
    public int nCardNumber = 10134, nPayMethod = 2;
    public string[] cGroupsList = new string[0] { };
    public DateTime dHireDate = DateTime.Parse("1999 / 11 / 03"), dTermDate = DateTime.Parse("01 / 01 / 0001"), dRateEffectiveDate = DateTime.Parse("2017 - 07 - 15");
    public decimal nPayRate = 1500;
}

    public class PostEmployeeClass
{
    public int _interfaceID { get; set; }
    public int _errorCode { get; set; }
    public string _errorDescription { get; set; }
    public List<EmpPostResponse> respList;
}

public class EmpPostResponse
{
    public string RetKey { get; set; }
    public int ErrorCode { get; set; }
    public string Description { get; set; }
    public string Success { get; set; }
    public string SecondaryList { get; set; }
}


     static async Task<List<EmpPostResponse>> CallPostEmployeeAsync(object postdata)
    {
        Console.WriteLine("Post Employee Process Started");
        PostEmployeeClass authclass = null;
        List<EmpPostResponse> data = null;
        HttpResponseMessage response = await client.PostAsJsonAsync("xxxxxxV2/api/ED907F98-9132-4C7D-B4D4-7648A2577F6D/Integration/employees", postdata);
        response.EnsureSuccessStatusCode();

        if (response.IsSuccessStatusCode)
        {
            Console.WriteLine("success");
            authclass = await response.Content.ReadAsAsync<PostEmployeeClass>();

            data = authclass.respList;
        }
        else
            Console.WriteLine("fail:" + response.StatusCode.ToString());

        return data;
    }
    static void Main(string[] args)
    {
        Console.WriteLine("Starting the Process");
        RunAsync().Wait();
    }
    static async Task RunAsync()
    {
        PostEmpData objPost = new PostEmpData();
        client.BaseAddress = new Uri("https://xxxx.xxxxx.com/");
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        try
        {
            string AuthToken="XXXXXXXXXXXXX";
            client.DefaultRequestHeaders.Add("AuthToken",  AuthToken);

            Console.WriteLine(AuthToken);

            var postdata = CallPostEmployeeAsync(objPost);

        }catch(Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }

【问题讨论】:

  • 安装 Fiddler,将 Postman 与 C# 请求进行比较并找出不同之处。
  • 发现问题的最佳方法是使用像wireshark或fiddler这样的嗅探器。将使用 post man 的 http 标头与您的 http 客户端进行比较。从初始请求中的第一个标头开始,使其看起来与邮递员标头完全相同。
  • 在写代码之前一定要在 Postman 上试一试。
  • 如果我查看屏幕截图,我会看到状态 200 OK。所以看来你可以调用api。对吗?
  • 是的,我可以从 Postman 调用 API,问题在于 C# 代码传递 AuthToken。

标签: c# api httpclient postman dotnet-httpclient


【解决方案1】:

我查看了您的代码,发现了一些问题。

一件事是行不通的:PostEmpData 将序列化为一个空对象,因为它不包含任何属性。所以主体将类似于:{}。您需要向该类添加属性:

public class PostEmpData
{
    public string cExternalGUID { get; set; } = "10134";
    public string cEmployeeID { get; set; } = "10134";
    public string cLastName { get; set; } = "Anderson";
    public string cFirstName { get; set; } = "Derek";
    public string cAccessGroup { get; set; } = "";
    public string cActive { get; set; } = "A";
    public int nCardNumber { get; set; } = 10134;
    public int nPayMethod { get; set; } = 2;
    public string[] cGroupsList  { get; set; }= new string[0] { };
    public DateTime dHireDate  { get; set; }= DateTime.Parse("1999 / 11 / 03");
    public DateTime dTermDate  { get; set; }= DateTime.Parse("01 / 01 / 0001");
    public DateTime dRateEffectiveDate  { get; set; }= DateTime.Parse("2017 - 07 - 15");
    public decimal nPayRate  { get; set; }= 1500;
}

这很可能会导致未经授权的响应。而且它可能与令牌无关。

与 Postman 请求相比,还有另一个不同之处。使用 Postman,您发送一个对象数组 [{}],但使用代码您发送一个对象。因此,您可能必须发布 PostEmpData 列表。

【讨论】:

  • 感谢您的回复,它确实帮助我解决了这个问题。我对我的课程进行了一些更改,现在效果很好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-21
  • 1970-01-01
  • 2016-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多