OK... so here is something I do not even know if it is even possible. Is it possible to upload an image file during the initial phase of a code first migration? For instance, when creating an initial site user or an admin user that has a portrait image, would it be possible to upload that image during the initial creation of that user?
I couldn't find anything relevant in SO or online that would even come close to even suggest a viable solution so this might be the very first time something like this has even been attempted.
First, create the new migration file (or use the existing one).
Inside Up() method you can put code for
file upload, and inside Down() method code for file removal from
repo (in case you want to revert migration).
Below is one of the many possible ways to do some remote upload, this is one of the simplest:
using (var webClient = new WebClient())
{
webClient.UploadFile("ftp://localhost/samplefile.jpg", "samplefile.jpg");
}
For this to work you should add using System.Net; to the migration file. Also, obviously you need to handle upload permissions and credentials, depending on the type of remote repo you are using.
EDIT:
Using File object is even more trivial. Here is the complete code for migration class:
using System;
using System.Data.Entity.Migrations;
using System.IO;
public partial class MigrationWithFileCopy : DbMigration
{
public override void Up()
{
File.Copy("sourceFile.jpg", "destinationFile.jpg");
}
public override void Down()
{
File.Delete("destinationFile.jpg");
}
}
Related
Say If we use two separate files called a.cs and b.cs in a C# project using VISUAL STUDIO, my question is does one file aware of the other WITHOUT putting a using statement about the other file. ie In the file a.cs can we use a class that is already defined in b.cs but not putting a using b.cs; statement in the beginning of the file?.When we compile altogether will the project know each file content and won't raise any error?
I guess you are on the wrong track here. Files don't interact with each other. But the classes do. Namespaces are used to refer to the class that are meant to be used. You can change the file name to anything several times, it won't affect your project. Moreover you can put many classes inside the same file name under the same namespace and you won't have to use using.
Just consider this scenario, Namespace are the area code, and the phone numbers are the classes. Being in the same area already, you don't have to use the area code to call a different number that exists in the same area. But if you are dialling a number outside your area, you would want to use the area code. Basically by adding area code(namespace) infront of the number, you are applying using to refer to the other number(class). Hope you got the idea.
Edit: Explaining programmatically
Suppose this is your Area
using something;
using someotherthing;
namespace MyMainNamespace
{
private class MyMainClass
{
private void blahblah { ... }
}
private class ClassABC
{
private void blahblah { ... }
}
private class ClassXYZ
{
private void blahblah { ... }
}
}
See, in the above example, to interact with the MyMainClass, ClassABC & ClassXYZ. you don't have to use using MyMainNamespace;. Because they all lie in the same area MyMainNamespace. But there exists a class in another namespace like shown below:
using something;
using someotherthing;
namespace SubNamespace
{
public class SecondaryClass
{
public void apple{ ... }
}
}
If you want to access SecondaryClass which lies in SubNamespace(different area) you would have to use using SubNamespace; in your main area. Like:
using something;
using someotherthing;
using SubNamespace; //add the namespace
namespace MyMainNamespace
{
private class MyMainClass
{
private void blahblah {
...
// Now you can use methods & functions that exist in `SecondaryClass`
SecondaryClass secondary = new SecondaryClass();
secondary.apple();
....
....
}
}
}
Hope this is enough to get the idea by now
Also, it doesn't matter that these namespace(MyMainNamespace & SubNamespace) lies in the same file or different file. You NEVER REFER TO THE FILENAME(filename.cs) by applying using. You ALWAYS REFER TO THE NAMESPACES.
If the C# code in a.cs and b.cs are inside the same namespace, then no using statement should be needed. If the 2 cs files use different namespaces, then you will have to put a using statement for the namespace of the code you want to reference.
After deploying a new version of a website the browser loads everything from its cache from the old webpage until a hard, force refresh is done.
In ASP.NET MVC if the file becomes in Bundle, it handled by Optimization framework. a version added to your file link, and if a change occurs in your bundle's file a new token generate. follow below code :
for example, js file name is: datatables
when you put it in a bundle with the same name, you will see the
datatables?v=anY9_bo7KitrGnXQr8ITP3ylmhQe9NDzSjgLpLQWQFE1
as a file name.
change datatables and watch again the name of the file in the browser, surely it will change:
datatables?v=r8yhQBxKyDgrOGyqr1ndtdG92Ije09nqTY7yogrOSTk1
But there's two questions:
What we can do if our file wasn't in Bundle?
Is a way to force the browser to refresh cache?
we have one solution with some different way for implementation. we use above solution for it.
datatables?v=1
we can handle the version of the file, it's mean that every time that we change our file, change the version of it too. but it's not a suitable way.
another way used Guide, it wasn't suitable too, because each time it fetches the file and doesn't use from the browser cache.
datatables?v=Guid.NewGuid()
The last way that is the best Way is :
when file change occur , change version too. check follow code :
<script src="~/scripts/main.js?v=#File.GetLastWriteTime(Server.MapPath("/scripts/main.js")).ToString("yyyyMMddHHmmss")"></script>
by this way, when you change the file, LastWriteTime change too, so the version of the file will change and in the next when you open the browser, it detects a new file and fetch it.
Assuming you cannot use bundling for some reason, the solution suggested by the original poster is good enough, however it's better to put the logic inside a helper method.
It makes the code testable, it helps to change the logic without changing .cshtml , and also helps to not repeat the filename twice. Then you can have have a much cleaner code:
<script src="#Url.ContentWithVersion("~/scripts/main.js")"></script>
To do so, you can add ContentWithVersion extension method to the existing UrlHelper:
using System;
using System.IO;
using System.Web;
using System.Web.Mvc;
public static class UrlHelperExtensions
{
public static string ContentWithVersion(this UrlHelper urlHelper, string path)
{
if (urlHelper == null)
throw new ArgumentNullException(nameof(urlHelper));
var result = urlHelper.Content(path);
var file = HttpContext.Current.Server.MapPath(path);
if (File.Exists(file))
result += $"?v={File.GetLastWriteTime(file).ToString("yyyyMMddHHmmss")}";
return result;
}
}
Lightswitch (Desktop app, out-of-browser) has very limited documentation scattered here and there. I'm looking for a way to clear all data in the intrinsic database in order to add new data after significant changes were made.
Here's the only working solution I have for now:
Write a DeleteAll() method for each and every VisualCollection I have.
Add an event or button to a screen, for example.
Call all the DeleteAll() methods (at event fired or button click).
Save.
This is obviously not efficient at all and very not DRY. What I'd like to have is some kind of ClearDatabase() method that I'd be using only for development and debugging.
So here are the 2 important parts of my question:
Can I (and if so, how would I) get all EntitySets in my ApplicationData without hardcoding ?
Is it possible to call such a method from the Client side of my app ? I'm thinking maybe in the auto-generated Application.Application_Initialize().
Since at the time of this post there seems to be absolutely no answer to this question on the internet, I came up with new code by digging in Lightswitch's code.
Here's a working, tested solution I wrote. Just follow those very simple steps.
In the solution explorer, under yourAppName.Server, create a new folder named UserCode, if it doesn't exist already.
In that folder, add a new class named DataUtilities.
Delete all code in that new class, and paste in this code:
using Microsoft.LightSwitch;
using Microsoft.LightSwitch.Details;
using Microsoft.LightSwitch.Framework;
using Microsoft.LightSwitch.Threading;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
namespace LightSwitchApplication.UserCode
{
public static class DataUtilities
{
public static void DeleteAllSets(this DataWorkspace workspace, params Type[] excludedTypes)
{
List<Type> listExcludedTypes = excludedTypes.ToList();
ApplicationData appData = workspace.ApplicationData;
IEnumerable<IDataServiceProperty> properties = appData.Details.Properties.All();
foreach (IDataServiceProperty prop in properties)
{
dynamic entitySet = prop.Value;
Type entityType = entitySet.GetType().GetGenericArguments()[0];
if (!listExcludedTypes.Contains(entityType))
{
typeof(DataUtilities).GetMethod("DeleteSet", BindingFlags.Static | BindingFlags.Public)
.MakeGenericMethod(entityType)
.Invoke(null, new object[] { entitySet });
}
}
appData.SaveChanges();
}
public static void DeleteSet<T>(this EntitySet<T> entities) where T:
IDispatcherObject, IObjectWithDetails, IStructuralObject, INotifyPropertyChanged, IBusinessObject, IEntityObject
{
List<T> entityList = entities.Select(e => e).Execute().ToList();
int entityCount = entityList.Count();
for (int i = 0; i < entityCount; i++)
{
T entity = entityList.ElementAt(i);
if (entity != null)
{
// Uncomment the line below to see all entities being deleted.
// Debug.WriteLine("DELETING " + typeof(T).Name + ": " + entity);
entity.Delete();
}
}
}
}
}
Do step 1 again, but this time under yourAppName.DesktopClient. You should now have 2 folders named UserCode, one in both side of the application.
Right-click on that last folder (UserCode in yourAppName.DesktopClient), go to Add and then Existing Element... .
Navigate to ...\yourAppName\yourAppName.Server\UserCode.
Select DataUtilities.cs, and click on the little down arrow besides the Add button. Choose Add as link. Now the class can be used on both Server side AND Client Side.
Now let's use the new extension methods !
Back in the solution explorer, Right-click on yourAppName.DesktopClient, and select Show Application Code (Should be the first option in the dropdown menu).
Replace the generated code with this (Or, if you had some custom code already in that class, add the single line I show in Application_Initialize()):
using LightSwitchApplication.UserCode;
namespace LightSwitchApplication
{
public partial class Application
{
partial void Application_Initialize()
{
Current.CreateDataWorkspace().DeleteAllSets();
}
//Some other methods here if you already modified this class.
}
}
Voila ! The next time you start your application, all data stored in the intrinsic database should be gone.
More info on the code:
How it works
I won't explain the whole process here but basically:
DeleteAllSets(...) will get all the EntitySets of the data source and call DeleteSet(...) on each one of them.
DeleteSet(...) will call the already existing Delete() method on each entity in the EntitySet.
How to exclude data from deletion
You can also pass in Type parameters to the DeleteAllSets(...) method to exclude those from the deletion process:
Lets say I have 2 tables storing employees data and products data respectively. Let those tables be called Employee and Product. If, for example, I had added test data in the Product table, and wanted to get rid of it, without deleting all my employees, I'd use the extension method like this:
Current.CreateDataWorkspace().DeleteAllSets(typeof(Employee));
This would delete all the entities in the Product table only.
I hope this helps anyone stuck with Lightswitch's not-so-easy debugging and testing ! The whole process is probably translatable to the Web version, but I'll leave that to someone else.
First thing to say is that I can't use built in Properties.Settings, as these settings are stored in an XML file which are used by several people (not at the same time but via version control).
I am developing a code generation tool which allows the users to specificy the output locations of all the generated files, along with other project specific settings.
Currently, in the application I have a static class called ProjectSettings which has a public static parameter for each setting using the in program:
public static string Settings_ScreenDefinitions_C;
public static string Settings_ScreenDefinitions_H;
// Etc currently there are about 20 of these.
Is there a better way of storing and accessing these thoughout the project?
Secondly these settings are stored in an XML using a read/write call for each setting in the above ProjectSettings class:
xmlWriter.WriteElementString("ScreenDefinitionsFileC", ProjectSettings.Settings_ScreenDefinitions_C);
xmlWriter.WriteElementString("ScreenDefinitionsFileH", ProjectSettings.Settings_ScreenDefinitions_H);
// Again there is around 20 of these, one for each property and the same for reading them back out.
As I add more properties I can't help but feel that there must be a more elegant way of constructing the class (maybe a dictionary?) and a better way of using that within the XML for saving and reading?
Any suggestions/pointers would be great.
Here is how I would do it with an enum and a dictionary. I've used console output to show how you can write the key and value of the dictionary.
using System;
using System.Collections.Generic;
namespace ConsoleApplication
{
class Program
{
private enum Settings
{
ScreenDefinitionsFileC,
ScreenDefinitionsFileH
};
static void Main(string[] args)
{
var settings= new Dictionary<Settings, string>()
{
{Settings.ScreenDefinitionsFileC, "Setting 1"},
{Settings.ScreenDefinitionsFileH, "Setting 2"}
};
foreach (var setting in settings)
{
Console.WriteLine("{0} {1}", setting.Key, setting.Value);
}
Console.ReadKey(true);
}
}
}
This way you can enumerate your settings when writing to XML, but can also look-up specific settings during the life cycle of your program.
I don't know the whole list of the configurations, but I hope most of them may be controlled by adding different configuration in configurationManger, that is if you add "MyConfiguration" you can open afterwards project settings (especially pre-build and post build event)and the configurations there are all only for "myConfiguration" so switching between different configurations is only by selecting different configuration.
I am new to writing plugin for rhino 3d.
I have gone through the documentation and sample code here:
http://wiki.mcneel.com/developer/dotnetplugins
but unable to figure out how to open a .3dm file from plugin.
Can someone help me?
Thanks!!
It depends a little on what you are trying to do and which version of Rhino you are running.
If you are running Rhino 4 and using the Rhino_DotNet SDK, then you need to have your command class derive from MRhinoScriptCommand and call RhinoApp().RunScript(#"-_Open C:\path_to_model.3dm")
If you are running Rhino 5 and using the RhinoCommon SDK (recommended), then you should call RunScript in a fashion that Brian suggested above. You also need to mark your command class with the the Rhino.Commands.Style attribute of ScriptRunner
ex.
using Rhino.Commands;
[CommandStyle(ScriptRunner)]
class MyCommand : Rhino.Commands.Command
{
public override string EnglishName { get { return "MyCommand"; } }
protected override Result RunCommand(RhinoDoc doc, RunMode mode)
{
RhinoApp.RunScript(#"-_Open C:\model.3dm");
}
}
This will open the 3dm file and make it the active document.
On the other hand if you just want to read the 3dm file into memory and inspect the contents of it, I would recommend using the Rhino.FileIO.File3dm class in RhinoCommon. There is a static Read function on that class that you can use.
You can script the Open command from inside a plug-in using:
Rhino.RhinoApp.RunScript() to script the open command. For example:
Rhino.RhinoApp.RunScript(#"-_Open C:\model.3dm");