Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Ansar 181 posts 291 karma points
    Jan 14, 2012 @ 21:09
    Ansar
    0

    Referring DotNetOpenAuth.DLL making error on all XSLTs

    I just referred DotNetOpenAuth.DLL and all XSLTs are showing error.. 

    Removing DotNetOpenAuth makes all work fine!!.. It seems like some kind of bug..Its Umbraco 4.7.1

    I am on a project deadline and its DotNetOpenAuth is a must to finish it..

    Plaese help.......

  • Ansar 181 posts 291 karma points
    Jan 14, 2012 @ 21:38
    Ansar
    0

    Here is the details using umbDebugShowTrace

    Unable to load one or more of the types in assembly 'DotNetOpenAuth, Version=3.4.5.10202, Culture=neutral, PublicKeyToken=2780ccd10d57b246'. Exceptions were thrown:
    System.IO.FileNotFoundException: Could not load file or assembly 'System.Web.Mvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.
    Unable to load one or more of the types in assembly 'DotNetOpenAuth, Version=3.4.5.10202, Culture=neutral, PublicKeyToken=2780ccd10d57b246'. Exceptions were thrown:
    System.IO.FileNotFoundException: Could not load file or assembly 'System.Web.Mvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.
      at umbraco.BusinessLogic.Utils.TypeFinder.FindClassesMarkedWithAttribute(Assembly assembly, Type attribute)
      at umbraco.BusinessLogic.Utils.TypeFinder.FindClassesMarkedWithAttribute(Type attribute)
      at umbraco.macro.GetXsltExtensionsImpl()
      at umbraco.cms.businesslogic.cache.Cache.GetCacheItem[TT](String cacheKey, Object syncLock, CacheItemPriority priority, CacheItemRemovedCallback refreshAction, CacheDependency cacheDependency, TimeSpan timeout, GetCacheItemDelegate`1 getCacheItem)
      at umbraco.macro.GetXsltExtensions()
      at umbraco.macro.AddMacroXsltExtensions()
      at umbraco.macro.GetXsltTransformResult(XmlDocument macroXML, XslCompiledTransform xslt, Dictionary`2 parameters)
      at umbraco.macro.loadMacroXSLT(macro macro, MacroModel model, Hashtable pageElements)

     

  • Lennart Stoop 304 posts 842 karma points
    Jan 14, 2012 @ 21:49
    Lennart Stoop
    100

    Its still a mystery to me why this keeps happening: referencing a third party assembly and running into missing MVC dependencies.

    I had the same issue when referencing recaptcha, here's how I worked around it:

    http://our.umbraco.org/forum/getting-started/installing-umbraco/22533-Upgrade-to-470-Recaptcha-missing-assembly-reference

    Still not sure why it would require MVC..

  • Ansar 181 posts 291 karma points
    Jan 14, 2012 @ 22:05
    Ansar
    0

    wow!! thanks a lot.. I have read the links from your posts and it seems like its a common issue!!!

  • Jamie Howarth 306 posts 773 karma points c-trib
    Jan 15, 2012 @ 13:46
    Jamie Howarth
    1

    This is an issue to do with the TypeFinder static class, which uses Reflection to crawl assemblies (and referenced assemblies therein) to find classes decorated with [XsltExtension] or [RestExtension]. Because DotNetOpenAuth and ReCAPTCHA have "soft" references to System.Web.Mvc (in that they reference it, but the reference should not be called into question unless you're using the MVC-specific classes), the TypeFinder class tries to open all referenced DLLs, and get the public classes to then check for the decorative attribute. Because System.Web.Mvc is not included by default, it errors in a rather ugly fashion.

    The workaround is to either include System.Web.Mvc.dll in your /bin directory, or to install ASP.NET MVC via WebPI on your server. I opt for the latter cause it's easier and avoids it happening to any other sites on the same server, but it does need patching & I've taken a look at it.

    HTH,

    Benjamin

  • Lennart Stoop 304 posts 842 karma points
    Jan 15, 2012 @ 14:51
    Lennart Stoop
    0

    Thanks Benjamin, that really explains it.

    I'm not sure if its possible for the TypeFinder to distinguish soft from hard references?

  • Stephen 767 posts 2273 karma points c-trib
    Jan 15, 2012 @ 15:06
    Stephen
    0

    Umbraco has a mechanism to auto-discover some functionality, such as XSLT extensions, by looking for types marked with special attributes. In order to do so, it has to load each and every assembly within reach, and then recursively load each and every dependency assembly. In the past (pre-4.7 I believe) this was wrapped in a giant try...catch and every exception was ignored. This try...catch has been removed because it was hiding errors and turning debugging into a nightmare.

    The drawback is that if a DLL in your BIN has some unresolved dependencies, you'll get the above error. In your case it looks like DotNetOpenAuth somewhat references System.Web.Mvc... which does not seem to be installed on your server. In other words, the entire set of DLLs in BIN has to be "consistent" ie all dependencies must be recursively resolveable.

    Now, the issue is indeed rather common now that people use 4.7 more and more, and I start to wonder whether we should keep throwing exceptions, or just report the error in the trace and keep running. What do ppl think?

    Edit: I wrote this then had lunch then posted it... and in the meantime Benjamin explained pretty much the same... But the question remains valid: should we stop throwing exceptions when a reference can not be resolved, and simply report the error to the trace and/or log?

  • Stephen 767 posts 2273 karma points c-trib
    Jan 15, 2012 @ 15:13
    Stephen
    0

    @Lennart: I don't think there is a difference between a soft and a hard reference. A reference is resolved when you examine a type that depends on it. If you use DotNetOpenAuth but don't use any of the types that depend on MVC then the MVC reference will not be resolved. But since the TypeFinder wants to examine each and every type in a DLL, it _will_ examine types that depend on MVC.

    I don't see how we can avoid the exception. But we could decide it's not lethal and simply report it in the trace instead of throwing.

  • Jamie Howarth 306 posts 773 karma points c-trib
    Jan 15, 2012 @ 15:15
    Jamie Howarth
    0

    We shouldn't throw exceptions on missing assemblies IMO. If you need a class in an assembly in your C#/.NET code then your compiler should catch the missing reference anyway. From my initial checks so far there's no way of distinguishing a "soft" reference - it's identical to any other reference, but only gets called into play when you use a class that uses the reference - e.g. ReCAPTCHA MVC controls need route-handling magic in System.Web.Mvc.

    Dynamic discovery of extensions is great, but I think it should stretch to a single level - thinking about it, doesn't this mean that you're also crawling every Umbraco DLL, and don't they cross-reference each other...? By that logic, does it make this an un-necessary performance hit by searching a DLL's references? Just a thought.

    Benjamin

  • Jamie Howarth 306 posts 773 karma points c-trib
    Jan 15, 2012 @ 15:17
    Jamie Howarth
    0

    @Stephen you got there as I did! lol

    Ugly as it sounds (I hate hard-coding stuff), there could be a hard-code to ignore types that inherit from classes in System.Web.Mvc... as it seems to be only this library that causes the majority of problems. Thoughts?

  • Lennart Stoop 304 posts 842 karma points
    Jan 15, 2012 @ 15:34
    Lennart Stoop
    0

    I think Benjamin has a point with recursive crawling & performance overhead. If there's any DLL's that contain XSLT extensions etc. they should be referenced directly, right?

    If catching those exceptions would cause debugging nightmares, you could also have them thrown in debugging mode only and catch them on a release environment (although I guess most developers will work in debugging mode locally)

  • Stephen 767 posts 2273 karma points c-trib
    Jan 15, 2012 @ 15:45
    Stephen
    0

    @Benjamin - the .NET framework somehow ensures that there is no "infinite loops" in resolving dependencies. And I don't think there is a performance issue here. In addition this only runs once when the app domain starts. Or at least it should run only once.

    I don't really like the idea of hiding some types... I'd rather add a configuration option so that you can select between a) throwing and b) reporting the exception, when in debug mode--in release mode we would always report and never throw.

    If that makes sense enough I can push a patch...

  • Jamie Howarth 306 posts 773 karma points c-trib
    Jan 15, 2012 @ 15:59
    Jamie Howarth
    0

    @Stephen I know about the dependency loop thing, but I'm wondering if there's a measured performance hit from the crawls on each library - from what I remember of the core code, it doesn't aggregate all libraries and references, then do Distinct() on the entire list... which maybe it should, prior to type-finding in each library.

  • Stephen 767 posts 2273 karma points c-trib
    Jan 15, 2012 @ 17:48
    Stephen
    0

    Not sure I understand you... TypeFinder is type-finding in each first-level libraries ie DLLs that are in BIN. But not on dependencies. When it loads Foo.dll, if Foo.dll requires System.Web.Mvc, it will require System.Web.Mvc but it will not type-find System.Web.Mvc. So I do not see where's the perf. issue. Yet I'm posting this while also helping my 4yo Playmobil secret agents fight the enemy, so maybe I'm not paying enough attention.

    Looking at TypeFinder code shows that the reported exception should show only when debugging (GlobalSettings.DebugMode == true) -- in production it should not be thrown. Anz, could you confirm you're also seeing the exception, or not seeing it, when not in debug mode?

    It should be relatively easy to add an umbracoTypeFinderDoesNotThrow config option...

  • Andrew Arnott 1 post 21 karma points
    Jan 16, 2012 @ 21:54
    Andrew Arnott
    0

    As for discerning a soft reference from a hard reference, it seems to me the best way would be simply to catch the TypeLoadExceptions when they're thrown, then move on.  If you're trying to look at an individual type and it throws, that type is unavailable and you may move onto the next type in that assembly.

    That would achieve the desired behavior, albeit with exceptions which are unavoidable.

  • Jamie Howarth 306 posts 773 karma points c-trib
    May 22, 2012 @ 16:17
    Jamie Howarth
    0

    Hi Andrew,

    Thanks for chipping in - I found a better way which uses LoadFrom instead of Load. I've patched this and it's awaiting a pull request back into the Umbraco core to fix it. In the meantime I've attached an updated businesslogic.dll to the ticket which works with Umbraco 4.7.1 (and 4.7.1.1), but hasn't made its' way into 4.7.2 (I believe). Upvote for 4.7.3/4.8!

    Cheers,

    Benjamin

Please Sign in or register to post replies

Write your reply to:

Draft