Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用web api中的过滤器传递带有错误消息的状态_C#_Asp.net Web Api_Asp.net Web Api2 - Fatal编程技术网

C# 如何使用web api中的过滤器传递带有错误消息的状态

C# 如何使用web api中的过滤器传递带有错误消息的状态,c#,asp.net-web-api,asp.net-web-api2,C#,Asp.net Web Api,Asp.net Web Api2,我不知道我在哪里找不到,如果用户名和密码有误,我会一直发送错误消息。我的服务运行良好,如果用户id和密码与200状态和手动创建的状态不匹配,我可以手动发送错误消息。这是我创建的HandleRequest类的代码 public class HandleRequest : Attribute, IAuthenticationFilter { public string Realm { get; set; } public async Task Auth

我不知道我在哪里找不到,如果用户名和密码有误,我会一直发送错误消息。我的服务运行良好,如果用户id和密码与200状态和手动创建的状态不匹配,我可以手动发送错误消息。这是我创建的
HandleRequest
类的代码

public class HandleRequest : Attribute, IAuthenticationFilter
    {
        public string Realm { get; set; }




        public async Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
        {
            //throw new NotImplementedException();
            HttpRequestMessage request = context.Request;
            AuthenticationHeaderValue authorization = request.Headers.Authorization;

            string status = await SendAsync(request, cancellationToken);


            if (context.Request.RequestUri.LocalPath == "/Login/UserLogin")
            {
                return;
            }
            else if (authorization == null)
            {
                // No authentication was attempted (for this authentication method).
                // Do not set either Principal (which would indicate success) or ErrorResult (indicating an error).
                context.ErrorResult = new AuthenticationFailureResult("Null auth token..", request);
                return;
            }
            else if (status == "Success")
            {
                return;
            }
            else
            {
                context.ErrorResult = new AuthenticationFailureResult("Invalid auth token..", request);
                return;
            }
        }


        public Task ChallengeAsync(HttpAuthenticationChallengeContext context, CancellationToken cancellationToken)
        {
            Challenge(context);
            return Task.FromResult(0);
        }

        private void Challenge(HttpAuthenticationChallengeContext context)
        {
            string parameter;

            if (String.IsNullOrEmpty(Realm))
            {
                parameter = null;
            }
            else
            {
                // A correct implementation should verify that Realm does not contain a quote character unless properly
                // escaped (precededed by a backslash that is not itself escaped).
                parameter = "realm=\"" + Realm + "\"";
            }

            context.ChallengeWith("Basic", parameter);
        }

        public virtual bool AllowMultiple
        {
            get { return false; }
        }




        private static bool TryRetrieveToken(HttpRequestMessage request, out string token)
        {
            token = null;
            IEnumerable<string> authzHeaders;
            if (!request.Headers.TryGetValues("Authorization", out authzHeaders) || authzHeaders.Count() > 1)
            {
                return false;
            }
            var bearerToken = authzHeaders.ElementAt(0);
            token = bearerToken.StartsWith("Bearer ") ? bearerToken.Substring(7) : bearerToken;
            return true;
        }

        public async Task<string> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {

            string status = "";
            HttpStatusCode statusCode;
            string token;
            //determine whether a jwt exists or not
            if (!TryRetrieveToken(request, out token))
            {
                statusCode = HttpStatusCode.Unauthorized;
                //allow requests with no token - whether a action method needs an authentication can be set with the claimsauthorization attribute
                //return base.SendAsync(request, cancellationToken);
            }

            try
            {
                string sec = WebConfigurationManager.AppSettings["sec"];
                var now = DateTime.UtcNow;
                var securityKey = new Microsoft.IdentityModel.Tokens.SymmetricSecurityKey(System.Text.Encoding.Default.GetBytes(sec));


                SecurityToken securityToken;
                JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler();
                TokenValidationParameters validationParameters = new TokenValidationParameters()
                {
                    ValidAudience = "http://localhost:1987",
                    ValidIssuer = "http://localhost:1987",
                    ValidateLifetime = true,
                    ValidateIssuerSigningKey = true,
                    LifetimeValidator = this.LifetimeValidator,
                    IssuerSigningKey = securityKey
                };
                //extract and assign the user of the jwt
                Thread.CurrentPrincipal = handler.ValidateToken(token, validationParameters, out securityToken);
                HttpContext.Current.User = handler.ValidateToken(token, validationParameters, out securityToken);


                var identity = (ClaimsPrincipal)Thread.CurrentPrincipal;


                var id = int.Parse(identity.Claims.Where(c => c.Type == "id")
                  .Select(c => c.Value).SingleOrDefault());


                bool isValidToken = IsValidToken(id, userName, type);
                if (isValidToken == true)
                {
                    status = "Success";
                }
                else
                {
                    statusCode = HttpStatusCode.Unauthorized;
                    status = "Unauthorized";
                }

            }
            catch (SecurityTokenValidationException e)
            {
                e.Message.ToString();
                statusCode = HttpStatusCode.Unauthorized;
                status = "Unauthorized";
            }
            catch (Exception ex)
            {
                ex.Message.ToString();
                statusCode = HttpStatusCode.InternalServerError;
                status = "InternalServerError";
            }

            return status;
        }
        public bool LifetimeValidator(DateTime? notBefore, DateTime? expires, SecurityToken securityToken, TokenValidationParameters validationParameters)
        {
            if (expires != null)
            {
                if (DateTime.UtcNow < expires) return true;
            }
            return false;
        }

        private bool IsValidToken(int? id, string userName, string type)
        {
            bool isValid = false;
            using (MCSDEMOEntities con = new MCSDEMOEntities())
            {
                var GetUserDatails = (from u in con.ios_Users
                                      where u.ID == id && u.LOGIN == userName && u.TYPEDESCR == type
                                      select u).ToList();
                if (GetUserDatails.Count == 1)
                {
                    isValid = true;
                }
                else
                {
                    isValid = false;
                }
            }

            return isValid;
        }


    }





    public static class HttpRequestHeadersExtensions
    {
        public static void Set(this HttpRequestHeaders headers, string name, string value)
        {
            if (headers.Contains(name)) headers.Remove(name);
            headers.Add(name, value);
        }
    }

    public static class HttpAuthenticationChallengeContextExtensions
    {
        public static void ChallengeWith(this HttpAuthenticationChallengeContext context, string scheme)
        {
            ChallengeWith(context, new AuthenticationHeaderValue(scheme));
        }

        public static void ChallengeWith(this HttpAuthenticationChallengeContext context, string scheme, string parameter)
        {
            ChallengeWith(context, new AuthenticationHeaderValue(scheme, parameter));
        }

        public static void ChallengeWith(this HttpAuthenticationChallengeContext context, AuthenticationHeaderValue challenge)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            context.Result = new AddChallengeOnUnauthorizedResult(challenge, context.Result);
        }
    }


    public class AddChallengeOnUnauthorizedResult : IHttpActionResult
    {
        public AuthenticationHeaderValue Challenge { get; private set; }
        public IHttpActionResult InnerHttpResult { get; private set; }

        public AddChallengeOnUnauthorizedResult(AuthenticationHeaderValue challenge, IHttpActionResult innerResult)
        {
            Challenge = challenge;
            InnerHttpResult = innerResult;
        }

        public async Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
        {
            HttpResponseMessage response = await InnerHttpResult.ExecuteAsync(cancellationToken);

            if (response.StatusCode == HttpStatusCode.Unauthorized)
            {
                // Only add one challenge per authentication scheme.
                if (!response.Headers.WwwAuthenticate.Any((h) => h.Scheme == Challenge.Scheme))
                {
                    response.Headers.WwwAuthenticate.Add(Challenge);
                }
            }

            return response;
        }
    }

    public class AuthenticationFailureResult : IHttpActionResult
    {
        public string ReasonPhrase { get; private set; }
        public HttpRequestMessage Request { get; private set; }

        public AuthenticationFailureResult(string reasonPhrase, HttpRequestMessage request)
        {
            ReasonPhrase = reasonPhrase;
            Request = request;
        }

        public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
        {
            return Task.FromResult(execute());
        }

        private HttpResponseMessage execute()
        {
            HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
            response.RequestMessage = Request;
            response.ReasonPhrase = ReasonPhrase;
            return response;
        }
    }
