MIssing method in System.Web.Http.ApiController.get_Request() - c#

I have a controller.
public sealed class AccountsController : BaseApiController
{
private readonly IDatabaseAdapter _databaseAdapter;
public AccountsController(IDatabaseAdapter databaseAdapter)
{
_databaseAdapter = databaseAdapter;
}
[AllowAnonymous]
[Route("create")]
public async Task<IHttpActionResult> CreateUser(CreateUserBindingModel createUserModel)
{
if (!ModelState.IsValid)
return BadRequest(ModelState);
if (! await _databaseAdapter.DoesAgentExist(createUserModel.UserName))
return BadRequest();
if (await _databaseAdapter.DoesAgentHaveAccount(createUserModel.UserName))
return BadRequest();
// Create account.
var password = PasswordHelper.GeneratePassword(32);
createUserModel.Password = password;
createUserModel.ConfirmPassword = password;
var user = new ApplicationUser
{
UserName = createUserModel.UserName,
};
var addUserResult = await AppUserManager.CreateAsync(user, createUserModel.Password);
if (!addUserResult.Succeeded)
return GetErrorResult(addUserResult);
var locationHeader = new Uri(Url.Link("GetUserById", new { id = user.Id }));
return Created(locationHeader, ModelFactory.Create(user));
}
}
When I send the following fiddler to the create method.
http://localhost:59430/api/accounts/create User-Agent: Fiddler
Content-Type: application/json Accept: application/json Host:
localhost:59430 Content-Length: 106
{ "UserName":"a.xxxxx", "Password":"xxxxxx",
"ConfirmPassword":"xxxxxx", }
It gets down to the following line:
var addUserResult = await AppUserManager.CreateAsync(user, createUserModel.Password);
Then the following exception occurs
{ "message": "An error has occurred.", "exceptionMessage": "Method
not found: 'System.Net.Http.HttpRequestMessage
System.Web.Http.ApiController.get_Request()'.", "exceptionType":
"System.MissingMethodException", "stackTrace": " at
WebAuth.Controllers.BaseApiController.get_AppUserManager()\r\n at
WebAuth.Controllers.AccountsController.d__3.MoveNext() in
C:\Users\stuarts\Documents\Visual Studio
2017\Projects\WebAuth\WebAuth\Controllers\AccountsController.cs:line
76\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.Threading.Tasks.TaskHelpersExtensions.d__3`1.MoveNext()\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.Web.Http.Controllers.ApiControllerActionInvoker.d__0.MoveNext()\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.Web.Http.Controllers.ActionFilterResult.d__2.MoveNext()\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.Web.Http.Dispatcher.HttpControllerDispatcher.d__1.MoveNext()"
}
Anyone know what is going on? I have no idea why it can't find that method.
My bin folders contains
System.Web.Http.dll
System.Web.Http.Owin.dll
System.Net.Http.dll
ApplicationUserManager
public sealed class ApplicationUserManager : UserManager<ApplicationUser>
{
public ApplicationUserManager(IUserStore<ApplicationUser> store) : base(store)
{
}
public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options,
IOwinContext context)
{
var appDbContext = context.Get<ApplicationDbContext>();
var appUserManager = new ApplicationUserManager(new UserStore<ApplicationUser>(appDbContext));
appUserManager.UserValidator = new UserValidator<ApplicationUser>(appUserManager)
{
AllowOnlyAlphanumericUserNames = true,
RequireUniqueEmail = false,
};
appUserManager.PasswordValidator = new PasswordValidator
{
RequiredLength = 12,
RequireNonLetterOrDigit = true,
RequireUppercase = true,
RequireLowercase = true,
RequireDigit = true
};
appUserManager.MaxFailedAccessAttemptsBeforeLockout = 3;
appUserManager.DefaultAccountLockoutTimeSpan = TimeSpan.FromHours(1);
return appUserManager;
}
}
BaseApiController
public class BaseApiController : ApiController
{
private ModelFactory _modelFactory;
private readonly ApplicationUserManager _applicationUserManager = null;
protected ApplicationUserManager AppUserManager => _applicationUserManager ?? Request.GetOwinContext().GetUserManager<ApplicationUserManager>();
protected ModelFactory ModelFactory => _modelFactory ?? (_modelFactory = new ModelFactory(Request, AppUserManager));
protected IHttpActionResult GetErrorResult(IdentityResult result)
{
if (result == null)
return InternalServerError();
if (result.Succeeded) return null;
if (result.Errors != null)
foreach (var error in result.Errors)
ModelState.AddModelError(string.Empty, error);
if (ModelState.IsValid)
return BadRequest();
return BadRequest(ModelState);
}
private readonly ApplicationRoleManager _appRoleManager = null;
protected ApplicationRoleManager AppRoleManager => _appRoleManager ?? Request.GetOwinContext().GetUserManager<ApplicationRoleManager>();
}

I found a solution to this.
When I was building there was build warnings going to the output window but not showing in the main error / warning window.
They were to do with assembly conflicts and said recommend putting the assembly redirect in the web.Config.
Once I had went through them all (around 80) it now works.
e.g.
<dependentAssembly>
<assemblyIdentity name="System.Net.Http" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="0.0.0.0-4.2.0.0" newVersion="4.2.0.0" />
</dependentAssembly>

Related

Jil.DeserializationException: 'Expected digit'

I am trying to implement the Jil serializer in WebAPI(C#). While deserializing throws the error like "Jil.DeserializationException: 'Expected digit'". I have attached the code samples.
WebApiConfig.cs
config.Formatters.Clear();
var _jilOptions = new Options(dateFormat: DateTimeFormat.ISO8601, excludeNulls: true, includeInherited: true);
config.Formatters.Add(new JilFormatter(_jilOptions));
JilFormatter.cs
public class JilFormatter : MediaTypeFormatter
{
private static readonly MediaTypeHeaderValue _applicationJsonMediaType = new MediaTypeHeaderValue("application/json");
private static readonly MediaTypeHeaderValue _textJsonMediaType = new MediaTypeHeaderValue("text/json");
private readonly Options _options;
public JilFormatter(Options options)
{
_options = options;
SupportedMediaTypes.Add(_applicationJsonMediaType);
SupportedMediaTypes.Add(_textJsonMediaType);
SupportedEncodings.Add(new UTF8Encoding(false, true));
SupportedEncodings.Add(new UnicodeEncoding(false, true, true));
}
public override bool CanReadType(Type type)
{
if (type == null)
return false;
return true;
}
public override bool CanWriteType(Type type)
{
if (type == null)
return false;
return true;
}
public override Task<object> ReadFromStreamAsync(Type type, Stream input, HttpContent content, IFormatterLogger formatterLogger)
{
var reader = new StreamReader(input);
var deserialize = TypedDeserializers.GetTyped(type);
var result = deserialize(reader, _options);
return Task.FromResult(result);
}
public override Task WriteToStreamAsync(Type type, object value, Stream output, HttpContent content, TransportContext transportContext)
{
var writer = new StreamWriter(output);
JSON.Serialize(value, writer, _options);
writer.Flush();
return Task.FromResult(true);
}
}
TypedDeserializers class:
static class TypedDeserializers
{
private static readonly ConcurrentDictionary<Type, Func<TextReader, Options, object>> _methods;
private static readonly MethodInfo _method = typeof(JSON).GetMethod("Deserialize", new[] { typeof(TextReader), typeof(Options) });
static TypedDeserializers()
{
_methods = new ConcurrentDictionary<Type, Func<TextReader, Options, object>>();
}
public static Func<TextReader, Options, object> GetTyped(Type type)
{
return _methods.GetOrAdd(type, CreateDelegate);
}
private static Func<TextReader, Options, object> CreateDelegate(Type type)
{
return (Func<TextReader, Options, object>)_method
.MakeGenericMethod(type)
.CreateDelegate(typeof(Func<TextReader, Options, object>));
}
}
ReuestTest.cs
public class ReuestTest
{
public long UserId { get; set; }
public long MobileDeviceId { get; set; }
public bool IsInitialLoad { get; set; }
}
testController.cs
[HttpPost]
public string GetAllDispatchestest(ReuestTest request)
{
return something;
}
Exception:
{
"Message": "An error has occurred.",
"ExceptionMessage": "Expected digit",
"ExceptionType": "Jil.DeserializationException",
"StackTrace": " at Jil.Deserialize.Methods._ReadInt64(TextReader reader)\r\n at _DynamicMethod4(TextReader , Int32 )\r\n at Jil.JSON.Deserialize[T](TextReader reader, Options options)\r\n at api.myapi.com.Utilities.JilFormatter.ReadFromStreamAsync(Type type, Stream input, HttpContent content, IFormatterLogger formatterLogger) in F:\\Projects\\myapi\\myapi.Solution\\api.myapi.com\\Utilities\\JilFormatter.cs:line 51\r\n at System.Net.Http.Formatting.MediaTypeFormatter.ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger, CancellationToken cancellationToken)\r\n at System.Net.Http.HttpContentExtensions.<ReadAsAsyncCore>d__0`1.MoveNext()\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.Web.Http.ModelBinding.FormatterParameterBinding.<ExecuteBindingAsyncCore>d__0.MoveNext()\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.Web.Http.Controllers.HttpActionBinding.<ExecuteBindingAsyncCore>d__0.MoveNext()\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.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext()\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.Web.Http.Controllers.ExceptionFilterResult.<ExecuteAsync>d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Web.Http.Controllers.ExceptionFilterResult.<ExecuteAsync>d__0.MoveNext()\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.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()"
}

