简体   繁体   English

错误:ASP.NET WebAPI中的System.InvalidOperationException

[英]Error: System.InvalidOperationException in ASP.NET WebAPI

I'm trying to enter some data into database and get access_token on the end of successful call. 我正在尝试将一些数据输入数据库并在成功调用结束时获取access_token。

When I make a call passing this parameters: 当我通过这个参数进行调用时:

在此输入图像描述

Everything goes fine, user gets registered and saved into database, and access_token returns to user: 一切顺利,用户注册并保存到数据库中,access_token返回给用户:

在此输入图像描述

But, when I add signs +, = or \\ in the deviceId value I get exception and nothing get saved in database: 但是,当我在deviceId值中添加符号+,=或\\时,我得到异常,并且没有任何内容保存在数据库中:

在此输入图像描述

在此输入图像描述

{
    "message": "An error has occurred.",
    "exceptionMessage": "Error getting value from 'ReadTimeout' on 'Microsoft.Owin.Host.SystemWeb.CallStreams.InputStream'.",
    "exceptionType": "Newtonsoft.Json.JsonSerializationException",
    "stackTrace": "   at Newtonsoft.Json.Serialization.DynamicValueProvider.GetValue(Object target)\r\n   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.CalculatePropertyValues(JsonWriter writer, Object value, JsonContainerContract contract, JsonProperty member, JsonProperty property, JsonContract& memberContract, Object& memberValue)\r\n   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)\r\n   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)\r\n   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeDictionary(JsonWriter writer, IDictionary values, JsonDictionaryContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)\r\n   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)\r\n   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)\r\n   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)\r\n   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)\r\n   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)\r\n   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeDictionary(JsonWriter writer, IDictionary values, JsonDictionaryContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)\r\n   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)\r\n   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)\r\n   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)\r\n   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)\r\n   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)\r\n   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter, Object value, Type objectType)\r\n   at Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter jsonWriter, Object value, Type objectType)\r\n   at Newtonsoft.Json.JsonSerializer.Serialize(JsonWriter jsonWriter, Object value)\r\n   at System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, Encoding effectiveEncoding)\r\n   at System.Net.Http.Formatting.JsonMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, Encoding effectiveEncoding)\r\n   at System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, HttpContent content)\r\n   at System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStreamAsync(Type type, Object value, Stream writeStream, HttpContent content, TransportContext transportContext, CancellationToken cancellationToken)\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()\r\n   at System.Web.Http.Owin.HttpMessageHandlerAdapter.<BufferResponseContentAsync>d__13.MoveNext()",
    "innerException": {
        "message": "An error has occurred.",
        "exceptionMessage": "Timeouts are not supported on this stream.",
        "exceptionType": "System.InvalidOperationException",
        "stackTrace": "   at System.IO.Stream.get_ReadTimeout()\r\n   at Microsoft.Owin.Host.SystemWeb.CallStreams.DelegatingStream.get_ReadTimeout()\r\n   at GetReadTimeout(Object )\r\n   at Newtonsoft.Json.Serialization.DynamicValueProvider.GetValue(Object target)"
    }
}

This is model definition for this call: 这是此调用的模型定义:

public class Registration
    {
        public string UserName { get; set; }
        public string Password{ get; set; }
        public string DeviceId { get; set; }
        public string DeviceName { get; set; }
    }

Field deviceId gets saved into database as UserName, and by it's definition it is NVARCHAR(1024) 字段deviceId以UserName的形式保存到数据库中,根据它的定义,它是NVARCHAR(1024)

在此输入图像描述

Is it possible that NVARCHAR doesn't allow characters that are not letters and numbers? NVARCHAR是否可能不允许不是字母和数字的字符? Did someone else had problem like this? 别人有这样的问题吗?

EDIT: This is the method where the problem is: 编辑:这是问题的方法:

[Route("registration/request")]
public async Task<HttpResponseMessage> RegistrationRequest(Registration model)
{
    try
    {
        MatrixLogManager.Info("Starting token creating.");

        var request = HttpContext.Current.Request;
        var tokenServiceUrl = request.Url.GetLeftPart(UriPartial.Authority) + request.ApplicationPath + "/Token";

        MatrixLogManager.Info("Checking if model is valid.");
        if (!ModelState.IsValid)
        {
            return Request.CreateResponse(BadRequest(ModelState));
        }
        using (MatrixServiceLayerLogin login = new MatrixServiceLayerLogin())
        {
            if (login.LoginUser(model.UserName, model.Password, true, true))
            {
                var personId = login.GetPersonId();

                MatrixLogManager.Debug("User " + model.UserName + "successfully logged in on MatrixSTS.");
                try
                {
                    using (var authRepo = new AuthRepository())
                    {
                        ApplicationUser appUser = new UserFactory().CreateApplicationUser(model, personId);
                        IdentityResult result = await authRepo.RegisterUser(appUser);
                        EMailService.SendEmail(appUser);
                        IHttpActionResult errorResult = GetErrorResult(result);

                        if (errorResult != null)
                        {
                            return Request.CreateResponse(errorResult);
                        }

                        using (var client = new HttpClient())
                        {
                            var requestParams = new List<KeyValuePair<string, string>>
                                                {
                                                    new KeyValuePair<string, string>("grant_type", "password"),
                                                    new KeyValuePair<string, string>("username", appUser.UserName),
                                                    new KeyValuePair<string, string>("password", "0000")
                                                };

                            var requestParamsFormUrlEncoded = new FormUrlEncodedContent(requestParams);
                            var tokenServiceResponse = await client.PostAsync(tokenServiceUrl, requestParamsFormUrlEncoded);
                            var responseString = await tokenServiceResponse.Content.ReadAsStringAsync();
                            var responseCode = tokenServiceResponse.StatusCode;
                            var responseMsg = new HttpResponseMessage(responseCode)
                            {
                                Content = new StringContent(responseString, Encoding.UTF8, "application/json")
                            };

                            responseMsg.Headers.Add("PSK", appUser.PSK);
                            return responseMsg;
                        }
                    }
                }
                catch (Exception ex)
                {
                    MatrixLogManager.Error("Error: ", ex);
                    throw ex;
                }
            }
            else
            {
                return Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "Invalid username or password.");
            }
        }
    }
    catch (Exception ex)
    {
        MatrixLogManager.Error(string.Format("Error while trying registring user: Exception = {0} InnerException {1}", ex.Message, ex.InnerException.Message));
        throw;
    }
}

Try-Catch does not catch any exception, the real exception happens here: Try-Catch没有捕获任何异常,真正的异常发生在这里:

public async Task<IdentityResult> RegisterUser(ApplicationUser userModel)
{
    userModel.TwoFactorEnabled = true;
    userModel.PSK = TimeSensitivePassCode.GeneratePresharedKey();

    var result = await _userManager.CreateAsync(userModel, "0000");

    return result;
}

When the line where the result is returns to client. 当结果返回客户端的行。 I've gues that saving in line before doesn't go well. 我猜想在之前保存不顺利。 I will set try-catch in that part of code and I will post exception. 我将在该部分代码中设置try-catch,我将发布异常。

This usually happens when you're wrapping a Response twice. 当您将响应包装两次时,通常会发生这种情况。

Consider your method returns Task<IHttpActionResult> instead of Task<HttpResponseMessage> and note how you are wrapping that errorResult twice when calling: 考虑你的方法返回Task<IHttpActionResult>而不是Task<HttpResponseMessage>并注意你在调用时如何包装errorResult两次:

return Request.CreateResponse(errorResult);

this is probably leading you to believe that errors in your token service are causing this issue, when the double-wrapping in fact is :) 这可能会让你相信你的令牌服务中的错误导致了这个问题,当双重包装实际上是:)

consider the following: 考虑以下:

[Route("registration/request")]
public async Task<IHttpResult> RegistrationRequest(Registration model)
{
    try
    {
        MatrixLogManager.Info("Starting token creating.");

        var request = HttpContext.Current.Request;
        var tokenServiceUrl = request.Url.GetLeftPart(UriPartial.Authority) + request.ApplicationPath + "/Token";

        MatrixLogManager.Info("Checking if model is valid.");
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }
        using (MatrixServiceLayerLogin login = new MatrixServiceLayerLogin())
        {
            if (login.LoginUser(model.UserName, model.Password, true, true))
            {
                var personId = login.GetPersonId();

                MatrixLogManager.Debug("User " + model.UserName + "successfully logged in on MatrixSTS.");
                try
                {
                    using (var authRepo = new AuthRepository())
                    {
                        ApplicationUser appUser = new UserFactory().CreateApplicationUser(model, personId);
                        IdentityResult result = await authRepo.RegisterUser(appUser);
                        EMailService.SendEmail(appUser);
                        IHttpActionResult errorResult = GetErrorResult(result);

                        if (errorResult != null)
                        {
                            // MAJOR CHANGE here
                            return errorResult;
                        }

                        using (var client = new HttpClient())
                        {
                            var requestParams = new List<KeyValuePair<string, string>>
                                                {
                                                    new KeyValuePair<string, string>("grant_type", "password"),
                                                    new KeyValuePair<string, string>("username", appUser.UserName),
                                                    new KeyValuePair<string, string>("password", "0000")
                                                };

                            var requestParamsFormUrlEncoded = new FormUrlEncodedContent(requestParams);
                            var tokenServiceResponse = await client.PostAsync(tokenServiceUrl, requestParamsFormUrlEncoded);
                            var responseString = await tokenServiceResponse.Content.ReadAsStringAsync();
                            var responseCode = tokenServiceResponse.StatusCode;
                            var responseMsg = new HttpResponseMessage(responseCode)
                            {
                                Content = new StringContent(responseString, Encoding.UTF8, "application/json")
                            };

                            responseMsg.Headers.Add("PSK", appUser.PSK);
                            return responseMsg;
                        }
                    }
                }
                catch (Exception ex)
                {
                    MatrixLogManager.Error("Error: ", ex);
                    throw ex;
                }
            }
            else
            {
                return Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "Invalid username or password.");
            }
        }
    }
    catch (Exception ex)
    {
        MatrixLogManager.Error(string.Format("Error while trying registring user: Exception = {0} InnerException {1}", ex.Message, ex.InnerException.Message));
        throw;
    }
}