和我的登录控制器

  public class LoginController : ApiController
    {
        LoginModel logMod = new LoginModel();
        LoginResponse logResp = new LoginResponse();


        [HttpPost]
        public  LoginResponse UserLogin(LoginRequest logReq)
        {
            logResp = logMod.UserLogin(logReq );
            return logResp;
        }
    }
登录模型类

        public  LoginResponse UserLogin(LoginRequest LogReq)
        {

            LoginResponse logResp = new LoginResponse();
            try
            {
                if (LogReq.userName != "" && LogReq.password != "")
                {
                    using (MCSDEMOEntities DataModel = new MCSDEMOEntities())
                    {
                        var UserDetails = (from user in DataModel.ios_Users
                                           where (user.LOGIN == LogReq.userName && user.PASSWORD == LogReq.password && user.ACTIVE != 0)
                                           select new
                                           {
                                               user.ID,
                                               user.TYPEDESCR,
                                               user.USERNAME
                                           }).ToList();
                        if (UserDetails.Count != 0)
                        {
                            foreach (var Udetails in UserDetails)
                            {
                                logResp.id = Udetails.ID;
                                logResp.type = Udetails.TYPEDESCR;
                                logResp.userName = Udetails.USERNAME;
                            }
                            //create jwt token.
                            logResp.userToken = createToken(logResp.id, logResp.type, LogReq.userName);
                            logResp.Status = "Success";
                        }
                        else
                        {
                            logResp.Status = "401";
                            //throw new HttpResponseException("Customer Name cannot be empty", HttpStatusCode.BadRequest);
                          // throw new AuthenticationFailureResult("","")
                        }
                    }
                }
                else
                {
                    logResp.Status = "No Condition Match";
                }

            }
            catch (Exception ex)
            {
                logResp.Status = ex.Message.ToString();
            }

            return logResp;
        }


在上面的代码中,它很好地实现了服务,但即使用户id和密码不匹配,它也会发送http-200OK消息,状态为json中的-401。我想用代码401传递http,您需要从api返回
HttpResponseMessage
,以便用其他信息(如状态)包装响应对象

    [HttpPost]
    public  HttpResponseMessage UserLogin(LoginRequest logReq)
    {
        logResp = logMod.UserLogin(logReq );
        // Decide based on your logic. This is
        // a mock example. 
        var status = HttpStatusCode.OK
        return Request.CreateResponse(HttpStatusCode.OK, logResp);
    }
您可以在此处找到更多信息:

引述:

HttpResponseMessage直接转换为HTTP响应

其他类型将序列化返回值写入响应体;返回200(正常)


谢谢,这给了我一个主意。。你的逻辑运作得很好:)祝你有一个美好的一天:)
    [HttpPost]
    public  HttpResponseMessage UserLogin(LoginRequest logReq)
    {
        logResp = logMod.UserLogin(logReq );
        // Decide based on your logic. This is
        // a mock example. 
        var status = HttpStatusCode.OK
        return Request.CreateResponse(HttpStatusCode.OK, logResp);
    }