Error with IHttpActionResult in web api actions

I am facing method not found error in web server, but locally in visual studio it works:
[HttpGet]
[Route("api/checkhealth")]
public async Task<IHttpActionResult> CheckHealth()
{
var message = "checkhealth method was invoked";
return new TextResult(message, Request);
}
Then in browser getting below error:
<Error>
<Message>An error has occurred.</Message>
<ExceptionMessage>Method not found: 'System.Net.Http.HttpRequestMessage System.Web.Http.ApiController.get_Request()'.
</ExceptionMessage>
<ExceptionType>System.MissingMethodException</ExceptionType>
<StackTrace>at BMI.Controllers.APIController.<CheckHealth>d__0.MoveNext() at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.Start[TStateMachine](TStateMachine& stateMachine) at BMI.Controllers.APIController.CheckHealth() at lambda_method(Closure , Object , Object[] ) at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass6_3.<GetExecutor>b__2(Object instance, Object[] methodParameters) at
System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken) --- End of stack trace from previous location where exception was thrown --- at
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Controllers.ApiControllerActionInvoker.
<InvokeActionAsyncCore>d__1.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Controllers.ActionFilterResult.
<ExecuteAsync>d__5.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Dispatcher.HttpControllerDispatcher.
<SendAsync>d__15.MoveNext()
</StackTrace>
</Error>
I have implemented IHttpActionResult as below:
public class TextResult : IHttpActionResult
{
string message;
HttpRequestMessage request;
public TextResult(string message, HttpRequestMessage request)
{
this.message = message;
this.request = request;
}
public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
var response = new HttpResponseMessage()
{
Content = new StringContent(message),
RequestMessage = request
};
return Task.FromResult(response);
}
}
The actual method in my project is post but here I am trying to fix with get first then I believe post will also work.
Here to mention the below method work perfectly, so I think something I am missing with IHttpActionResult:
[HttpGet]
[Route("api/getok")]
public JsonResult<string> getJson()
{
return Json("OK");
}
Do you have any one faced and solved this problem yet. Please help me, thanks in advance.
Using the CreateResponse extension on the request would allow any configuration from the request to be copied over to the response which would probably be missing when you create the response manually like in your example.
public class TextResult : IHttpActionResult {
string message;
HttpRequestMessage request;
public TextResult(string message, HttpRequestMessage request) {
this.message = message;
this.request = request;
}
public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken) {
var response = request.CreateResponse(HttpStatusCode.OK, message);
return Task.FromResult(response);
}
}
Also the controller action is not defined correctly as it is defined as async Task<IHttpActionResult> when the action is not doing anything async.
Refactor to follow correct syntax if not actually asynchronous.
[HttpGet]
[Route("api/checkhealth")]
public IHttpActionResult CheckHealth() {
var message = "checkhealth method was invoked";
return new TextResult(message, Request);
}

