且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Response status code does not indicate success: 401 (Unauthorized).

更新时间:2022-09-05 12:11:09

在使用ASP.NET5调用IBM Bluemix上的REST API服务时出现此异常;

Response status code does not indicate success: 401 (Unauthorized).  
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at dotnethelloworld.Controllers.ValuesController.<Get>d__1.MoveNext()

相关代码:

        // GET api/values/txt
        [HttpGet("{txt}")]
        public async Task<string> Get(string txt)
        {
            String retString = txt;
            try
            {
                //构造url,source为要翻译文本的语言,target指定要翻译为什么语言
                String uri = "https://gateway.watsonplatform.net/language-translation/api/v2/translate?";
                uri += "source=en&target=es&text=" + txt;

                System.Net.Http.HttpClientHandler handler = new System.Net.Http.HttpClientHandler();
                NetworkCredential myCred = new NetworkCredential("用户名", "密码", "gateway.watsonplatform.net");
                CredentialCache myCache = new CredentialCache();
                myCache.Add(new Uri(uri), "Basic", myCred);
                handler.Credentials = myCache;
                System.Net.Http.HttpClient httpClient = new System.Net.Http.HttpClient(handler);
                
                retString = await httpClient.GetStringAsync(uri);
                return "{\"text\":\"" + retString + "\"}";
            }
            catch (Exception ex)
            {
                return ex.Message;
                //throw ex;
            }
        }

MSDN中关于NetworkCredential 类的使用示例:

NetworkCredential myCred = new NetworkCredential(
	SecurelyStoredUserName,SecurelyStoredPassword,SecurelyStoredDomain);

CredentialCache myCache = new CredentialCache();

myCache.Add(new Uri("www.contoso.com"), "Basic", myCred);
myCache.Add(new Uri("app.contoso.com"), "Basic", myCred);

WebRequest wr = WebRequest.Create("www.contoso.com");
wr.Credentials = myCache;
只是它是用的WebRequest,而我是用的HttpClient,却不生效,没有找到具体原因;但可以通过另一种方法来解决用户验证的问题。

解决方法:

设置httpClient.DefaultRequestHeaders.Authorization 属性,代码如下:

System.Net.Http.HttpClient httpClient = new System.Net.Http.HttpClient();
//将服务凭证转换为Base64编码格式
byte[] auth = Encoding.UTF8.GetBytes("用户名:密码");
String auth64 = Convert.ToBase64String(auth);
//创建并指定服务凭证,认证方案为Basic
httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", auth64);

retString = await httpClient.GetStringAsync(uri);