I am trying to create some regression tests that make async calls to our API. I have been getting a null reference error consistently no matter what I try. I have tried several different ways of calling the request to no avail. I'm at my wit's end. I can put a breakpoint in the code to check the URL and run that URL in Postman and it returns data as expected. I am passing a few headers but nothing out of the ordinary.
Below is the stack trace and my code. Can anyone see what I am missing?
Thanks
<GetApiResponse>d__17`1.MoveNext() in C:\Users\foo\Documents\test.api\Common\Base.cs:line 199
--- 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 Test.API.ResultsTest.<ResultsAPI_SortByLowToHigh>d__1.MoveNext() in C:\Users\voo\Documents\test.api\ResultsTest.cs:line 74
--- 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.GetResult()
Result Message:
Test method Test.API.ResultsAPI_SortByLowToHigh threw exception:
System.NullReferenceException: Object reference not set to an instance of an object.
try
{
var webRequest = WebRequest.Create(url);
webRequest.Method = "GET";
webRequest.ContentType = "application/json";
webRequest.Headers.Add("ApiVersion", "1");
webRequest.Headers.Add("Country-Code", "US");
webRequest.Headers.Add("Currency-Code", "USD");
Task<WebResponse> responseTask = webRequest.GetResponseAsync();
using (var webResponse = await responseTask)
{
using (var sres = webResponse.GetResponseStream())
{
var ms = new MemoryStream();
if (sres != null) await sres.CopyToAsync((ms));
ms.Position = 0;
using (var sr = new StreamReader(ms))
{
JsonResponse = sr.ReadToEnd();
}
}
}
if (!string.IsNullOrEmpty(JsonResponse))
{
response = JsonConvert.DeserializeObject<ServiceResponse>(JsonResponse);
}
else
{
throw new Exception(typeof(ServiceResponse).Name + " API returned null Response");
}
return response;
}
catch (WebException e)
{
ErrorMsg.AppendLine(e.Message);
throw;
}
Related
using MVC jQuery .NET Core
using Abp Background Job
I have a background job that get Enqueued correctly and I can see the job in the db.
However the logging shows me I'm getting and authorization error (ee below) despite being logged in. I have the same AbpAuthorize attributes placed on the services and background jobs.
Not sure how to proceed debugging the problem - any suggestions welcome.
SERVICE CODE USING/ENQUEUING THE JOB:
public async Task BulkImportBackground(IList<CreatePracticeDto> inputs)
{
await _backgroundJobManager.EnqueueAsync<ImportBulkPracticesBackgroundJob, ImportBulkPracticesBackgroundJobArgs>(
new ImportBulkPracticesBackgroundJobArgs
{
CreatePracticeDtos = inputs
});
_backgroundJobManager.Start();
}
JOB CLASS CODE:
using Abp.Authorization;
using Abp.BackgroundJobs;
using Abp.Dependency;
using Abp.Modules;
using Gp.Authorization;
using Gp.Ccre.ImportResult;
using Gp.Ccre.ImportResult.Dtos;
using Gp.Ccre.Practice.Dtos;
using System;
using System.Collections.Generic;
using System.Linq;
using Abp.Domain.Uow;
namespace Gp.Ccre.Practice.BackgroundJobs
{
[DependsOn(
typeof(IPracticeAppService),
typeof(IImportResultsAppService))]
[AbpAuthorize(PermissionNames.Pages_Practices, RequireAllPermissions = false)]
public class ImportBulkPracticesBackgroundJob : BackgroundJob<ImportBulkPracticesBackgroundJobArgs>, ITransientDependency
{
private readonly IPracticeAppService _practiceAppService;
private readonly IImportResultsAppService _importResultsAppService;
public ImportBulkPracticesBackgroundJob(IImportResultsAppService importResultsAppService, IPracticeAppService practiceAppService)
{
_practiceAppService = practiceAppService;
_importResultsAppService = importResultsAppService;
}
public override void Execute(ImportBulkPracticesBackgroundJobArgs args)
{
IList<CreateImportResultDto> createResultsDto = new List<CreateImportResultDto>();
var k = 0;
DateTime importedOn = DateTime.Now;
foreach (CreatePracticeDto createDto in args.CreatePracticeDtos)
{
k++;
try
{
//this correctly automatically ignores 'soft' deleted records.
var count = _practiceAppService.GetAllIdName().Result.Count(x => x.Name.Equals(createDto.Name, StringComparison.CurrentCultureIgnoreCase));
if (count > 0)
{
createResultsDto.Add(new CreateImportResultDto
{
Row = k,
Name = createDto.Name,
Message = "Already exists. Skipped.",
MessageType = AppConsts.ImportMessageType.Warning.ToString(),
ImportedOn = importedOn
});
continue;
}
// ** GOOGLE MAP API CALL **
var coordinatesFound = false; //_practiceAppService.TryGetGeoCodeAddress(createDto);
createDto.ImportedOn = importedOn;
// *** SAVE SINGLE ****
_practiceAppService.Create(createDto);
createResultsDto.Add(new CreateImportResultDto
{
Row = k,
Name = createDto.Name,
Message = "Successful.",
MessageType = AppConsts.ImportMessageType.Info.ToString(),
ImportedOn = importedOn,
GoogleMapCoordinatesFound = coordinatesFound
});
}
catch (Exception e)
{
createResultsDto.Add(new CreateImportResultDto
{
Row = k,
Name = createDto.Name,
Message = e.Message,
MessageType = AppConsts.ImportMessageType.Error.ToString(),
ImportedOn = importedOn
});
continue;
}
}
//*** SAVE RESULTS ***
foreach (var resultDto in createResultsDto)
{
_importResultsAppService.Create(resultDto);
}
CurrentUnitOfWork.SaveChanges();
}
}
[Serializable]
public class ImportBulkPracticesBackgroundJobArgs
{
public IList<CreatePracticeDto> CreatePracticeDtos { get; set; }
}
}
STACK TRACE (partial)
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> Abp.Authorization.AbpAuthorizationException: Current user did not login to the application!
at Abp.Authorization.AuthorizationHelper.AuthorizeAsync(IEnumerable`1 authorizeAttributes) in D:\Github\aspnetboilerplate\src\Abp\Authorization\AuthorizationHelper.cs:line 43
at Abp.Authorization.AuthorizationHelper.CheckPermissions(MethodInfo methodInfo, Type type) in D:\Github\aspnetboilerplate\src\Abp\Authorization\AuthorizationHelper.cs:line 98
at Abp.Authorization.AuthorizationHelper.AuthorizeAsync(MethodInfo methodInfo, Type type) in D:\Github\aspnetboilerplate\src\Abp\Authorization\AuthorizationHelper.cs:line 57
at Nito.AsyncEx.Synchronous.TaskExtensions.WaitAndUnwrapException(Task task)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location where exception was thrown ---
at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot)
--- End of stack trace from previous location where exception was thrown ---
at Nito.AsyncEx.Synchronous.TaskExtensions.WaitAndUnwrapException(Task task)
at Nito.AsyncEx.AsyncContext.Run(Func`1 action)
at Abp.Authorization.AuthorizationInterceptor.Intercept(IInvocation invocation) in D:\Github\aspnetboilerplate\src\Abp\Authorization\AuthorizationInterceptor.cs:line 20
at Castle.DynamicProxy.AbstractInvocation.Proceed()
--- End of inner exception stack trace ---
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at Abp.BackgroundJobs.BackgroundJobManager.TryProcessJob(BackgroundJobInfo jobInfo) in D:\Github\aspnetboilerplate\src\Abp\BackgroundJobs\BackgroundJobManager.cs:line 119
The problem was caused by trying to inject a service into the background job. stick to IRepository and all good.
I need some support regarding InAppBillingPlugin for Xamarin.Forms. First of all I did configuration according to documnetation: https://jamesmontemagno.github.io/InAppBillingPlugin/
application, Google Console (managed products) and iTunes Connect site.
Here is my application code.
private async Task TryInAppPurchace(string androidProductId, string iOSProductId="")
{
if (!CrossInAppBilling.IsSupported)
return;
//Android
var products = new string[] { androidProductId };
if(Device.RuntimePlatform == Device.iOS)
products = new string[] { iOSProductId };
var billing = CrossInAppBilling.Current;
//billing.InTestingMode = true;
try
{
var connected = await billing.ConnectAsync(ItemType.InAppPurchase);
if (!connected)
{
await Application.Current.MainPage.DisplayAlert("Connectivity Error", "Unable to connect to the internet.", "OK");
return;
}
var items = await billing.GetProductInfoAsync(ItemType.InAppPurchase, products);
var item = items.ToList().First();
//try to purchase item
var purchase = await billing.PurchaseAsync(item.ProductId, ItemType.InAppPurchase, item.ProductId);
//possibility that a null came through.
if (purchase == null)
{
await Application.Current.MainPage.DisplayAlert("Purchase Error", "You are unable to buy this product.", "OK");
return;
}
else
{
await _pageService.DisplayAlert("Purchased", "Consumable product.", "OK");
if (Device.RuntimePlatform == Device.iOS)
return;
var consumedItem = await CrossInAppBilling.Current.ConsumePurchaseAsync(purchase.ProductId, purchase.PurchaseToken);
if (consumedItem != null)
{
await Application.Current.MainPage.DisplayAlert("New Package added", "Successfully added new package", "OK");
}
}
}
catch (InAppBillingPurchaseException purchaseEx)
{
var message = string.Empty;
await Application.Current.MainPage.DisplayAlert("Exeption", purchaseEx.Message, "OK");
switch (purchaseEx.PurchaseError)
{
case PurchaseError.BillingUnavailable:
message = "BillingUnavailable";
break;
case PurchaseError.DeveloperError:
message = "DeveloperError";
break;
case PurchaseError.ItemUnavailable:
message = "ItemUnavailable";
break;
case PurchaseError.GeneralError:
message = "GeneralError";
break;
case PurchaseError.UserCancelled:
message = "UserCancelled.";
break;
case PurchaseError.AppStoreUnavailable:
message = "AppStoreUnavailable.";
break;
case PurchaseError.PaymentNotAllowed:
message = "PaymentNotAllowed.";
break;
case PurchaseError.PaymentInvalid:
message = "PaymentInvalid";
break;
case PurchaseError.InvalidProduct:
message = "InvalidProduct";
break;
case PurchaseError.ProductRequestFailed:
message = "ProductRequestFailed";
break;
case PurchaseError.RestoreFailed:
message = "RestoreFailed";
break;
case PurchaseError.ServiceUnavailable:
message = "ServiceUnavailable";
break;
}
}
catch (Exception ex)
{
//Something else has gone wrong, log it
await Application.Current.MainPage.DisplayAlert("Exeption", ex.Message, "OK");
}
finally
{
await billing.DisconnectAsync();
}
}
My problem is that I am not able to buy the same product again and I am getting exeption from Google Play:
{Plugin.InAppBilling.Abstractions.InAppBillingPurchaseException:
Unable to process purchase. at
Plugin.InAppBilling.InAppBillingImplementation+d__33.MoveNext
() [0x00116] in
C:\projects\inappbillingplugin\src\Plugin.InAppBilling.Android\InAppBillingImplementation.cs:324
--- End of stack trace from previous location where exception was thrown --- at
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw ()
[0x0000c] in :0 at
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess
(System.Threading.Tasks.Task task) [0x0003e] in
:0 at
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification
(System.Threading.Tasks.Task task) [0x00028] in
:0 at
System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd
(System.Threading.Tasks.Task task) [0x00008] in
:0 at
System.Runtime.CompilerServices.TaskAwaiter`1[TResult].GetResult ()
[0x00000] in :0 at
Plugin.InAppBilling.InAppBillingImplementation+d__32.MoveNext
() [0x00090] in
C:\projects\inappbillingplugin\src\Plugin.InAppBilling.Android\InAppBillingImplementation.cs:264
--- End of stack trace from previous location where exception was thrown --- at
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw ()
[0x0000c] in :0 at
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess
(System.Threading.Tasks.Task task) [0x0003e] in
:0 at
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification
(System.Threading.Tasks.Task task) [0x00028] in
:0 at
System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd
(System.Threading.Tasks.Task task) [0x00008] in
:0 at
System.Runtime.CompilerServices.TaskAwaiter`1[TResult].GetResult ()
[0x00000] in :0 at
DrivingCourse_app.ViewModels.AccessPageViewModel+d__18.MoveNext
() [0x0025c] in
C:\Projects\GIT-REPO\DrivingCourse_DE\DrivingCourse_app\DrivingCourse_app\DrivingCourse_app\ViewModels\AccessPageViewModel.cs:136
}
Is something wrong with my code? This code is working for every fist purchase of the product, so configuration itself and the general process works.
Any ideas?
getting the error while calling the "SignalR: Caller is not authorized to invoke the LoadPvtChatHistory_Hub method" also IsAuthenticated always gets false.
public class QueryStringBearerAuthorizeAttribute : AuthorizeAttribute
{
public override bool AuthorizeHubConnection(Microsoft.AspNet.SignalR.Hubs.HubDescriptor hubDescriptor, IRequest request)
{
var dataProtectionProvider = new Microsoft.Owin.Security.DataProtection.DpapiDataProtectionProvider();
var secureDataFormat = new Microsoft.Owin.Security.DataHandler.TicketDataFormat(dataProtectionProvider.Create());
//var secureDataFormat = new Microsoft.Owin.Security.DataHandler.TicketDataFormat(new MachineKeyProtector());
var token = request.QueryString.Get("Bearer");
if (string.IsNullOrEmpty(token))
return false;
// var token = request.QueryString.Get(WebApiConfig.AuthenticationType);
var authenticationTicket = secureDataFormat.Unprotect(token);
if (authenticationTicket == null || authenticationTicket.Identity == null || !authenticationTicket.Identity.IsAuthenticated)
{
return false;
}
request.Environment["server.User"] = new ClaimsPrincipal(authenticationTicket.Identity);
request.Environment["server.Username"] = authenticationTicket.Identity.Name;
request.GetHttpContext().User = new ClaimsPrincipal(authenticationTicket.Identity);
return true;
}
public override bool AuthorizeHubMethodInvocation(Microsoft.AspNet.SignalR.Hubs.IHubIncomingInvokerContext hubIncomingInvokerContext, bool appliesToMethod)
{
var connectionId = hubIncomingInvokerContext.Hub.Context.ConnectionId;
// check the authenticated user principal from environment
var environment = hubIncomingInvokerContext.Hub.Context.Request.Environment;
var principal = environment["server.User"] as System.Security.Claims.ClaimsPrincipal;
if (principal != null && principal.Identity != null && principal.Identity.IsAuthenticated) // IsAuthenticated always gets false
{
// create a new HubCallerContext instance with the principal generated from token
// and replace the current context so that in hubs we can retrieve current user identity
hubIncomingInvokerContext.Hub.Context = new Microsoft.AspNet.SignalR.Hubs.HubCallerContext(new Microsoft.AspNet.SignalR.Owin.ServerRequest(environment), connectionId);
return true;
}
else
{
return false;
}
}
}
when click on send button I am calling this Invoke method of AppHub but while calling it gives me an error like not authorized.
AppHub.invoke('LoadPvtChatHistory_Hub', curVM, GENERAL_CONFIG.APP_messageExpiryTimeLimit);
AppHub.cs
[QueryStringBearerAuthorize]
public class AppHub : Hub
{
public void LoadPvtChatHistory_Hub(string xiSelectedUserID, int xiMessageExpiryTimeLimit)
{
///code....
}
}
[16:36:33 GMT+0530 (India Standard Time)] SignalR: Caller is not authorized to invoke the LoadPvtChatHistory_Hub method on AppHub.
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNet.SignalR.Hubs.HubPipelineModule.<>c__DisplayClass0_0.<<BuildIncoming>b__0>d.MoveNext().
jquery.signalR.js:82 [16:36:33 GMT+0530 (India Standard Time)] SignalR: apphub.loadPvtChatHistory_Hub failed to execute. Error: Caller is not authorized to invoke the LoadPvtChatHistory_Hub method on AppHub.
jquery.signalR.js:82 [16:37:00 GMT+0530 (India Standard Time)] SignalR: Invoking apphub.sendPrivateMessage_Hub
jquery.signalR.js:82 [16:37:04 GMT+0530 (India Standard Time)] SignalR: Caller is not authorized to invoke the SendPrivateMessage_Hub method on AppHub.
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNet.SignalR.Hubs.HubPipelineModule.<>c__DisplayClass0_0.<<BuildIncoming>b__0>d.MoveNext().
jquery.signalR.js:82 [16:37:04 GMT+0530 (India Standard Time)] SignalR: apphub.sendPrivateMessage_Hub failed to execute. Error: Caller is not authorized to invoke the SendPrivateMessage_Hub method on AppHub.
Here is my the solution, WORK on Azure and local. AngularJS, Web API and SignalR request.Environment["server.User"] this code doesn't work on Azure. First i create my Custom Filter Class.
public override bool AuthorizeHubMethodInvocation(IHubIncomingInvokerContext hubIncomingInvokerContext, bool appliesToMethod)
{
var connectionId = hubIncomingInvokerContext.Hub.Context.ConnectionId;
var request=hubIncomingInvokerContext.Hub.Context.Request;
var _Authorization = request.QueryString.Get("Bearer");
if (!string.IsNullOrEmpty(_Authorization))
{
//var token = _Authorization.Replace("Bearer ", "");
var ticket = Startup.OAuthOptions.AccessTokenFormat.Unprotect(_Authorization);
if (ticket != null && ticket.Identity != null && ticket.Identity.IsAuthenticated)
{
Dictionary<string, object> _DCI = new Dictionary<string, object>();
_DCI.Add("server.User", new ClaimsPrincipal(ticket.Identity));
hubIncomingInvokerContext.Hub.Context = new HubCallerContext(new ServerRequest(_DCI), connectionId);
return true;
}
}
return false;
}
Refer this article.
I've got a simple web api which is consumed from a mvc project, I keep on getting the 'Response status code does not indicate success' and was wondering how would I get the response body from the error, I can see the error within a rest viewer but can't navigate through to the error. This is the following code within the MVC app
public ActionResult Index()
{
try
{
var uri = "http://localhost:57089/api/values";
using (var client = new HttpClient())
{
Task<string> response = client.GetStringAsync(uri);
object result = JsonConvert.DeserializeObject(response.Result);
return (ActionResult) result;
}
}
catch (Exception ex)
{
return Content(ex.ToString());
}
return View();
}
Within the API controller I'm sending a bad request, here's the code
public IHttpActionResult Get()
{
return BadRequest("this is a very bad request " + System.DateTime.Now.ToUniversalTime());
}
I've tried to use WebException, HttpRequestException as exceptions to catch the error with no luck.
I can see the response body within the rest viewer
I want to be able to navigate to the Error Message so I can pass that to the client (which later will be changed to a guid).
[EDITED]
I've got a solution without using GetStringAsync, but wanted to use that if possible.
Here's the solution
var httpClient = new HttpClient();
httpClient.BaseAddress = new Uri(url);
HttpResponseMessage responseMessage = httpClient.GetAsync("").Result;
if (responseMessage.IsSuccessStatusCode) return Content(responseMessage.ToString());
var a = responseMessage.Content.ReadAsStringAsync().Result;
var result = JsonConvert.DeserializeObject<HttpError>(a);
object value = "";
return Content(result.TryGetValue("ErrorMessage", out value) ? value.ToString() : responseMessage.ToString());
Is there a better way?
Using WebException you should be able to get to the ResponseStream and the custom error message like this:
catch (WebException e)
{
var message = e.Message;
using (var reader = new StreamReader(e.Response.GetResponseStream()))
{
var content = reader.ReadToEnd();
}
}
Hope that helps.
In the following, ar.GetResponseAsString() just throws an exception.
Here is my code:
AsyncCallback GetTheResponse = ar =>
{
try
{
var result = ar.GetResponseAsString();
Debug.WriteLine(string.Format("ResponseStream:::{0}", result));
callback(result, null);
}
catch (Exception ex)
{
Debug.WriteLine(ex.ToString());
}
}
What am I doing wrong?
Catch the WebException that the 400 is throwing then grab the response from the exception message. That's where your error response is hiding