Injected service not resolved only for Delete action

I have a controller the beginning of which looks like this:
[Route("api/[controller]")]
public class PersonsController : BaseController
BaseController looks like this so far:
public class BaseController : Controller
{
public BaseController(CompanyDbContext dbContext)
{
Db = dbContext;
}
protected CompanyDbContext Db;
}
PersonsController has a few gets, a post, a put, and a delete. Everything except the Delete action works fine, there are no problems resolving the injected CompanyDbContext.
The Delete action looks like this:
[HttpDelete("{id}")]
public async Task<IActionResult> Delete(int id)
{
var pers = await Db.Persons.SingleOrDefaultAsync(p => p.PersonId == id);
if (pers == null)
{
return NotFound();
}
Db.Remove(pers);
await Db.SaveChangesAsync();
return Ok();
}
Yet when I do a delete request:
public async Task DeletePersonAsync(int id)
{
var resp = await _client.DeleteAsync($"api/Persons/{id}");
resp.EnsureSuccessStatusCode();
}
where _client is an HttpClient, I get the following error:
InvalidOperationException: Unable to resolve service for type
'AcmeSoft.Api.Data.CompanyDbContext' while attempting to activate
'AcmeSoft.Api.Controllers.PersonsController'
I am using the default, built-in DI that comes with a new MVC Core 2.0 project. I register the context service in class Startup as follows:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<CompanyDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddMvc();
}
Yet the service resolves properly for all actions but Delete. What could be wrong here? Where have I gone wrong?
For those that like long questions, the entire PersonsController is as follows:
[Route("api/[controller]")]
public class PersonsController : BaseController
{
public PersonsController(CompanyDbContext dbContext) : base(dbContext)
{
}
[HttpGet]
public IActionResult Get()
{
var persons = Db.Persons.ToList();
return Ok(persons);
}
[HttpGet("{id}")]
public async Task<IActionResult> Get(int id)
{
var pers = await Db.Persons.SingleOrDefaultAsync(p => p.PersonId == id);
if (pers == null)
{
return Ok(null);
}
return Ok(pers);
}
[HttpGet("GetByIdNumber/{idNumber}")]
public async Task<IActionResult> GetByIdNumber(string idNumber)
{
var pers = await Db.Persons.SingleOrDefaultAsync(e => e.IdNumber == idNumber);
if (pers == null)
{
return Ok(null);
}
return Ok(pers);
}
[HttpGet("PersonEmployees")]
public async Task<IActionResult> PersonEmployees()
{
var emps = await Db.PersonEmployees.ToListAsync();
return Ok(emps);
}
[HttpPost]
public async Task<IActionResult> Post([FromBody] Person person)
{
Db.Add(person);
await Db.SaveChangesAsync();
return Ok(person);
}
[HttpPut]
public async Task<IActionResult> Put([FromBody] Person person)
{
Db.Update(person);
await Db.SaveChangesAsync();
return Ok(person);
}
[HttpDelete("{id}")]
public async Task<IActionResult> Delete(int id)
{
var pers = await Db.Persons.SingleOrDefaultAsync(p => p.PersonId == id);
if (pers == null)
{
return NotFound();
}
Db.Remove(pers);
await Db.SaveChangesAsync();
return Ok();
}
}
All actions except delete work.
ADDED: The stack trace shown on the developer error page is:
System.InvalidOperationException: Unable to resolve service for type 'AcmeSoft.Api.Data.CompanyDbContext' while attempting to activate 'AcmeSoft.Api.Controllers.PersonsController'.
at Microsoft.Extensions.Internal.ActivatorUtilities.GetService(IServiceProvider sp, Type type, Type requiredBy, Boolean isDefaultParameterRequired)
at lambda_method(Closure , IServiceProvider , Object[] )
at Microsoft.AspNetCore.Mvc.Controllers.ControllerActivatorProvider.<>c__DisplayClass4_0.<CreateActivator>b__0(ControllerContext controllerContext)
at Microsoft.AspNetCore.Mvc.Controllers.ControllerFactoryProvider.<>c__DisplayClass5_0.<CreateControllerFactory>g__CreateController|0(ControllerContext controllerContext)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeInnerFilterAsync>d__14.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.<InvokeNextResourceFilter>d__22.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.<InvokeFilterPipelineAsync>d__17.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.<InvokeAsync>d__15.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Builder.RouterMiddleware.<Invoke>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.<Invoke>d__7.MoveNext()