I cant see your full implementation, but if I were take an educated guess, you are likely trying to call your login routine, which returns a HttpResponseMessage data type (from within your Register routine). 我看不到你的完整实现,但如果我采取有根据的猜测,你可能会尝试调用你的登录例程,它会返回一个HttpResponseMessage数据类型(来自你的Register例程)。 And both of these methods make use of Request.CreateResponse to create the response. 这两种方法都使用Request.CreateResponse来创建响应。

See the problem is, that you are trying to serialize an already serialized HttpResponseMessage. 看问题是,您正在尝试序列化已经序列化的HttpResponseMessage。 Your Login method will call Request.CreateResponse to create the HttpResponseMessage which you probably just turn around and "pass-through" to your Register method (but are likely funneling it through another Request.CreateResponse method call --- which is where you get into trouble). 您的Login方法将调用Request.CreateResponse来创建HttpResponseMessage,您可能只需转向并“传递”到您的Register方法(但很可能通过另一个Request.CreateResponse方法调用汇集它 - 这是您进入的地方麻烦)。 IT is an "implicit" mistake and tough to catch - something like a chess player staring at the chess board for hours. 这是一个“隐含”的错误,很难捕捉到 - 像棋手一样盯着国际象棋棋盘几个小时。

Now for the solution: simply pass the result of your login method as the result of your register method without "processing" it through the Request.CreateResponse method. 现在解决方案:只需将登录方法的结果作为register方法的结果传递,而不通过Request.CreateResponse方法“处理”它。 If you are a purist of Rest returned status codes, you can change the returned status code first prior to returning the Register method (because Login is likely to have a status code of OK [200] - whereas it is better practice to return CREATED [201] in the Register rest end point). 如果您是Rest返回状态代码的纯粹主义者,则可以在返回Register方法之前更改返回的状态代码(因为Login可能具有OK [200]的状态代码 - 而更好的做法是返回CREATED [ 201]在注册休息终点)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 ASP.Net 错误 System.InvalidOperationException - ASP.Net error System.InvalidOperationException System.InvalidOperationException:无法解析 ASP.NET Core 中的服务 - System.InvalidOperationException: Unable to resolve service in ASP.NET Core ASP.NET 核心 API System.InvalidOperationException 在本地化 - ASP.NET Core API System.InvalidOperationException in localization ASP.NET 核心错误:System.InvalidOperationException:尝试激活时无法解析服务类型 - ASP.NET Core error: System.InvalidOperationException: Unable to resolve service for type while attempting to activate EF继续抛出错误System.InvalidOperationException ASP.NET MVC - EF keep throwing error System.InvalidOperationException ASP.NET MVC ASP.NET 错误:内部服务器错误:System.InvalidOperationException:尝试激活时无法解析服务类型 - ASP.NET Error: Internal Server Error: System.InvalidOperationException: Unable to resolve service for type while attempting to activate ASP.NET Core 6 Web API 的集成测试抛出 System.InvalidOperationException - Integration test for ASP.NET Core 6 web API throws System.InvalidOperationException Asp.net 核心System.InvalidOperationException: 无法追踪实体类型x的实例 - Asp.net core System.InvalidOperationException: The instance of entity type x cannot be tracked ASP.NET 核心 Web API - System.InvalidOperationException: LINQ 表达式 'DbSet<mandate> ()</mandate> - ASP.NET Core Web API - System.InvalidOperationException: The LINQ expression 'DbSet<Mandate>() ASP.NET Web服务:身份验证失败。 ExceptionType“:” System.InvalidOperationException” - ASP.NET WebService: Authentication failed. ExceptionType“:”System.InvalidOperationException"
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM