I have a situation where I need to add localised satallite assemblies to an existing XAP file. This is in the context of a SharePoint webpart.
The problem is that when I add the de/Assembly.resources.dll and rebuild the XAP, it fails to load in the browser. The mode of failure depends on how I attempt add the assembly to the AppManifest.xaml. In some cases, it just shows nothing in the browser. In others, it shows the loading spinner stuck at 0%.
My procedure is as follows:
Extract XAP
Extract the .resource from core webpart assembly
Convert to .resx
Translate
Rebuild as delay signed satallite assembly
copy to 'de' subfolder
Add to AppManifest
Rebuild XAP
Copy back to 14 hive
IISRESET
Clear browser cache
Test
The original assemblies are signed and so I have disabled assembly verification checking sn -Vr [star],[star] and have modified the registry to include 64bit and 32bit entries for verification checking. Assembly verification check skipping has been proven on the same system in a non-Silverlight/XAP context. The assemblies are built with the same .net version. SharePoint timer service was restarted after sn -Vr to reload exception list for verification skipping.
I must be missing something, but I don't know what.
In one Silverlight localisation guide I saw that the .csproj contains a string of supported localisations - I doubt the original base assembly was build with any other cultures specified - could this be the problem?
I need to make 3rd party (I'm a software distributor) extensions to some OOTB components of the software I resell. I have permission for this, and can even get my assemblies signed when the time is right, but I have no source access and any changes to the core component take a long time and a lot of effort - i.e. undesireable.
Assistance greatly appreciated. I have this working already for some ASP.net apps and standard webparts - but this Silverlight based web-part remains a problem.
Many thanks.
Related
I am using VS2008 to publish my application files using ClickOnce. I read somewhere that ClickOnce intelligently does only partial updates; meaning it only downloads files from the network share if the file has changed in subsequent updates. However, this wasn't working for me. So I did some research and stumbled upon this MSDN article - http://msdn.microsoft.com/en-us/library/ms404267.aspx. It says that if we build using VS, it doesn't perform the partial updates. Can anyone tell me why this is the case? If so, is there a way to atleast let the referenced dlls to be downloaded only for the first time. I am using Microsoft Practices Enterprise Library and some 3rd party controls (with huge Theme files).
Thanks,
Uniball
Partial updates work fine in ClickOnce even when building in VS. However, if you have a solution made up of a few projects (eg a couple of class library projects and an executable) then any time you rebuild all the projects the timestamp on the assembly files will change, even if the code hasn't. Since ClickOnce really only looks at the timestamps to decide whether a file needs updating, it'll pull down the (unchanged) assemblies as new files when the user updates.
The workaround is to pull any dependent projects out of your executable's solution file and build them separately. That means that any assemblies whose code doesn't change very often will only get pulled down to the client once. If you need to change the assembly, you simply open its solution and make the change, then reopen your executable's solution and rebuild that. The next ClickOnce update will pull down both the exe and the changed assembly.
Hope that's clear enough!
Bear with a bit me before jumping straight to the normal caching fix solutions. Here's what happening:
I have a project, a single project out of dozens in our solution that appears to be refusing to update its code when I build and run. It's not part of the xap, but a dll sitting along side the xap.
Things I've already determined not a solution:
I've checked the output of its dll and it has been built, and its contents updated to match my code, verified with dotPeek. But it refuses to display the updated code.
I clean, rebuild the solution, and restart the dev server but it refuses to display the updated code.
I switch to a different browser, no dice.
I clear browser cache's to no avail.
I completely delete my local code and do a fresh fetch from our repository, again, no love from silverlight.
I have not been without a little success though. The ONE bone I've been thrown was over the weekend. Not touching it for a couple days, I came back to work on Monday and, without having done anything to it, it just updated. Now, however, it's cached again, or something, because it's stuck in the last set of changes I made to it.
So my question is this: What am I missing?
Most likely your files may be read only and MS Build fails to display error message and it does not update files. In case if you have mistakenly checked in your .xap files, then this is possible, you will have to remove it from your source control and also make .xap file writable by removing readonly checkbox.
Visual Studio checks in your .xap files by mistake and silverlight build does not report any error.
Second, do you have any other file backup service installed like Shadow copy or Dropbox kind of online backup service, something is probably making xap files readonly and that is causing this problem.
Here there are couple answers: Prevent Silverlight 3 from caching while debugging
Code below helped me(add this to Page_Load of page that hosted the app ):
Response.Cache.SetExpires(DateTime.Now.AddSeconds(-100));
Response.Cache.SetCacheability(HttpCacheability.NoCache);
UPDATE:
Prevent Silverlight xap from being cached by proxy server
"So my question is this: What am I missing?"
An internal caching mechanism that our application uses. So, none of you could really have helped me as it was an architectural feature of our software.
I have a common silverlight project. This project project, among other things, includes constants and static classes.
The silverlight App i have references this common library.
In addition, i have a handful of external modules that are loaded on-demand (via Prism). Each module is its own .Xap file and they too reference the common library.
So now each Xap in my silverlight application has a reference to the Common.dll.
Does this mean the common.dll is loaded every time a xap is loaded, or does it essentially mean only the main App's common.dll is ever loaded?
The ultimate question im getting at is this:
If i make a code change (bug fix) in the common.dll, do i have to release ALL Xap files or just the main App xap?
Thanks.
If you use Assembly Caching in all projects that reference the common dll then you'll just get one copy downloaded as it's own zip file. This way all the different XAP files will reference the same dll. Otherwise common.dll will be included in each XAP file that references.
You'll need to create a common.extmap.xml file for your common.dll which needs to be in the same folder from where the dll is referenced.
By default DLLs are loaded on demand. This means that you can't really guarantee which directory they will load from. This is a common issue among modular applications and one that there isn't a ready prescription for. It depends on requirements, essentially.
Some things you can do:
GAC the Common.dll in the target environment. This will allow you to control the versioning of that DLL centrally.
Release everything every time Common.dll changes (as you mentioned).
We have opted for number 2 (we treat our "Common.dll" as a contract assembly that changes rarely) in order to keep our xcopy deployments intact.
Number 1 might make more sense if you anticipate that code churn on Common.dll will be high or you want to keep your deployment schedules for modules completely autonomous (like if the modules were being developed and deployed by seperate teams with seperate build and source respositories, for example).
Edit: It looks like Silverlight has something to provide an xcopy variant of the GAC approach. ChrisF's answer is probably the way I would go with Silverlight (we do WPF, so that's a bit different). I'll leave this here for posterity.
I have an application for a huge business, which needs many pages, controls etc. The .xap file easily goes up to 50MB. I notice that every time when I load the page, the .xap file got downloaded to my local. However, my users may use 3G network to connect, so it must be very slow if we downlaod the app everytime they open the page. So I was wondering if there is some way I can do the deployment similar to WPF, which only download to local when the version is changed....
Any other suggestion to improve the loading speed is welcomed.
Thanks a lot
First and for most get your web server caching headers sorted. Typically you open the ClientBin folder in IIS Manager and enter the HTTP Response Header section. Set expiry to something like 1 Day (or if you update during normal working hours set to 15 Minutes). Note just because the content expires doesn't mean it will be re-downloaded but it does mean it'll get cached before being used. The browser will inform the server of the version it currently has if it has expired allow the server to simply respond with "go ahead and use that it hasn't changed since the last time you checked".
For such a large system you should seriously consider dividing the app up into multiple dll projects. Then use the Application Library Caching feature found in the main apps project properties. You need to create the appropriate .extmap.xml files for each of your dlls. Many of the SDK and Toolkit dlls have them already. This results in separate .zip files for these dlls being placed in the ClientBin folder and not incorporated into one large Xap. This allows you separate slow moving / never changing code into a set of zips and more frequently changing business code into another set. When you update the app the you only update the changed zips thus reducing the download burden of a new version. (Note this only works with inbrowser based apps).
In the serverlight project option, check the Reduce XAP size by using application library caching.
Using Silverlight 3, I noticed that System.Xml.Linq.dll was added to my XAP file, increasing the size from 12 to 58 k, so I checked the box 'Reduce XAP Size by using application library caching'.
Publishing the app to IIS, then loading it with Web Dev Helper enabled, I see that when I open the app, the XAP file at 12k is loaded, then the System.Xml.Linq.zip is loaded at 46k, for a total of 58k. Whenever I refresh the main page of the app, the same files are loaded into the browser. If I uncheck the 'Reduce..." box, then re-publish the app to IIS, one XAP file at 58k is loaded whenever I load the application.
How is one method different from or better than the other? I could see the advantage if the dll were somehow saved on the client computer removing the need to download it each time the app were opened.
Thanks
Mike Thomas
A browser caches by URL, so by splitting your application into a part which changes frequently and a part which will probably stay the same for a long time (the Linq part) and which might be shared between applications even, you save some download.
But it depends on the exact situation (frequency of change, location of 'generic' DLLs, etc.) whether it really helps.
The whole reason for keeping XAP size small is so that your application loads as quickly as possible. This is important: even on a faster connection, a bloated XAP can take extra seconds to load, which can be long enough for your users to leave your site.
While Linq is only accounting for 46KB, there are other cases where this can make a bigger deal. For instance, the SyndicationFeed class makes it really easy to handle RSS and ATOM feeds, but it weighs in at 114KB.
Application library caching helps in two ways:
It allows for sharing common DLL's between applications, so if another application has already pulled down a system DLL, your app can just reference it.
It allows your application updates to be smaller, since the framework DLL's won't change betwen XAP versions.
The difference is that when dll's are outside of the XAP file even though browser asks for those files webserver responds with 304 Not Modified HTTP response.
By default browser will not request for those files to be downloaded again. This obviously saves time especially when project references "heavy" libraries (ie. Telerik ones can be quite large in size)
Hope this helps someone.