Property null in web api controller when using Entity Framework 5 and Oracle

i have a problem in a new web api controller when i try to use EF5 with Oracle.
My controller:
public class DeviceV1Controller : ApiController
{
private readonly IDevice _repository;
public DeviceV1Controller()
{
IDevice _repository = new EFDeviceRepository();
}
[Route("api/Device/{hashImei}/app/{nome}")]
public HttpResponseMessage Post(string hashImei, string nome, [FromBody] DeviceInfo deviceInfo)
{
_repository.Add(deviceInfo);
return Request.CreateResponse(HttpStatusCode.OK);
}
}
_repository is correctly bound in the constructor, but entering the Post api this variable become null and i get this error:
{
message: "An error has occurred."
exceptionMessage: "object reference not set to an instance of an object."
exceptionType: "System.NullReferenceException"
stackTrace: " in MpssApiRest.Controllers.DeviceV1Controller.Post(String hashImei, String nome, DeviceInfo deviceInfo) in c:\SVILUPPO\MpssApiRest\MpssApiRest\MpssApiRest\Controllers\DeviceV1Controller.cs:riga 28 in lambda_method(Closure , Object , Object[] ) in System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass10.<GetExecutor>b__9(Object instance, Object[] methodParameters) in System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(Object instance, Object[] arguments) in System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken) --- Fine traccia dello stack da posizione precedente dove è stata generata l'eccezione --- in System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) in System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) in System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__0.MoveNext() --- Fine traccia dello stack da posizione precedente dove è stata generata l'eccezione --- in System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) in System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) in System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext() --- Fine traccia dello stack da posizione precedente dove è stata generata l'eccezione --- in System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) in System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) in System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__0.MoveNext()"
}
EFDeviceRepository concrete class is:
public class EFDeviceRepository : IDevice
{
private readonly EntityDevice ctx;
public EFDeviceRepository()
{
ctx = new EntityDevice();
}
public void Add(Models.V1.DeviceInfo deviceInfo)
{
EntityDevice ctx = new EntityDevice();
MPSS_APP_DEVICE device = new MPSS_APP_DEVICE();
device.HASHIMEI = deviceInfo.HashImei;
ctx.MPSS_APP_DEVICE.Add(device);
ctx.SaveChanges();
}
}
Thanks
EDIT: Sample Web Request (retrieved from the comments)
Ip Address: 192.168.1.129
Url: /myproject/api/device/123456/app/appname
JSON:
{
"applicazione" : "Gestione Interventi",
"hashImei" : "123123121323123121",
"modello" : "Nexus 5",
"pushNotificatioToken" : "oifjwfijowfjfoiwjrgfoirwj42rohfoifrj",
"sistemaOperativo" : "ANDROID", "versione" : "LOLLIPOP_MR1"
}
The reason why _repository is null in your Action is because you are not initializing it in your constructor. Instead you have declared and initialized a local variable of the same name in your constructor!
public class DeviceV1Controller : ApiController
{
private readonly IDevice _repository;
public DeviceV1Controller()
{
_repository = new EFDeviceRepository();
}
// ...
}

