I have a path "$/Folder1/Folder2/Folder3/File.xml" I would like to get the path minus "File.xml" i.e. "$/Folder1/Folder2/Folder3".
I have written the following method,
public string GetFilePathFromFolderPath(string serverPath)
{
var folders = serverPath.Split('/').ToList();
folders.RemoveAt(folders.Count - 1);
return folders.Aggregate(string.Empty,
(current, folder) =>
!string.IsNullOrEmpty(current)
? string.Format("{0}/{1}", current, folder)
: string.Format("{0}", folder));
}
Is there a better way to do this?
My Unit Test works fine but I would like to know if there is a simple way...
[TestMethod()]
public void GetRootPathFromConfigFilePath_Validate()
{
var t = new Twrar();
var a = t.GetFilePathFromFolderPath("$/Quan/Maa/CSr/mai.py");
Assert.IsTrue(a == "$/Quan/Maa/CSr");
}
I assume you mean to use "/" as the path separator character even though it is "\" for Windows.
Dim s = "$/Quan/Maa/CSr///mai.py"
Console.WriteLine(System.IO.Path.GetDirectoryName(s).Replace("\"c, "/"c))
outputs $/Quan/Maa/CSr
The following is Tarun Arora's edit:
For C# this should be...
public string GetFilePathFromFolderPath(string serverPath)
{
return Path.GetDirectoryName(serverPath).Replace("\\", "/");
}
And all of my unit tests pass this...
[TestMethod()]
public void GetRootPathFromConfigFilePath_Validate()
{
var t = new TfsWrapper();
var a = t.GetFilePathFromFolderPath("$/Quan/Maa/CSr/mai.py");
Assert.IsTrue(a == "$/Quan/Maa/CSr");
}
[TestMethod()]
public void GetRootPathFromConfigFilePath_SmallPath()
{
var t = new TfsWrapper();
var a = t.GetFilePathFromFolderPath("$/Quan/mai.py");
Assert.IsTrue(a == "$/Quan");
}
[TestMethod()]
public void GetRootPathFromConfigFilePath_RootPath()
{
var t = new TfsWrapper();
var a = t.GetFilePathFromFolderPath("$/mai.py");
Assert.IsTrue(a == "$");
}
I have this method:
private static string GetPath(string fullPath)
{
string file = System.IO.Path.GetFileName(fullPath);
return fullPath.Replace(file, "");
}
Related
I am new to Web API and REST services and looking to build a simple REST server which accepts file uploads. I found out grapevine which is simple and easy to understand. I couldn't find any file upload example?
This is an example using System.Web.Http
var streamProvider = new MultipartFormDataStreamProvider(ServerUploadFolder);
await Request.Content.ReadAsMultipartAsync(streamProvider);
but the grapevine Request property does not have any method to do that. Can someone point me to an example?
If you are trying to upload a file as a binary payload, see this question/answer on GitHub.
If you are trying to upload a file from a form submission, that will be a little bit trickier, as the multi-part payload parsers haven't been added yet, but it is still possible.
The following code sample is complete untested, and I just wrote this off the top of my head, so it might not be the best solution, but it's a starting point:
public static class RequestExtensions
{
public static IDictionary<string, string> ParseFormUrlEncoded(this IHttpRequest request)
{
var data = new Dictionary<string, string>();
foreach (var tuple in request.Payload.Split('='))
{
var parts = tuple.Split('&');
var key = Uri.UnescapeDataString(parts[0]);
var val = Uri.UnescapeDataString(parts[1]);
if (!data.ContainsKey(key)) data.Add(key, val);
}
return data;
}
public static IDictionary<string, FormElement> ParseFormData(this IHttpRequest request)
{
var data = new Dictionary<string, FormElement>();
var boundary = GetBoundary(request.Headers.Get("Content-Type"));
if (boundary == null) return data;
foreach (var part in request.Payload.Split(new[] { boundary }, StringSplitOptions.RemoveEmptyEntries))
{
var element = new FormElement(part);
if (!data.ContainsKey(element.Name)) data.Add(element.Name, element);
}
return data;
}
private static string GetBoundary(string contenttype)
{
if (string.IsNullOrWhiteSpace(contenttype)) return null;
return (from part in contenttype.Split(';', ',')
select part.TrimStart().TrimEnd().Split('=')
into parts
where parts[0].Equals("boundary", StringComparison.CurrentCultureIgnoreCase)
select parts[1]).FirstOrDefault();
}
}
public class FormElement
{
public string Name => _dispositionParams["name"];
public string FileName => _dispositionParams["filename"];
public Dictionary<string, string> Headers { get; private set; }
public string Value { get; }
private Dictionary<string, string> _dispositionParams;
public FormElement(string data)
{
var parts = data.Split(new [] { "\r\n\r\n", "\n\n" }, StringSplitOptions.None);
Value = parts[1];
ParseHeaders(parts[0]);
ParseParams(Headers["Content-Disposition"]);
}
private void ParseHeaders(string data)
{
Headers = data.TrimStart().TrimEnd().Split(new[] {"\r\n", "\n"}, StringSplitOptions.RemoveEmptyEntries).Select(header => header.Split(new[] {':'})).ToDictionary(parts => parts[0].TrimStart().TrimEnd(), parts => parts[1].TrimStart().TrimEnd());
}
private void ParseParams(string data)
{
_dispositionParams = new Dictionary<string, string>();
foreach (var part in data.Split(new[] {';'}))
{
if (part.IndexOf("=") == -1) continue;
var parts = part.Split(new[] {'='});
_dispositionParams.Add(parts[0].TrimStart(' '), parts[1].TrimEnd('"').TrimStart('"'));
}
}
}
If you are looking for something async to use immediately, you can try to implement the answer to this stackoverflow question, which has not been tested by me.
I tried this solution: Custom fields with FormBuilder in the Microsoft Bot Framework
But failed to get it working....The problem I encountered is that when I assign the base.Form = value, the _prompt in the _field gets a default recognizer, and it won't get overriden in the next line's SetRecognizer call, that only replaces the _field's recognizer.
However the matching process uses the _prompt's recognizer internally ( ? ).
Here is my code:
public class LuisIntentRecognizer<T> : RecognizePrimitive<T>
where T : class
{
public LuisIntentRecognizer(IField<T> field, string luisModelID, string luisSubscriptionKey)
: base(field)
{
_luisModelID = luisModelID;
_luisSubscriptionKey = luisSubscriptionKey;
}
public override DescribeAttribute ValueDescription(object value)
{
return new DescribeAttribute((string)value);
}
public override IEnumerable<string> ValidInputs(object value)
{
yield return (string)value;
}
public override TermMatch Parse(string input)
{
TermMatch result = null;
if (!string.IsNullOrWhiteSpace(input))
{
var luisModel = new LuisModelAttribute(_luisModelID, _luisSubscriptionKey);
var luisService = new LuisService(luisModel);
var luisResult = luisService.QueryAsync(input).Result; // TODO refactor somehow to async
var winner = luisResult.Intents.MaxBy(i => i.Score ?? 0d);
if (winner != null && !string.IsNullOrEmpty(winner.Intent))
{
result = new TermMatch(0, winner.Intent.Length, 0.0, winner.Intent);
}
else
{
result = new TermMatch(0, input.Length, 0.0, input);
}
}
return result;
}
public override string Help(T state, object defaultValue)
{
var prompt = new Prompter<T>(_field.Template(TemplateUsage.StringHelp), _field.Form, null);
var args = HelpArgs(state, defaultValue);
return prompt.Prompt(state, _field.Name, args.ToArray()).Prompt;
}
private string _luisModelID;
private string _luisSubscriptionKey;
}
public class LuisIntentField<T> : FieldReflector<T>
where T : class
{
public LuisIntentField(string name, string luisModelID, string luisSubscriptionKey, bool ignoreAnnotations = false)
: base(name, ignoreAnnotations)
{
_luisModelID = luisModelID;
_luisSubscriptionKey = luisSubscriptionKey;
}
public override IForm<T> Form
{
set
{
base.Form = value;
base.SetRecognizer(new LuisIntentRecognizer<T>(this, _luisModelID, _luisSubscriptionKey));
}
}
private string _luisModelID;
private string _luisSubscriptionKey;
}
Could anyone get it working?
Thanks
It seems to be a bug in the framework indeed: https://github.com/Microsoft/BotBuilder/issues/879
I have a radEditor control with the ImageManager enabled. this feature worked fine within our last version we had (2011 version) but now with the version we have, the image manager does not insert the image selected. Below is my radEditor html tag:
<telerik:RadEditor ID="txtRTE"
SpellCheckSettings-AllowAddCustom="false"
ToolsFile="~/SimpleRTEEditorTools.xml"
OnClientLoad="HandleRTEClientLoad"
ExternalDialogsPath="~/RadControls/EditorDialogs/"
runat="server"
Height="200"
Skin="Default"
EditModes="Design"
AllowScripts="false"
StripFormattingOptions="All">
<ImageManager ViewPaths=".." UploadPaths=".." SearchPatterns="*.jpg,*.gif,*.png" EnableImageEditor="False" ViewMode="Grid" />
I am editing the ViewPaths and uploadPaths within the code behind's page_load method:
txtRTE.ImageManager.ViewPaths = paths;
txtRTE.ImageManager.UploadPaths = paths;
txtRTE.ImageManager.ContentProviderTypeName = typeof(FolderContentProvider).AssemblyQualifiedName;
We implemented our own content provider as seen below:
public class FolderContentProvider : FileBrowserContentProvider
{
private string ROOT_DIRECTORY_FULL_PATH =
//Path to record documents folder
System.Configuration.ConfigurationManager.AppSettings[Constants.RECORD_DOC_ROOT_FOLDER_APP_KEY].ToString() +
//folder containing images
Constants.Record_DOC_FORM_TEXT_IMAGE_FOLDER + "\\" +
//to get Record ID
((MyAppPrincipal)System.Threading.Thread.CurrentPrincipal).Record.ID;
public string RootDirectory
{
get
{
return ROOT_DIRECTORY_FULL_PATH;
}
private set
{
}
}
private PathPermissions fullPermissions = PathPermissions.Read | PathPermissions.Upload;
private DirectoryItem[] GetSubDirectories(string path)
{
//we have only one directory no sub directories
//no need to go to file system to find that out
return new DirectoryItem[0];
}
private string GetDirectoryFullPath(string path)
{
return RootDirectory;
}
private FileItem[] GetFiles(string path)
{
string[] filesFullName = Directory.GetFiles(RootDirectory);
ArrayList files = new ArrayList();
for (int i = 0; i < filesFullName.Length; i++)
{
string fullPath = filesFullName[i];
System.IO.FileInfo currentFile = new System.IO.FileInfo(fullPath);
if (IsAlowedFileExtension(currentFile.Extension))
{
string url = string.Format("{0}?path={1}", HttpContext.Current.Request.ApplicationPath + "/app/FormTextImageHandler.ashx", currentFile.Name);
files.Add(new FileItem(
currentFile.Name, //file name
currentFile.Extension, //extension
currentFile.Length, //size
string.Empty,//currentFile.FullName, //location
url, //url
string.Empty,//tag
fullPermissions//permissions
));
}
}
return (FileItem[])files.ToArray(typeof(FileItem));
}
private bool IsAlowedFileExtension(string Extension)
{
if (Extension.Equals(".gif", StringComparison.InvariantCultureIgnoreCase))
return true;
if (Extension.Equals(".jpg", StringComparison.InvariantCultureIgnoreCase))
return true;
if (Extension.Equals(".png", StringComparison.InvariantCultureIgnoreCase))
return true;
return false;
}
public FolderContentProvider(HttpContext context, string[] searchPatterns, string[] viewPaths, string[] uploadPaths, string[] deletePaths, string selectedUrl, string selectedItemTag)
: base(context, searchPatterns, viewPaths, uploadPaths, deletePaths, selectedUrl, selectedItemTag)
{
}
public override string DeleteFile(string path)
{
//we do not allow removing files
return null;
}
public override string DeleteDirectory(string path)
{
//we don't have any sub directories
//and moreover we don't give delete rights
return null;
}
public override string StoreFile(Telerik.Web.UI.UploadedFile file, string path, string name, params string[] arguments)
{
int fileLength = (int)file.InputStream.Length;
byte[] content = new byte[fileLength];
file.InputStream.Read(content, 0, fileLength);
string fullPath = RootDirectory +"\\"+ name;
FileStream fileStream = new FileStream(fullPath, FileMode.OpenOrCreate);
fileStream.Write(content, 0, content.Length);
fileStream.Flush();
fileStream.Close();
return string.Empty;
}
public override DirectoryItem ResolveDirectory(string path)
{
DirectoryItem[] directories = new DirectoryItem[0];
FileItem[] files = this.GetFiles(RootDirectory);
DirectoryItem dir = new DirectoryItem("Images", string.Empty, RootDirectory, string.Empty, fullPermissions, files, directories);
return dir;
}
public override DirectoryItem ResolveRootDirectoryAsTree(string path)
{
//we don't have any subdirectories - everythinng is in the same folder
DirectoryItem[] directories = new DirectoryItem[0];
FileItem[] files = this.GetFiles(RootDirectory);
DirectoryItem root = new DirectoryItem("Images", string.Empty, "Images\\", string.Empty, fullPermissions, files, directories);
return root;
}
public override bool CanCreateDirectory
{
get
{
return false;
}
}
public override string CreateDirectory(string path, string name)
{
return null;
}
public override string StoreBitmap(Bitmap bitmap, string url, ImageFormat format)
{
return null;
}
public override Stream GetFile(string url)
{
return null;
}
public override string GetPath(string url)
{
return RootDirectory;
}
public override string GetFileName(string url)
{
return null;
}
[Obsolete]
public override DirectoryItem[] ResolveRootDirectoryAsList(string path)
{
return null;
}
public override bool CheckWritePermissions(string folderPath) {
return true;
}
}
Any idea's why the old version was able to insert into the field, but the new version is not?
The FileBrowserProvider API could be changed between the old and new versions. That why my suggestion is to examine the code of the following demo http://demos.telerik.com/aspnet-ajax/editor/examples/dbfilebrowsercontentprovider/defaultcs.aspx that works as expected and compare it with the code of your custom solution.
If you have any customized dialogs you may need to copy the EditorDialogs folder from the new installation that you are using and customize them from scratch.
Best regards,
Rumen
I'm trying iterate a sting[] and get only records which respects the condition "Contains".
I've been trying this:
var lines = File.ReadAllLines("C:\\temp\\" + ReportPushFile("fileToSend_1.txt")).Where(i => i.Contains("BILL"));
But this returns me all records again without no filtering. What's wrong?
class Program : Logger
{
public static FTPclient Ftp = new FTPclient("ftp://smsftp.mobyt.it/", "C17053_004", "i7z0dx5b");
static void Main(string[] args)
{
List<Sms> sms = new List<Sms>();
sms.Add(new Sms() { recipient = "+393664528452" });
var lines = File.ReadAllLines("C:\\temp\\" + ReportPushFile("fileToSend_1.txt")).Where(i => i.StartsWith("BILL"));
// ...
}
public static string ReportPushFile(string NomeFile)
{
try
{
String LocalFileName = Ftp.ListDirectory("/reports/").Where(f => f.Contains(NomeFile)).OrderBy(x => new FileInfo(x).CreationTime).Max();
Ftp.Download("/reports/" + LocalFileName, "c:\\temp\\" + LocalFileName, true);
return LocalFileName;
}
catch(Exception ex)
{
return string.Empty;
}
}
}
Your code should work. Let's split it up and make the types explicit:
string path = "C:\\temp\\" + ReportPushFile("fileToSend_1.txt");
string[] readLines = File.ReadAllLines(path);
IEnumerable<string> lines = readLines.Where(i => i.Contains("BILL"));
You can now set some debug points and verify that:
readLines contains a list of lines.
lines contains only those lines that have BILL in them.
I have a type which has a default sort order as it implements IComparable<T> and IComparable. I'm not getting the results I expect from LINQ , basically it looks as if the IComparable<T> which the type implements is not being applied.
I thought I would get the result I want with an expression in the form:
var result = MyEnumerable<T>.OrderBy(r => r);
where T itself implements IComparable<T>. It's not happening.
I can see related questions where specific IComparable<T> classes are specified for the sort, but I can't find one which uses the default IComparable<T> implemented by T itself.
My syntax is clearly incorrect. What is the correct syntax please?
Thanks in advance.
OrderBy uses the default comparer Comparer<T>.Default which in turn will default to use the IComparable<T> implementation for T, or the non-generic IComparable if the former does not exist.
This code works:
public class Program
{
static void Main(string[] args)
{
var list = new List<Stuff>
{
new Stuff("one"),
new Stuff("two"),
new Stuff("three"),
new Stuff("four")
};
var sorted = list.OrderBy(x => x);
foreach (var stuff in sorted)
{
Console.Out.WriteLine(stuff.Name);
}
}
}
public class Stuff : IComparable<Stuff>
{
public string Name { get; set; }
public Stuff(string name)
{
Name = name;
}
public int CompareTo(Stuff other)
{
return String.CompareOrdinal(Name, other.Name);
}
}
public static class GenericSorter
{
public static IOrderedEnumerable<T> Sort<T>(IEnumerable<T> toSort, Dictionary<string, SortingOrder> sortOptions)
{
IOrderedEnumerable<T> orderedList = null;
foreach (KeyValuePair<string, SortingOrder> entry in sortOptions)
{
if (orderedList != null)
{
if (entry.Value == SortingOrder.Ascending)
{
orderedList = orderedList.ApplyOrder<T>(entry.Key, "ThenBy");
}
else
{
orderedList = orderedList.ApplyOrder<T>(entry.Key, "ThenByDescending");
}
}
else
{
if (entry.Value == SortingOrder.Ascending)
{
orderedList = toSort.ApplyOrder<T>(entry.Key, "OrderBy");
}
else
{
orderedList = toSort.ApplyOrder<T>(entry.Key, "OrderByDescending");
}
}
}
return orderedList;
}
private static IOrderedEnumerable<T> ApplyOrder<T>(this IEnumerable<T> source, string property, string methodName)
{
ParameterExpression param = Expression.Parameter(typeof(T), "x");
Expression expr = param;
foreach (string prop in property.Split('.'))
{
expr = Expression.PropertyOrField(expr, prop);
}
Type delegateType = typeof(Func<,>).MakeGenericType(typeof(T), expr.Type);
LambdaExpression lambda = Expression.Lambda(delegateType, expr, param);
MethodInfo mi = typeof(Enumerable).GetMethods().Single(
method => method.Name == methodName
&& method.IsGenericMethodDefinition
&& method.GetGenericArguments().Length == 2
&& method.GetParameters().Length == 2)
.MakeGenericMethod(typeof(T), expr.Type);
return (IOrderedEnumerable<T>)mi.Invoke(null, new object[] { source, lambda.Compile() });
}
}