本文整理汇总了C#中Dev2.PathOperations.Dev2CRUDOperationTO类的典型用法代码示例。如果您正苦于以下问题:C# Dev2CRUDOperationTO类的具体用法?C# Dev2CRUDOperationTO怎么用?C# Dev2CRUDOperationTO使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。
Dev2CRUDOperationTO类属于Dev2.PathOperations命名空间,在下文中一共展示了Dev2CRUDOperationTO类的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C#代码示例。
示例1: Rename
/// <summary>
/// Renames a file or folder from src to dst as per the value of args
/// </summary>
/// <param name="src"></param>
/// <param name="dst"></param>
/// <param name="args"></param>
public string Rename(IActivityIOOperationsEndPoint src, IActivityIOOperationsEndPoint dst, Dev2CRUDOperationTO args)
{
Source = src;
Destination = dst;
Dev2CRUDOperationTO = args;
return "Successful";
}
开发者ID:NatashaSchutte,项目名称:Warewolf-ESB,代码行数:13,代码来源:ActivityOperationBrokerMock.cs
示例2: CopyFileWithPathsExpectedRecursiveCopy
public void CopyFileWithPathsExpectedRecursiveCopy()
{
var innerDir = Guid.NewGuid().ToString();
var tempPath = Path.GetTempPath();
var tempFileName = Path.GetFileName(Path.GetTempFileName());
const string TempData = "some string data";
if(tempFileName != null)
{
var tempFile = Path.Combine(tempPath, innerDir, innerDir, tempFileName);
string directoryName = Path.GetDirectoryName(tempFile);
if(directoryName != null)
{
Directory.CreateDirectory(directoryName);
}
var upperLevelDir = Path.Combine(tempPath, innerDir);
File.WriteAllText(tempFile, TempData);
var dst = Path.Combine(tempPath, Guid.NewGuid().ToString());
var scrEndPoint = ActivityIOFactory.CreateOperationEndPointFromIOPath(ActivityIOFactory.CreatePathFromString(upperLevelDir, string.Empty, null, true));
var dstEndPoint = ActivityIOFactory.CreateOperationEndPointFromIOPath(ActivityIOFactory.CreatePathFromString(dst, string.Empty, null, true));
var moveTO = new Dev2CRUDOperationTO(true);
ActivityIOFactory.CreateOperationsBroker().Copy(scrEndPoint, dstEndPoint, moveTO);
var newFilePath = Path.Combine(dst, innerDir, tempFileName);
Assert.IsTrue(File.Exists(newFilePath));
Assert.IsTrue(File.Exists(tempFile));
}
}
开发者ID:NatashaSchutte,项目名称:Warewolf-ESB,代码行数:27,代码来源:Dev2IOBrokerTests.cs
示例3: Create
public string Create(IActivityIOOperationsEndPoint dst, Dev2CRUDOperationTO args, bool createToFile)
{
CreateToFile = createToFile;
Destination = dst;
Dev2CRUDOperationTO = args;
return "Successful";
}
开发者ID:NatashaSchutte,项目名称:Warewolf-ESB,代码行数:7,代码来源:ActivityOperationBrokerMock.cs
示例4: ExecuteConcreteAction
protected override IList<OutputTO> ExecuteConcreteAction(IDSFDataObject dataObject, out ErrorResultTO allErrors, int update)
{
IList<OutputTO> outputs = new List<OutputTO>();
allErrors = new ErrorResultTO();
var colItr = new WarewolfListIterator();
//get all the possible paths for all the string variables
var outputItr = new WarewolfIterator(dataObject.Environment.Eval(OutputPath, update));
colItr.AddVariableToIterateOn(outputItr);
var unameItr = new WarewolfIterator(dataObject.Environment.Eval(Username, update));
colItr.AddVariableToIterateOn(unameItr);
var passItr = new WarewolfIterator(dataObject.Environment.Eval(DecryptedPassword,update));
colItr.AddVariableToIterateOn(passItr);
var privateKeyItr = new WarewolfIterator(dataObject.Environment.Eval(PrivateKeyFile, update));
colItr.AddVariableToIterateOn(privateKeyItr);
if(dataObject.IsDebugMode())
{
AddDebugInputItem(new DebugEvalResult(OutputPath, "File or Folder", dataObject.Environment, update));
AddDebugInputItem(new DebugItemStaticDataParams(Overwrite.ToString(), "Overwrite"));
AddDebugInputItemUserNamePassword(dataObject.Environment, update);
if (!string.IsNullOrEmpty(PrivateKeyFile))
{
AddDebugInputItem(PrivateKeyFile, "Destination Private Key File", dataObject.Environment, update);
}
}
while(colItr.HasMoreData())
{
IActivityOperationsBroker broker = ActivityIOFactory.CreateOperationsBroker();
Dev2CRUDOperationTO opTo = new Dev2CRUDOperationTO(Overwrite);
try
{
IActivityIOPath dst = ActivityIOFactory.CreatePathFromString(colItr.FetchNextValue(outputItr),
colItr.FetchNextValue(unameItr),
colItr.FetchNextValue(passItr),
true, colItr.FetchNextValue(privateKeyItr));
IActivityIOOperationsEndPoint dstEndPoint = ActivityIOFactory.CreateOperationEndPointFromIOPath(dst);
string result = broker.Create(dstEndPoint, opTo, true);
outputs.Add(DataListFactory.CreateOutputTO(Result, result));
}
catch(Exception e)
{
outputs.Add(DataListFactory.CreateOutputTO(Result, "Failure"));
allErrors.AddError(e.Message);
break;
}
}
return outputs;
}
开发者ID:FerdinandOlivier,项目名称:Warewolf-ESB,代码行数:58,代码来源:DsfPathCreate.cs
示例5: CreateDirectoryWithOverwriteTrue_Present_Expected_DirectoryCreated
public void CreateDirectoryWithOverwriteTrue_Present_Expected_DirectoryCreated()
{
Dev2CRUDOperationTO opTO = new Dev2CRUDOperationTO(true);
IActivityIOPath path = ActivityIOFactory.CreatePathFromString(_tmpdir1, "", "");
IActivityIOOperationsEndPoint FileSystemPro = ActivityIOFactory.CreateOperationEndPointFromIOPath(path);
bool ok = FileSystemPro.CreateDirectory(path, opTO);
Assert.IsTrue(ok);
}
开发者ID:FerdinandOlivier,项目名称:Warewolf-ESB,代码行数:9,代码来源:FileSystemTests.cs
示例6: PutWithOverwriteTrue_UNCPathValidUser_File_Present_FileInStream
public void PutWithOverwriteTrue_UNCPathValidUser_File_Present_FileInStream()
{
Dev2CRUDOperationTO opTO = new Dev2CRUDOperationTO(true);
string tmp = TestResource.PathOperations_UNC_Path_Secure + Guid.NewGuid() + ".test";
string tmp2 = TestResource.PathOperations_UNC_Path_Secure + Guid.NewGuid() + ".test";
PathIOTestingUtils.CreateAuthedUNCPath(tmp, false, _inDomain);
IActivityIOPath dst = ActivityIOFactory.CreatePathFromString(tmp, (_inDomain ? "DEV2\\" : ".\\") + TestResource.PathOperations_Correct_Username, TestResource.PathOperations_Correct_Password);
IActivityIOPath src = ActivityIOFactory.CreatePathFromString(tmp2, (_inDomain ? "DEV2\\" : ".\\") + TestResource.PathOperations_Correct_Username, TestResource.PathOperations_Correct_Password);
IActivityIOOperationsEndPoint FileSystemPro = ActivityIOFactory.CreateOperationEndPointFromIOPath(dst);
Stream stream = new MemoryStream(File.ReadAllBytes(_tmpfile1));
var directoryInfo = new FileInfo(src.Path).Directory;
if(directoryInfo != null)
{
int len = FileSystemPro.Put(stream, dst, opTO, directoryInfo.ToString(), new List<string>());
stream.Close();
PathIOTestingUtils.DeleteAuthedUNCPath(tmp);
PathIOTestingUtils.DeleteAuthedUNCPath(tmp2);
Assert.IsTrue(len > 0);
}
else
{
Assert.Fail();
}
}
开发者ID:FerdinandOlivier,项目名称:Warewolf-ESB,代码行数:26,代码来源:FileSystemTests.cs
示例7: PutWithOverwriteTrue_UNCPath_File_Present_Expected_FileReadIntoStream
public void PutWithOverwriteTrue_UNCPath_File_Present_Expected_FileReadIntoStream()
{
Dev2CRUDOperationTO opTO = new Dev2CRUDOperationTO(true);
string tmp = Path.GetTempFileName();
File.Delete(tmp);
IActivityIOPath dst = ActivityIOFactory.CreatePathFromString(tmp, "", "");
IActivityIOPath src = ActivityIOFactory.CreatePathFromString(_tmpfile2, "", "");
IActivityIOOperationsEndPoint FileSystemPro = ActivityIOFactory.CreateOperationEndPointFromIOPath(dst);
Stream stream = FileSystemPro.Get(src, new List<string>());
var directoryInfo = new FileInfo(src.Path).Directory;
if(directoryInfo != null)
{
int len = FileSystemPro.Put(stream, dst, opTO, directoryInfo.ToString(), new List<string>());
File.Delete(tmp);
Assert.IsTrue(len > 0);
}
else
{
Assert.Fail();
}
}
开发者ID:FerdinandOlivier,项目名称:Warewolf-ESB,代码行数:22,代码来源:FileSystemTests.cs
示例8: ValidateSourceAndDestinationContents
/// <summary>
/// Transfer the contents of the directory
/// </summary>
/// <param name="src"></param>
/// <param name="dst"></param>
/// <param name="args"></param>
void ValidateSourceAndDestinationContents(IActivityIOOperationsEndPoint src,
IActivityIOOperationsEndPoint dst,
Dev2CRUDOperationTO args)
{
if(!args.Overwrite)
{
var srcContentsFolders = src.ListFoldersInDirectory(src.IOPath);
foreach(var sourcePath in srcContentsFolders)
{
var sourceEndPoint =
ActivityIOFactory.CreateOperationEndPointFromIOPath(sourcePath);
IList<string> dirParts =
sourceEndPoint.IOPath.Path.Split(sourceEndPoint.PathSeperator().ToCharArray(),
StringSplitOptions.RemoveEmptyEntries);
var directory = dirParts.Last();
var destinationPath =
ActivityIOFactory.CreatePathFromString(dst.Combine(directory),
dst.IOPath.Username,
dst.IOPath.Password, true, dst.IOPath.PrivateKeyFile);
var destinationEndPoint =
ActivityIOFactory.CreateOperationEndPointFromIOPath(destinationPath);
if(destinationEndPoint.PathExist(destinationEndPoint.IOPath))
{
ValidateSourceAndDestinationContents(sourceEndPoint, destinationEndPoint, args);
}
}
var srcContents = src.ListFilesInDirectory(src.IOPath);
var dstContents = dst.ListFilesInDirectory(dst.IOPath);
var sourceFileNames = srcContents.Select(srcFile => GetFileNameFromEndPoint(src, srcFile)).ToList();
var destinationFileNames = dstContents.Select(dstFile => GetFileNameFromEndPoint(dst, dstFile)).ToList();
if(destinationFileNames.Count > 0)
{
var commonFiles = sourceFileNames.Where(destinationFileNames.Contains).ToList();
if(commonFiles.Count > 0)
{
var fileNames = commonFiles.Aggregate("",
(current, commonFile) =>
current + "\r\n" + commonFile);
throw new Exception(
"The following file(s) exist in the destination folder and overwrite is set to false:- " +
fileNames);
}
}
}
}
开发者ID:Robin--,项目名称:Warewolf,代码行数:59,代码来源:Dev2ActivityIOBroker.cs
示例9: Move
public string Move(IActivityIOOperationsEndPoint src, IActivityIOOperationsEndPoint dst,
Dev2CRUDOperationTO args)
{
string result;
try
{
result = Copy(src, dst, args);
if(result.Equals("Success"))
{
src.Delete(src.IOPath);
}
}
finally
{
_filesToDelete.ForEach(RemoveTmpFile);
}
return result;
}
开发者ID:Robin--,项目名称:Warewolf,代码行数:21,代码来源:Dev2ActivityIOBroker.cs
示例10: Copy
public string Copy(IActivityIOOperationsEndPoint src, IActivityIOOperationsEndPoint dst,
Dev2CRUDOperationTO args)
{
string status;
try
{
status = ValidateCopySourceDestinationFileOperation(src, dst, args, () =>
{
if(src.RequiresLocalTmpStorage())
{
if(dst.PathIs(dst.IOPath) == enPathType.Directory)
{
dst.IOPath.Path = dst.Combine(GetFileNameFromEndPoint(src));
}
using(var s = src.Get(src.IOPath, _filesToDelete))
{
// for flips sake quite putting short-hand notation in-line it causes bugs!!! ;)
dst.Put(s, dst.IOPath, args, Path.IsPathRooted(src.IOPath.Path) ? Path.GetDirectoryName(src.IOPath.Path) : null, _filesToDelete);
s.Close();
s.Dispose();
}
}
else
{
var sourceFile = new FileInfo(src.IOPath.Path);
if(dst.PathIs(dst.IOPath) == enPathType.Directory)
{
dst.IOPath.Path = dst.Combine(sourceFile.Name);
}
using(var s = src.Get(src.IOPath, _filesToDelete))
{
if(sourceFile.Directory != null)
{
dst.Put(s, dst.IOPath, args, sourceFile.Directory.ToString(), _filesToDelete);
}
}
}
return ResultOk;
});
}
finally
{
_filesToDelete.ForEach(RemoveTmpFile);
}
return status;
}
开发者ID:Robin--,项目名称:Warewolf,代码行数:49,代码来源:Dev2ActivityIOBroker.cs
示例11: Rename
public string Rename(IActivityIOOperationsEndPoint src, IActivityIOOperationsEndPoint dst,
Dev2CRUDOperationTO args)
{
string result;
try
{
result = ValidateRenameSourceAndDesinationTypes(src, dst, args);
}
finally
{
_filesToDelete.ForEach(RemoveTmpFile);
}
return result;
}
开发者ID:Robin--,项目名称:Warewolf,代码行数:14,代码来源:Dev2ActivityIOBroker.cs
示例12: Create
public string Create(IActivityIOOperationsEndPoint dst, Dev2CRUDOperationTO args, bool createToFile)
{
string result;
try
{
ValidateEndPoint(dst, args);
result = CreateEndPoint(dst, args, createToFile);
}
finally
{
_filesToDelete.ForEach(RemoveTmpFile);
}
return result;
}
开发者ID:Robin--,项目名称:Warewolf,代码行数:14,代码来源:Dev2ActivityIOBroker.cs
示例13: MoveTmpFileToDestination
string MoveTmpFileToDestination(IActivityIOOperationsEndPoint dst, string tmp, string result)
{
using(Stream s = new MemoryStream(File.ReadAllBytes(tmp)))
{
Dev2CRUDOperationTO newArgs = new Dev2CRUDOperationTO(true);
//MO : 22-05-2012 : If the file doesnt exist then create the file
if(!dst.PathExist(dst.IOPath))
{
CreateEndPoint(dst, newArgs, true);
}
if(dst.Put(s, dst.IOPath, newArgs, null, _filesToDelete) < 0)
{
result = ResultBad;
}
}
return result;
}
开发者ID:Robin--,项目名称:Warewolf,代码行数:18,代码来源:Dev2ActivityIOBroker.cs
示例14: ValidateEndPoint
void ValidateEndPoint(IActivityIOOperationsEndPoint endPoint, Dev2CRUDOperationTO args)
{
if(endPoint.IOPath.Path.Trim().Length == 0)
{
throw new Exception("Source can not be an empty string");
}
if(endPoint.PathExist(endPoint.IOPath) && !args.Overwrite)
{
var type = endPoint.PathIs(endPoint.IOPath) == enPathType.Directory ? "Directory" : "File";
throw new Exception(string.Format("Destination {0} already exists and overwrite is set to false",
type));
}
}
开发者ID:Robin--,项目名称:Warewolf,代码行数:14,代码来源:Dev2ActivityIOBroker.cs
示例15: ValidateCopySourceDestinationFileOperation
string ValidateCopySourceDestinationFileOperation(IActivityIOOperationsEndPoint src,
IActivityIOOperationsEndPoint dst,
Dev2CRUDOperationTO args,
Func<string> performAfterValidation)
{
var result = ResultOk;
ValidateSourceAndDestinationPaths(src, dst);
//ensures destination folder structure exists
var opStatus = CreateEndPoint(dst, args, dst.PathIs(dst.IOPath) == enPathType.Directory);
if(!opStatus.Equals("Success"))
{
throw new Exception("Recursive Directory Create Failed For [ " + dst.IOPath.Path + " ]");
}
//transfer contents to destination when the source is a directory
if(src.PathIs(src.IOPath) == enPathType.Directory)
{
if(!TransferDirectoryContents(src, dst, args))
{
result = ResultBad;
}
}
else
{
if(!args.Overwrite)
{
EnsureFilesDontExists(src, dst);
}
if(!Dev2ActivityIOPathUtils.IsStarWildCard(src.IOPath.Path))
{
return performAfterValidation();
}
// we have star wild cards to deal with
if(!TransferDirectoryContents(src, dst, args))
{
result = ResultBad;
}
}
return result;
}
开发者ID:Robin--,项目名称:Warewolf,代码行数:44,代码来源:Dev2ActivityIOBroker.cs
示例16: RecursiveCopy
void RecursiveCopy(IActivityIOOperationsEndPoint src, IActivityIOOperationsEndPoint dst, Dev2CRUDOperationTO args)
{
try
{
// List directory contents
var srcContentsFolders = src.ListFoldersInDirectory(src.IOPath);
Task.WaitAll(srcContentsFolders.Select(sourcePath => Task.Run(() =>
{
var sourceEndPoint =
ActivityIOFactory.CreateOperationEndPointFromIOPath(sourcePath);
IList<string> dirParts =
sourceEndPoint.IOPath.Path.Split(sourceEndPoint.PathSeperator().ToCharArray(),
StringSplitOptions.RemoveEmptyEntries);
var destinationPath =
ActivityIOFactory.CreatePathFromString(dst.Combine(dirParts.Last()), dst.IOPath.Username,
dst.IOPath.Password, true, dst.IOPath.PrivateKeyFile);
var destinationEndPoint =
ActivityIOFactory.CreateOperationEndPointFromIOPath(destinationPath);
dst.CreateDirectory(destinationPath, args);
TransferDirectoryContents(sourceEndPoint, destinationEndPoint, args);
})).ToArray());
}
catch(AggregateException e)
{
var message = e.InnerExceptions.Where(exception => exception != null && !string.IsNullOrEmpty(exception.Message)).Aggregate("", (current, exception) => current + exception.Message + "\r\n");
throw new Exception(message, e);
}
}
开发者ID:Robin--,项目名称:Warewolf,代码行数:28,代码来源:Dev2ActivityIOBroker.cs
示例17: PutRaw
public string PutRaw(IActivityIOOperationsEndPoint dst, Dev2PutRawOperationTO args)
{
var result = ResultOk;
// directory put?
// wild char put?
try
{
_fileLock.EnterWriteLock();
if(dst.RequiresLocalTmpStorage())
{
var tmp = CreateTmpFile();
switch(args.WriteType)
{
case WriteType.AppendBottom:
using(var s = dst.Get(dst.IOPath, _filesToDelete))
{
File.WriteAllBytes(tmp, s.ToByteArray());
File.AppendAllText(tmp, args.FileContents);
}
break;
case WriteType.AppendTop:
using(var s = dst.Get(dst.IOPath, _filesToDelete))
{
File.WriteAllText(tmp, args.FileContents);
AppendToTemp(s, tmp);
}
break;
default:
if(IsBase64(args.FileContents))
{
var data = Convert.FromBase64String(args.FileContents.Replace("Content-Type:BASE64", ""));
File.WriteAllBytes(tmp, data);
}
else
{
File.WriteAllText(tmp, args.FileContents);
}
break;
}
result = MoveTmpFileToDestination(dst, tmp, result);
}
else
{
if(File.Exists(dst.IOPath.Path))
{
var tmp = CreateTmpFile();
switch(args.WriteType)
{
case WriteType.AppendBottom:
File.AppendAllText(dst.IOPath.Path, args.FileContents);
result = ResultOk;
break;
case WriteType.AppendTop:
using(var s = dst.Get(dst.IOPath, _filesToDelete))
{
File.WriteAllText(tmp, args.FileContents);
AppendToTemp(s, tmp);
result = MoveTmpFileToDestination(dst, tmp, result);
RemoveTmpFile(tmp);
}
break;
default:
if(IsBase64(args.FileContents))
{
var data = Convert.FromBase64String(args.FileContents.Replace("Content-Type:BASE64", ""));
File.WriteAllBytes(tmp, data);
}
else
{
File.WriteAllText(tmp, args.FileContents);
}
result = MoveTmpFileToDestination(dst, tmp, result);
RemoveTmpFile(tmp);
break;
}
}
else
{
// we can write directly to the file
Dev2CRUDOperationTO newArgs = new Dev2CRUDOperationTO(true);
CreateEndPoint(dst, newArgs, true);
if(IsBase64(args.FileContents))
{
var data = Convert.FromBase64String(args.FileContents.Replace("Content-Type:BASE64", ""));
File.WriteAllBytes(dst.IOPath.Path, data);
}
else
{
File.WriteAllText(dst.IOPath.Path, args.FileContents);
}
}
}
}
finally
{
//.........这里部分代码省略.........
开发者ID:Robin--,项目名称:Warewolf,代码行数:101,代码来源:Dev2ActivityIOBroker.cs
示例18: CreateEndPoint
string CreateEndPoint(IActivityIOOperationsEndPoint dst, Dev2CRUDOperationTO args, bool createToFile)
{
var result = ResultOk;
// check the the dir strucutre exist
var activityIOPath = dst.IOPath;
var dirParts = MakeDirectoryParts(activityIOPath, dst.PathSeperator());
// check from lowest path part up
var deepestIndex = -1;
var startDepth = dirParts.Count - 1;
var pos = startDepth;
while(pos >= 0 && deepestIndex == -1)
{
var tmpPath = ActivityIOFactory.CreatePathFromString(dirParts[pos], activityIOPath.Username,
activityIOPath.Password, true,activityIOPath.PrivateKeyFile);
try
{
if(dst.ListDirectory(tmpPath) != null)
{
deepestIndex = pos;
}
}
// ReSharper disable EmptyGeneralCatchClause
catch(Exception)
// ReSharper restore EmptyGeneralCatchClause
{
//Note that we doing a recursive create should the directory not exists
}
finally
{
pos--;
}
}
// now create all the directories we need ;)
pos = deepestIndex + 1;
var ok = true;
var origPath = dst.IOPath;
while(pos <= startDepth && ok)
{
var toCreate = ActivityIOFactory.CreatePathFromString(dirParts[pos], dst.IOPath.Username,
dst.IOPath.Password, true, dst.IOPath.PrivateKeyFile);
dst.IOPath = toCreate;
ok = CreateDirectory(dst, args);
pos++;
}
dst.IOPath = origPath;
// dir create failed
if(!ok)
{
result = ResultBad;
}
else if(dst.PathIs(dst.IOPath) == enPathType.File && createToFile)
{
if(!CreateFile(dst, args))
{
result = ResultBad;
}
}
return result;
}
开发者ID:Robin--,项目名称:Warewolf,代码行数:68,代码来源:Dev2ActivityIOBroker.cs
示例19: ExecuteBroker
protected override string ExecuteBroker(IActivityOperationsBroker broker, IActivityIOOperationsEndPoint scrEndPoint, IActivityIOOperationsEndPoint dstEndPoint)
{
Dev2CRUDOperationTO opTo = new Dev2CRUDOperationTO(Overwrite);
var result = broker.Rename(scrEndPoint, dstEndPoint, opTo);
return result.Replace("Move", "Rename");
}
开发者ID:Robin--,项目名称:Warewolf,代码行数:6,代码来源:DsfPathRename.cs
示例20: CreateDirectory
bool CreateDirectory(IActivityIOOperationsEndPoint dst, Dev2CRUDOperationTO args)
{
var result = dst.CreateDirectory(dst.IOPath, args);
return result;
}
开发者ID:Robin--,项目名称:Warewolf,代码行数:5,代码来源:Dev2ActivityIOBroker.cs
注:本文中的Dev2.PathOperations.Dev2CRUDOperationTO类示例整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。 |
请发表评论