Identity IUserEmailStore error on generating password reset token

Questions of some relevancy:
Webforms ASP.NET Identity system reset password
I am trying to implement password recovery using the identity system, but got stuck on the error (Store does not implement IUserEmailStore). Here is what I am doing, I am using Visual Studio 2013 Web. Using Web Forms (MVC learning in progress), the users sign up with their emails, and are stored in the username field in the database.
I have added UserManager Class in the IdentityModel.cs as:
public class UserManager : UserManager<ApplicationUser>
{
public UserManager()
: base(new UserStore<ApplicationUser>(new ApplicationDbContext()))
{
UserValidator = new UserValidator<ApplicationUser>(this) { AllowOnlyAlphanumericUserNames = false };
this.UserTokenProvider = new EmailTokenProvider<ApplicationUser, string>();
this.EmailService = new EmailService();
}
}
public class EmailService : IIdentityMessageService
{
public Task SendAsync(IdentityMessage message)
{
//email service here to send an email.
return Task.FromResult(0);
}
}
In IdentityModels.cs I've also added the helper:
public static string GetResetPasswordRedirectUrl(string code)
{
return "/Account/ResetPassword?" + CodeKey + "=" + HttpUtility.UrlEncode(code);
}
Those are all the changes I made in the IdentityModels.cs Class. Now for the ForgotPassword.aspx page I have done the following:
protected void ResetPassword(object sender, EventArgs e)
{
if (IsValid)
{
var manager = new UserManager();
var user = new ApplicationUser();
user = manager.FindByName(Email.Text);
// Check if the the user does not exist
if (user == null)
{
ErrorText.Text = "User Could not be found.";
return;
}
string token = manager.GeneratePasswordResetToken(user.Id);
string callbackUrl = IdentityHelper.GetResetPasswordRedirectUrl(token);
manager.SendEmail(user.Id, "Reset Password", "Please reset your password by clicking here.");
Link.NavigateUrl = callbackUrl;
}
}
My code gets stuck on
string token = manager.GeneratePasswordResetToken(user.Id);
giving this exception
{"Store does not implement IUserEmailStore<TUser>."}
A detailed information on the exception:
System.NotSupportedException was unhandled by user code
HResult=-2146233067
Message=Store does not implement IUserEmailStore<TUser>.
Source=Microsoft.AspNet.Identity.Core
StackTrace:
at Microsoft.AspNet.Identity.UserManager`2.GetEmailStore()
at Microsoft.AspNet.Identity.UserManager`2.<GetEmailAsync>d__a3.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
at Microsoft.AspNet.Identity.EmailTokenProvider`2.<GetUserModifierAsync>d__11.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
at Microsoft.AspNet.Identity.TotpSecurityStampBasedTokenProvider`2.<GenerateAsync>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
at Microsoft.AspNet.Identity.UserManager`2.<GenerateUserTokenAsync>d__e9.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at Microsoft.AspNet.Identity.UserManager`2.<GeneratePasswordResetTokenAsync>d__4f.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at Microsoft.AspNet.Identity.AsyncHelper.RunSync[TResult](Func`1 func)
at Microsoft.AspNet.Identity.UserManagerExtensions.GeneratePasswordResetToken[TUser,TKey](UserManager`2 manager, TKey userId)
at uCk.Account.ForgotPassword.Forgot(Object sender, EventArgs e) in c:\Users\Tim\Documents\Visual Studio 2013\Projects\uCk\uCk\Account\ForgotPassword.aspx.cs:line 38
at System.Web.UI.WebControls.Button.OnClick(EventArgs e)
at System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument)
at System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument)
at System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument)
at System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData)
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
InnerException:
What I understood from the exception is that I should implement the IUserEmailStore Interface? I am not sure what I am supposed to do here; if you look at the Usermanager() implementation I have added EmailService() shouldn't that be enough? How do I overcome the error and achieve the result expected?
your UserStore<> implementation does not implement IUserEmailStore<> so you need to derive from UserStore<> as well as implement IUserEmailStore<> like so
public class UserStore : UserStore<ApplicationUser>, IUserEmailStore<ApplicationUser>
{
public UserStore() : base(new ApplicationDbContext()){}
public Task<TUser> FindByEmailAsync(string email)
{
//implement
}
//... implement other methods required etc
}
then reference your new store in your manager constructor
public class UserManager : UserManager<ApplicationUser>
{
public UserManager() : base(new UserStore())
{
UserValidator = new UserValidator<ApplicationUser>(this) { AllowOnlyAlphanumericUserNames = false };
this.UserTokenProvider = new EmailTokenProvider<ApplicationUser, string>();
this.EmailService = new EmailService();
}
}

Categories

Resources