I'm developing an app using Xamarin forms, I have a Broadcast receiver which monitors connectivity change. It works perfectly when application is active, but when I close my application(just slide it out from the recent apps tray) the Broadcast receiver stops working.I'm not able find where i'm committing mistake.
Below is my manifest file :
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.ETMS.taskmanagement.permission.C2D_MESSAGE" />
<permission android:name="com.ETMS.taskmanagement.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
below is my Broadcast Receiver :
namespace ETMS.Droid.Receiver
{
[BroadcastReceiver(Enabled = true,Exported = true)]
[IntentFilter(new string[] { "android.net.conn.CONNECTIVITY_CHANGE" })]
class ConnectivityReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
Log.Debug("ETMS CONNECTIVITY ", "Reached Connectivity");
LocalPreferenceManager mManager = new LocalPreferenceManager(context);
bool hasNetwork = !intent.GetBooleanExtra(ConnectivityManager.ExtraNoConnectivity, false);
if (hasNetwork)
{
bool authenticate = GeofenceSPService.AuthenticateSp();
if (authenticate)
{
GeofenceSPService.SyncGeofenceToServer(mManager);
GeofenceSPService.LogTrace("Raj", "Connectivity Receiver : " + authenticate);
}
}
else
{
Log.Error("ETMS CONNECTIVITY ", "Reached Connectivity");
}
}
public bool IsConnected(Context context)
{
ConnectivityManager cm = (ConnectivityManager) context.GetSystemService(Context.ConnectivityService);
NetworkInfo activeNetwork = cm.ActiveNetworkInfo;
bool isConnected = activeNetwork != null && activeNetwork.IsConnectedOrConnecting;
return isConnected;
}
private void SendNotification(string networkDetails, Context context)
{
// Create an explicit content Intent that starts the main Activity.
Intent notificationIntent = new Intent(context, typeof(MainActivity));
// Construct a task stack
TaskStackBuilder stackBuilder = TaskStackBuilder.Create(context);
// Add the main Activity to the task stack as the parent.
stackBuilder.AddParentStack(Java.Lang.Class.FromType(typeof(MainActivity)));
// push the content Intent onto the stack.
stackBuilder.AddNextIntent(notificationIntent);
// Get a PendingINtent containing the entire backstack
PendingIntent notificationPendingIntent = stackBuilder.GetPendingIntent(0, PendingIntentFlags.UpdateCurrent);
// Get a notification builder that's compatible with platform versions >= 4
Notification.Builder builder = new Notification.Builder(context);
//Define the notification settings.
builder.SetSmallIcon(Resource.Drawable.networkoff)
.SetContentTitle(networkDetails)
.SetContentText("Network Connectivity")
.SetContentIntent(notificationPendingIntent);
// Dismiss the notification once the user touches it.
builder.SetAutoCancel(true);
// Get an instance of the Notification manager
NotificationManager mNotificationManager =
(NotificationManager) context.GetSystemService(Context.NotificationService);
mNotificationManager.Notify(0, builder.Build());
}
}
}
Related
I have a problem when dragging an image from the camera and making it wallpaper to ImageView.
I used the following code and it works on versions less than 5 .
But versions 5 or higher code does not work permanently and the camera does not work at all
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.companyname.camera_capimage" android:grantUriPermissions="true" android:installLocation="auto">
<uses-sdk android:minSdkVersion="17" android:targetSdkVersion="28" />
<application android:allowBackup="true" android:icon="#mipmap/ic_launcher" android:label="#string/app_name" android:roundIcon="#mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="#style/AppTheme"></application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-feature android:name="android.hardware.camera" />
</manifest>
MainActivity
public class MainActivity : AppCompatActivity
{
public static Bitmap bitmap;
public static string fileName;
public ImageView _imageView;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.activity_main);
Button button = FindViewById<Button>(Resource.Id.button1);
_imageView = FindViewById<ImageView>(Resource.Id.imageView1);
button.Click += BtnCamera_Click;
}
protected override void OnActivityResult(int requestCode, [GeneratedEnum] Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
Bitmap bitmap = (Bitmap)data.Extras.Get("data");
_imageView.SetImageBitmap(bitmap);
}
private void BtnCamera_Click(object sender, System.EventArgs e)
{
Intent intent = new Intent(MediaStore.ActionImageCapture);
StartActivityForResult(intent, 0);
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
error message
Java.Lang.SecurityException: 'Permission Denial: starting Intent { act=android.media.action.IMAGE_CAPTURE cmp=com.android.camera/.Camera } from ProcessRecord{273b163 23970:com.companyname.camera_capimage/u0a98} (pid=23970, uid=10098) with revoked permission android.permission.CAMERA'
In my xamarin android app, AltBeacon DidEnterRegion not triggered when MainLauncher attribute set to false for MainActivity. As I have SplashActivity for showing splash screen, I have to make the SplashActivity as my MainLauncher. I am using foreground service to detect iBeacon.
Code of my Application class:
namespace AltBeaconLibrarySample.Droid
{
#if DEBUG
[Application(Debuggable = true)]
#else
[Application(Debuggable = false)]
#endif
public class MainApplication : Application, IBootstrapNotifier
{
private RegionBootstrap regionBootstrap;
private BackgroundPowerSaver backgroundPowerSaver;
Region _generalRegion;
public bool IsStartedRanging { get; set; }
string foregroundServiceChannelId = "foregroundService";
string channelName = "ForegroundService";
int pendingIntentId = 1;
public MainApplication(IntPtr handle, JniHandleOwnership transer)
: base(handle, transer)
{
}
public void DidDetermineStateForRegion(int p0, Region p1)
{
}
public void DidEnterRegion(Region p0)
{
var beaconService = Xamarin.Forms.DependencyService.Get<IAltBeaconService>();
if (!IsStartedRanging)
{
beaconService.StartRanging();
IsStartedRanging = true;
}
}
public void DidExitRegion(Region p0)
{
var beaconService = Xamarin.Forms.DependencyService.Get<IAltBeaconService>();
if (IsStartedRanging)
{
beaconService.StopRanging();
IsStartedRanging = false;
}
beaconService.DidExitRegion();
}
public override void OnCreate()
{
base.OnCreate();
CrossCurrentActivity.Current.Init(this);
BeaconManager bm = BeaconManager.GetInstanceForApplication(this);
CreateNotificationChannel();
bm.EnableForegroundServiceScanning(GetForegroundServiceNotification(), 456);
bm.SetEnableScheduledScanJobs(false);
_generalRegion = new Org.Altbeacon.Beacon.Region/* AltBeaconOrg.BoundBeacon.Region*/("myEmptyBeaconId", Identifier.Parse("23A01AF0-232A-4518-9C0E-323FB773F5EF"), null, null);
regionBootstrap = new RegionBootstrap(this, _generalRegion);
backgroundPowerSaver = new BackgroundPowerSaver(this);
}
void CreateNotificationChannel()
{
if (Build.VERSION.SdkInt < BuildVersionCodes.O)
{
// Notification channels are new in API 26 (and not a part of the
// support library). There is no need to create a notification
// channel on older versions of Android.
return;
}
var channelDescription = "Foreground Sertrvice";
var channel = new NotificationChannel(foregroundServiceChannelId, channelName, NotificationImportance.High)
{
Description = channelDescription
};
var notificationManager = (NotificationManager)GetSystemService(NotificationService);
notificationManager.CreateNotificationChannel(channel);
}
public Notification GetForegroundServiceNotification()
{
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, foregroundServiceChannelId);
builder.SetSmallIcon(Resource.Drawable.xamagonBlue);
builder.SetContentTitle("Scanning for Beacons");
Intent intent = new Intent(this, typeof(MainActivity));
PendingIntent pendingIntent = PendingIntent.GetActivity(this, pendingIntentId, intent, PendingIntentFlags.UpdateCurrent);
builder.SetContentIntent(pendingIntent);
return builder.Build();
}
}
}
Code of SplashActivity class:
namespace AltBeaconLibrarySample.Droid
{
[Activity(Label = "AltBeaconLibrarySample.Droid",
Icon = "#mipmap/icon",
Theme = "#style/MainTheme",
MainLauncher = true,
NoHistory = true,
LaunchMode = Android.Content.PM.LaunchMode.SingleInstance,
ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class SplashActivity : Activity
{
static readonly string TAG = "X:" + typeof(SplashActivity).Name;
public override void OnCreate(Bundle savedInstanceState, PersistableBundle persistentState)
{
base.OnCreate(savedInstanceState, persistentState);
}
// Launches the startup task
protected override void OnResume()
{
base.OnResume();
Task startupWork = new Task(() => { SimulateStartup(); });
startupWork.Start();
}
// Simulates background work that happens behind the splash screen
async void SimulateStartup()
{
Log.Debug(TAG, "Performing some startup work that takes a bit of time.");
await Task.Delay(50); // Simulate a bit of startup work.
Log.Debug(TAG, "Startup work is finished - starting MainActivity.");
StartActivity(new Intent(Application.Context, typeof(MainActivity)));
}
}
}
Android manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.companyname.AltBeaconLibrarySample" android:installLocation="auto">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="28" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<application android:label="AltBeaconLibrarySample.Android">
<service android:enabled="true" android:exported="false" android:isolatedProcess="false" android:label="Beacon" android:name="org.altbeacon.beacon.service.BeaconService"></service>
<service android:enabled="true" android:exported="false" android:name="org.altbeacon.beacon.BeaconIntentProcessor"></service>
<receiver android:name="org.altbeacon.beacon.startup.StartupBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
<action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" />
</intent-filter>
</receiver>
</application>
</manifest>
Code of MainActivity class:
namespace AltBeaconLibrarySample.Droid
{
[Activity(Label = "AltBeaconLibrarySample.Droid",
Icon = "#mipmap/icon",
Theme = "#style/MainTheme",
MainLauncher = false,
LaunchMode = Android.Content.PM.LaunchMode.SingleInstance,
ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity, IBeaconConsumer
{
protected override void OnCreate(Bundle savedInstanceState)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState); // add this line to your code, it may also be called: bundle
CrossCurrentActivity.Current.Init(this, savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
LoadApplication(new App());
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
PermissionsImplementation.Current.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
#region IBeaconConsumer Implementation
public void OnBeaconServiceConnect()
{
}
#endregion
protected override void OnDestroy()
{
base.OnDestroy();
DependencyService.Get<IAltBeaconService>().OnDestroy();
}
protected override void OnResume()
{
base.OnResume();
}
protected override void OnPause()
{
base.OnPause();
}
}
}
BeaconManager code snippet:
BeaconManager bm = BeaconManager.GetInstanceForApplication(Plugin.CurrentActivity.CrossCurrentActivity.Current.Activity);
var iBeaconParser = new BeaconParser();
// Estimote > 2013
iBeaconParser.SetBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24");
bm.BeaconParsers.Add(iBeaconParser);
bm.BackgroundMode = false;
bm.Bind((IBeaconConsumer)Plugin.CurrentActivity.CrossCurrentActivity.Current.Activity);
I try to work with JobScheduler and JobService on Android Things
My installation is RPI (Raspberry Pi) running IoT RPI3 1.0.2
this is my simple code:
package com.mystuff.jobservicetest;
import android.app.Activity;
import android.app.job.JobInfo;
import android.app.job.JobParameters;
import android.app.job.JobScheduler;
import android.app.job.JobService;
import android.content.ComponentName;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends Activity {
private static final String TAG = MainActivity.class.getSimpleName();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
JobScheduler jobScheduler = (JobScheduler) getSystemService(
Context.JOB_SCHEDULER_SERVICE);
ComponentName name = new ComponentName(this, JobServiceTest.class);
JobInfo jobInfo = new JobInfo.Builder(1,name).setPeriodic(1000).build();
int result = jobScheduler.schedule(jobInfo);
Log.d(TAG, "result = "+result);
}
public class JobServiceTest extends JobService {
#Override
public boolean onStartJob(JobParameters jobParameters) {
Log.d(TAG, "Service job started");
return false;
}
#Override
public boolean onStopJob(JobParameters jobParameters) {
return false;
}
}
}
AndroidManifest.xml looks simple like this:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mystuff.jobservicetest">
<application>
<uses-library android:name="com.google.android.things" />
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.IOT_LAUNCHER" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<service android:name=".MainActivity$JobServiceTest"
android:permission="android.permission.BIND_JOB_SERVICE"/>
</application>
</manifest>
Outcome of logcat is just:
W/JobInfo: Specified interval for 1 is +1s0ms. Clamped to +15m0s0ms
Specified flex for 1 is +1s0ms. Clamped to +5m0s0ms
D/MainActivity: result = 1
I am missing "Service job started" log. Seems to onStartJob is never called.
Any hints?
Thanks
A JobService can only be scheduled in intervals of 15 minutes or longer. If you want a shorter task, you may want to look at alternative methods.
Can somebody tell me what am I missing. I have a webview app. It works fine except this, when I close app onesignal notification arrives fine, but when I click notification app does not open. Here is some code related to this problem.
I have been searching for solution but what ever I have tried it does not work.
When app is running notification comes and opens fine, but when it is closed it wont start app.
Thanks.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
OneSignal.startInit(this)
.inFocusDisplaying(OneSignal.OSInFocusDisplayOption.Notification)
.unsubscribeWhenNotificationsAreDisabled(true)
.setNotificationOpenedHandler(new
OneSignal.NotificationOpenedHandler() {
#Override
public void notificationOpened(OSNotificationOpenResult
result) {
String launchURL =
result.notification.payload.launchURL;
Intent intent = new Intent(getApplicationContext(),
NotificationActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT
| Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("url", launchURL);
startActivity(intent);
}
})
.init();
}
public class NotificationExtender extends NotificationExtenderService {
#Override
protected boolean onNotificationProcessing(OSNotificationReceivedResult notification) {
OverrideSettings overrideSettings = new OverrideSettings();
overrideSettings.extender = new NotificationCompat.Extender() {
#Override
public NotificationCompat.Builder extend(NotificationCompat.Builder builder) {
// Sets the background notification color to Green on Android 5.0+ devices.
return builder.setColor(new BigInteger("#005aaa", 16).intValue())
.setSmallIcon(R.drawable.ic_stat_onesignal_default);
}
};
OSNotificationDisplayedResult displayedResult = displayNotification(overrideSettings);
Log.d("OneSignalExample", "Notification displayed with id: " + displayedResult.androidNotificationId);
return true;
}
}
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".NotificationExtender"
android:permission="android.permission.BIND_JOB_SERVICE"
android:exported="false">
<intent-filter>
<action android:name="com.onesignal.NotificationExtender" />
</intent-filter>
</service>
<activity
android:name=".NotificationActivity"
android:parentActivityName=".MainActivity"/>
<meta-data android:name="com.onesignal.NotificationOpened.DEFAULT" android:value="DISABLE" />
I solved it.
It seams you do not need NotificationOpenedHandler, just NotificationExtender extends NotificationExtenderService. It look like this:
public class NotificationExtender extends NotificationExtenderService {
public NotificationExtender() {
super();
}
#Override
protected boolean onNotificationProcessing(OSNotificationReceivedResult receivedResult) {
Intent intent = new Intent(getApplicationContext(), NotificationActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.putExtra("url", receivedResult.payload.launchURL);
PendingIntent pendingIntent = PendingIntent.getActivity(
getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_ONE_SHOT);
Uri uri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(getApplicationContext())
.setSmallIcon(R.drawable.ic_stat_onesignal_default)
.setSound(uri)
.setContentTitle(receivedResult.payload.title)
.setContentText(receivedResult.payload.body)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_onesignal_large_icon_default))
.setColor(getResources().getColor(R.color.logo_color))
.setAutoCancel(true)
.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(0, notificationBuilder.build());
return true;
}
}
I have problem with resolving component with Unity in my .NET MVC 5 app.
In my App_Start folder I have generated UnityConfig.cs and UnityMvcActivator.cs, which looks like this:
public static class UnityConfig
{
#region Unity Container
private static Lazy<IUnityContainer> container =
new Lazy<IUnityContainer>(() =>
{
var container = new UnityContainer();
RegisterTypes(container);
return container;
});
public static IUnityContainer Container => container.Value;
#endregion
public static void RegisterTypes(IUnityContainer container)
{
// NOTE: To load from web.config uncomment the line below.
// Make sure to add a Unity.Configuration to the using statements.
// container.LoadConfiguration();
container.AddNewExtension<Interception>();
container.RegisterType<ILogger, EntLibFileLogger>(new ContainerControlledLifetimeManager(),
new InjectionConstructor(ConfigurationManager.AppSettings["logTrace"],
int.Parse(ConfigurationManager.AppSettings["logSize"])));
container.RegisterType<IUserRepository, UserRepository>(new Interceptor<InterfaceInterceptor>(), new InterceptionBehavior<LoggingInterceptionBehavior>());
container.RegisterType<IUserProvider, UserProvider>(new Interceptor<InterfaceInterceptor>(), new InterceptionBehavior<LoggingInterceptionBehavior>());
...
}
}
public static class UnityMvcActivator
{
/// <summary>
/// Integrates Unity when the application starts.
/// </summary>
public static void Start()
{
FilterProviders.Providers.Remove(FilterProviders.Providers.OfType<FilterAttributeFilterProvider>().First());
FilterProviders.Providers.Add(new UnityFilterAttributeFilterProvider(UnityConfig.Container));
DependencyResolver.SetResolver(new UnityDependencyResolver(UnityConfig.Container));
// TODO: Uncomment if you want to use PerRequestLifetimeManager
// Microsoft.Web.Infrastructure.DynamicModuleHelper.DynamicModuleUtility.RegisterModule(typeof(UnityPerRequestHttpModule));
}
/// <summary>
/// Disposes the Unity container when the application is shut down.
/// </summary>
public static void Shutdown()
{
UnityConfig.Container.Dispose();
}
}
Interception look like this:
class LoggingInterceptionBehavior : IInterceptionBehavior
{
private readonly ILogger _logger;
public LoggingInterceptionBehavior(ILogger logger)
{
_logger = logger;
}
public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
{
var methodDesc = $"{input.MethodBase.DeclaringType.Name}.{input.MethodBase.Name}";
var args = input.Arguments == null || input.Arguments.Count == 0
? "null"
: JsonConvert.SerializeObject(input.Arguments);
// Before invoking the method on the original target.
_logger.Log($"{methodDesc} start. Arguments: {args}", LogLevel.Info);
// Invoke the next behavior in the chain.
var result = getNext()(input, getNext);
// After invoking the method on the original target.
if (result.Exception != null)
{
_logger.Log($"{methodDesc} threw exception. {result.Exception.GetBaseException()}", LogLevel.Error);
}
else
{
_logger.Log($"{methodDesc} end", LogLevel.Info);
}
return result;
}
public IEnumerable<Type> GetRequiredInterfaces()
{
return Type.EmptyTypes;
}
public bool WillExecute
{
get { return true; }
}
}
I have also customized authorization filter, where is following code:
public class SayDoAuthorizeAttribute : AuthorizeAttribute
{
private readonly string[] allowedRoles;
public SayDoAuthorizeAttribute() : base()
{
}
public SayDoAuthorizeAttribute(params string[] roles)
{
allowedRoles = roles;
}
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
var userRoles = SayDoAuthorizeHelper.GetRolesAndCacheThem(httpContext);
bool authorize = false;
foreach (var role in allowedRoles)
{
if (userRoles.Contains(role))
{
authorize = true;
break;
}
}
return authorize;
}
...
}
The problem is that UnityConfig.Resolve fails on resolving IUserProvider component in following SayDoAuthorizeHelper.GetRolesAndCacheThem method. (I want to have this class static, because IsUserInRole and IsUserInRoles mehthods are also used in razor views.
public static class SayDoAuthorizeHelper
{
public static IEnumerable<string> GetRolesAndCacheThem(HttpContextBase httpContext)
{
var nameFromSession = httpContext.Session[Constants.SessionKeyUserPreselectSession];
var userName = (nameFromSession != null) ? (string)nameFromSession : httpContext.User.Identity.Name;
var rolesString = (string)httpContext.Cache.Get(userName);
if (string.IsNullOrEmpty(rolesString))
{
var userProvider = UnityConfig.Container.Resolve<IUserProvider>();
var roles = userProvider.GetUserRolesNames(userName);
rolesString = string.Join(",", roles);
//set absolute cache
var minutesToCacheRoles = double.Parse(ConfigurationManager.AppSettings[Constants.KeyCacheUserRolesInMinutes]);
httpContext.Cache.Insert(userName, rolesString, null, DateTime.Now.AddMinutes(minutesToCacheRoles), Cache.NoSlidingExpiration);
return roles;
}
return rolesString.Split(',').ToList();
}
public static bool IsUserInRole(System.Security.Principal.IPrincipal userPrincipal, string roleName)
{
var userRoles = GetRolesAndCacheThem(new HttpContextWrapper(HttpContext.Current));
return userRoles.Contains(roleName);
}
public static bool IsUserInRoles(System.Security.Principal.IPrincipal userPrincipal, string[] roleNames)
{
var userRoles = GetRolesAndCacheThem(new HttpContextWrapper(HttpContext.Current));
foreach (var roleName in roleNames)
{
if (userRoles.Contains(roleName))
{
return true;
}
}
return false;
}
}
When I have breakpoint set on line
var userProvider = UnityConfig.Container.Resolve();
then no exception is thrown, and code still continue, but I see in local variables that userProvider threw an exception of type 'System.IO.FileNotFoundException' Abb.Czopc.SayDo.BusinessLogic.Interface.IUserProvider {System.IO.FileNotFoundException}
with message "Cannot load assembly '15bd37ce9f8a41d9b9916a1ebadc536a'.". But in output window I see that assembly was loaded.
'iisexpress.exe' (CLR v4.0.30319: /LM/W3SVC/2/ROOT-1-131699797337577440): Loaded '15bd37ce9f8a41d9b9916a1ebadc536a'.
When I have registration in UnityConfig without Interception, everything works good.
container.RegisterType<IUserRepository, UserRepository>();
container.RegisterType<IUserProvider, UserProvider>();
I also tried replace InterfaceInterceptor with VirtualMethodInterceptor, but with same result.
Can anyone help? I dont know what is wrong. Thanks for help.
Solution is written in VS 2015, list of nuget packages is here:
<package id="Abb.Czopc.Common.Log" version="1.0.1" targetFramework="net451" />
<package id="Abb.Czopc.Common.Log.EntLibLogger" version="1.0.1" targetFramework="net451" />
<package id="Antlr" version="3.5.0.2" targetFramework="net451" />
<package id="AutoMapper" version="6.2.2" targetFramework="net451" />
<package id="EnterpriseLibrary.Common" version="6.0.1304.0" targetFramework="net451" />
<package id="EnterpriseLibrary.Logging" version="6.0.1304.0" targetFramework="net451" />
<package id="jQuery" version="3.3.1" targetFramework="net451" />
<package id="jQuery.Validation" version="1.17.0" targetFramework="net451" />
<package id="Microsoft.AspNet.Mvc" version="5.2.4" targetFramework="net451" />
<package id="Microsoft.AspNet.Razor" version="3.2.4" targetFramework="net451" />
<package id="Microsoft.AspNet.Web.Optimization" version="1.1.3" targetFramework="net451" />
<package id="Microsoft.AspNet.WebPages" version="3.2.4" targetFramework="net451" />
<package id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="1.0.8" targetFramework="net451" />
<package id="Microsoft.jQuery.Unobtrusive.Ajax" version="3.2.5" targetFramework="net451" />
<package id="Microsoft.jQuery.Unobtrusive.Validation" version="3.2.9" targetFramework="net451" />
<package id="Microsoft.Net.Compilers" version="2.7.0" targetFramework="net451" developmentDependency="true" />
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net451" />
<package id="Modernizr" version="2.8.3" targetFramework="net451" />
<package id="Newtonsoft.Json" version="11.0.2" targetFramework="net451" />
<package id="Respond" version="1.4.2" targetFramework="net451" />
<package id="Unity.Abstractions" version="3.3.0" targetFramework="net451" />
<package id="Unity.Container" version="5.8.5" targetFramework="net451" />
<package id="Unity.Interception" version="5.5.1" targetFramework="net451" />
<package id="Unity.Mvc" version="5.0.13" targetFramework="net451" />
<package id="WebActivatorEx" version="2.2.0" targetFramework="net451" />
<package id="WebGrease" version="1.6.0" targetFramework="net451" />