问题
I need scheduling functionality on my .NET MVC website and I came across Quartz.net library which can do exactly what I need.
The problem is I'm running my site on a hosting (GoDaddy) and when I added Quartz.net 2.0.1
to my project I've got "that assembly does not allow partially trusted callers"
exception. After some research I found out that many people have the same problem and some solved it by removing Common.Logging library from Quartz.net.
I followed some of the advice and removed all references to Common.Logging but I still have problems. It looks like it's not enough and now I'm getting Inheritance security rules violated while overriding member
exception, more details:
Inheritance security rules violated while overriding member:
Quartz.Util.DirtyFlagMap`2<TKey,TValue>.GetObjectData
(System.Runtime.Serialization.SerializationInfo,
System.Runtime.Serialization.StreamingContext)'.
Security accessibility of the overriding method must match the
security accessibility of the method being overriden.
It looks like I really need to change something in Quartz.net to make it work.
Has anyone run Quartz.net on medium trust? If so what needs to be done? May be someone can suggest some alternatives?
回答1:
I recommend building Common.Logging yourself rather than removing it from the project. You can get the latest source from http://netcommon.sourceforge.net/downloads.html.
I guess the second problem had to do with that the C5.dll wasn't trusted either. I would also just build that myself. The source can be found here: http://www.itu.dk/research/c5/.
Although there are other options than building the dlls (http://stackoverflow.com/questions/3072359/unblocking-a-dll-on-a-company-machine-how) I personally prefer to build the dlls myself unless I absolutely trust the downloaded product.
回答2:
Steinar's answer sent me in the right direction. Sharing the steps here that got QuartZNet to work in a medium trust hosting environment.
QuartzNet initially ran into permissions issues on medium trust, we needed to the do the following to fix the issue
(1) Downloaded QuartzNet code ( 2.1.0.400 ) from github and build it after making the following changes to AssemblyInfo.cs
Replaced
#if !NET_40
[assembly: System.Security.AllowPartiallyTrustedCallers]
#endif
with
[assembly: AllowPartiallyTrustedCallers]
#if NET_40
[assembly: SecurityRules(SecurityRuleSet.Level1)]
#endif
(2) Downloaded C5 code (v 2.1) and built it with
[assembly: AllowPartiallyTrustedCallersAttribute()
Ensure C5 is compiled in the same .NET version as Qartznet.
(3) Added the quartz section to web.config within TGH, section had requirepermission set to false. Common logging section also had requirepermission set to false, also configured it to use Common.Logging.Simple.NoOpLoggerFactoryAdapter.
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<sectionGroup name="common">
<section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging" requirePermission="false" />
</sectionGroup>
<section name="quartz" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0,Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<common>
<logging>
<factoryAdapter type="Common.Logging.Simple.NoOpLoggerFactoryAdapter, Common.Logging">
<arg key="showLogName" value="true" />
<arg key="showDataTime" value="true" />
<arg key="level" value="OFF" />
<arg key="dateTimeFormat" value="HH:mm:ss:fff" />
</factoryAdapter>
</logging>
</common>
<quartz>
<add key="quartz.scheduler.instanceName" value="QuartzScheduler" />
<add key="quartz.threadPool.type" value="Quartz.Simpl.SimpleThreadPool, Quartz" />
<add key="quartz.threadPool.threadCount" value="10" />
<add key="quartz.threadPool.threadPriority" value="2" />
<add key="quartz.jobStore.misfireThreshold" value="60000" />
<add key="quartz.jobStore.type" value="Quartz.Simpl.RAMJobStore, Quartz" />
</quartz>
(4) Initialised the scheduler using constructor with namecollection as the parameter, namecollection was the quartz section picked up from web.config.
In global.asax
QuartzScheduler.Start();
The class
public class QuartzScheduler
{
public static void Start()
{
ISchedulerFactory schedulerFactory = new StdSchedulerFactory((NameValueCollection)ConfigurationManager.GetSection("quartz"));
IScheduler scheduler = schedulerFactory.GetScheduler();
scheduler.Start();
IJobDetail inviteRequestProcessor = new JobDetailImpl("ProcessInviteRequest", null, typeof(InviteRequestJob));
IDailyTimeIntervalTrigger trigger = new DailyTimeIntervalTriggerImpl("Invite Request Trigger", Quartz.TimeOfDay.HourMinuteAndSecondOfDay(0, 0, 0), Quartz.TimeOfDay.HourMinuteAndSecondOfDay(23, 23, 59), Quartz.IntervalUnit.Second, 1);
scheduler.ScheduleJob(inviteRequestProcessor, trigger);
}
}
public class InviteRequestJob : IJob
{
public void Execute(IJobExecutionContext context)
{
RequestInvite.ProcessInviteRequests();
}
}
来源:https://stackoverflow.com/questions/10789875/using-quartz-net-on-medium-trust-hosting