/// <summary> /// Creates the temporary assembly. /// </summary> /// <param name="codeReferencedAssembly">The referenced assembly.</param> /// <param name="usingNameSpaces">The using name spaces.</param> /// <param name="namespace">The namespace.</param> /// <param name="coreCode">The core code.</param> /// <returns>Beyova.TempAssembly.</returns> public TempAssembly CreateTempAssembly(string coreCode, HashSet <string> codeReferencedAssembly = null, IEnumerable <string> usingNameSpaces = null, string @namespace = null) { try { using (CodeDomProvider provider = new CSharpCodeProvider()) { @namespace = @namespace.SafeToString("Beyova.RuntimeCompile"); if (codeReferencedAssembly == null) { codeReferencedAssembly = new HashSet <string>(); } foreach (var one in GetDefaultAdditionalAssembly()) { codeReferencedAssembly.Add(one.Location); } var nameSpaces = GetDefaultUsingNamespaces(); if (usingNameSpaces.HasItem()) { nameSpaces.AddRange(usingNameSpaces); } // Prepare namespace done; StringBuilder builder = new StringBuilder(512); foreach (var one in nameSpaces) { builder.AppendLineWithFormat("using {0};", one); } builder.AppendLineWithFormat("namespace {0}", @namespace); //Namespace start builder.AppendLine("{"); builder.AppendLine(coreCode); //End of namespace builder.Append("}"); return(CreateTempAssembly(builder.ToString().AsArray(), codeReferencedAssembly: codeReferencedAssembly)); } } catch (Exception ex) { throw ex.Handle(new { codeReferencedAssembly, @namespace, coreCode }); } }
/// <summary> /// Returns a <see cref="System.String" /> that represents this instance. /// </summary> /// <returns> /// A <see cref="System.String" /> that represents this instance. /// </returns> public override string ToString() { StringBuilder builder = new StringBuilder(512); //Write destination builder.Append(Method); builder.Append(StringConstants.WhiteSpace); builder.Append(Uri.PathAndQuery); builder.Append(StringConstants.WhiteSpace); builder.Append(ProtocolVersion); builder.AppendLine(); builder.AppendLine(); //Write headers if (Headers.HasItem()) { foreach (string key in Headers.Keys) { builder.AppendLineWithFormat("{0}: {1}", key, Headers.Get(key)); } } builder.AppendLine(); if (Method.IsInString(HttpConstants.HttpMethod.Post, HttpConstants.HttpMethod.Put)) { builder.AppendLine(Body.ToUtf8String()); } builder.AppendLine(); return(builder.ToString()); }
/// <summary> /// APIs the trace log to string. /// </summary> /// <param name="builder">The builder.</param> /// <param name="log">The log.</param> /// <param name="level">The level.</param> /// <returns>System.String.</returns> private static void ApiTraceLogToString(StringBuilder builder, ApiTraceStep log, int level) { if (builder != null && log != null) { builder.AppendIndent(level); builder.AppendLineWithFormat("Entry: {0}", log.EntryStamp.ToFullDateTimeString()); builder.AppendIndent(level); builder.AppendLineWithFormat("Exit: {0}", log.ExitStamp.ToFullDateTimeString()); builder.AppendIndent(level); builder.AppendLineWithFormat("Exception Key: {0}", log.ExceptionKey); builder.AppendIndent(level); foreach (var one in log.InnerTraces) { builder.AppendLineWithFormat("Inner trace: "); ApiTraceLogToString(builder, one, level + 1); } } }
/// <summary> /// Fills the and terms. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="builder">The builder.</param> /// <param name="objects">The objects.</param> private static void FillSetTerms <T>(StringBuilder builder, IEnumerable <T> objects) where T : MemberInfo { if (objects.HasItem()) { foreach (var one in objects) { builder.AppendLineWithFormat("destination.{0} = source.{0};", one.Name); } } }
/// <summary> /// APIs the event log to string. /// </summary> /// <param name="log">The log.</param> /// <returns>System.String.</returns> public static string ApiEventLogToString(this ApiEventLog log) { var builder = new StringBuilder(); if (log != null) { builder.AppendLineWithFormat("{0}: {1}", log.CreatedStamp.ToFullDateTimeString(), log.ApiFullName); builder.AppendLine(log.ToJson()); } return builder.ToString(); }
/// <summary> /// APIs the trace log to string. /// </summary> /// <param name="log">The log.</param> /// <returns>System.String.</returns> public static string ApiTraceLogToString(this ApiTraceLog log) { StringBuilder builder = new StringBuilder(); if (log != null) { builder.AppendLineWithFormat("Trace ID: {0}", log.TraceId); ApiTraceLogToString(builder, log, 0); } return(builder.ToString()); }
/// <summary> /// APIs the message to string. /// </summary> /// <param name="message">The message.</param> /// <returns></returns> public static string ApiMessageToString(this ApiMessage message) { var builder = new StringBuilder(512); if (message != null) { builder.AppendLineWithFormat("{0}: {1}", message.CreatedStamp.ToFullDateTimeString(), message.Category); builder.AppendLine(message.Message); } return(builder.ToString()); }
/// <summary> /// Writes the line. /// </summary> /// <param name="format">The format.</param> /// <param name="args">The arguments.</param> public void WriteLine(string format, params object[] args) { format = format == null ? string.Empty : format; if (args.HasItem()) { builder.AppendLineWithFormat(format, args); } else { builder.AppendLine(format); } }
/// <summary> /// APIs the trace log to string. /// </summary> /// <param name="log">The log.</param> /// <returns>System.String.</returns> public static string ApiTraceLogToString(this ApiTraceLog log) { StringBuilder builder = new StringBuilder(); if (log != null) { builder.AppendLineWithFormat("Trace ID: {0}", log.TraceId); ApiTraceLogToString(builder, log, 0); } return builder.ToString(); }
/// <summary> /// Writes the constructor. /// </summary> /// <param name="builder">The builder.</param> /// <param name="className">Name of the class.</param> protected override void WriteConstructor(StringBuilder builder, string className) { if (builder != null) { builder.AppendIndent(2); builder.AppendLineWithFormat("public {0}({1} instance, {2} injectionDelegates):base(instance, injectionDelegates)", className, typeof(T).ToCodeLook(), typeof(MethodInjectionDelegates).ToCodeLook()); builder.AppendIndent(2); builder.AppendLine("{"); builder.AppendIndent(2); builder.AppendLine("}"); builder.AppendLine(); } }
/// <summary> /// Writes the constructor. /// </summary> /// <param name="builder">The builder.</param> /// <param name="className">Name of the class.</param> protected virtual void WriteConstructor(StringBuilder builder, string className) { if (builder != null) { builder.AppendIndent(2); builder.AppendLineWithFormat("public {0}() : base()", className); builder.AppendIndent(2); builder.AppendLine("{"); builder.AppendIndent(2); builder.AppendLine("}"); builder.AppendLine(); } }
/// <summary> /// Creates the member clone class code. /// </summary> /// <param name="type">The type.</param> /// <param name="typeName">Name of the type.</param> /// <returns></returns> private static string CreateMemberCloneClassCode(Type type, string typeName) { if (type != null) { var getProperties = type.GetInstanceFullyPublicAccessiableProperties(); var getFields = type.GetInstanceFullyPublicAccessiableFields(); StringBuilder builder = new StringBuilder(4096 + getProperties.Length * 256 + getFields.Length * 256); var memberCloneType = typeof(IObjectMemberClone <>); builder.AppendLineWithFormat("public class {0}: {1}", typeName, memberCloneType.MakeGenericType(type).ToCodeLook()); builder.AppendBeginBrace(); // Constructor builder.AppendLineWithFormat("public {0}()", typeName); builder.AppendLine("{"); builder.AppendLine("}"); builder.AppendLineWithFormat("public void ShadowClone({0} source, {0} destination)", type.ToCodeLook()); builder.AppendBeginBrace(); builder.AppendLine("if(source != null && destination != null)"); builder.AppendBeginBrace(); FillSetTerms(builder, getProperties); FillSetTerms(builder, getFields); builder.AppendEndBrace(); builder.AppendEndBrace(); // End of ObjectMemberClone builder.AppendEndBrace(); return(builder.ToString()); } return(string.Empty); }
/// <summary> /// Generates the code. /// </summary> /// <param name="builder">The builder.</param> /// <param name="namespace">The namespace.</param> /// <param name="targetClassName">Name of the target class.</param> /// <param name="inheritedClass">The inherited class.</param> /// <param name="selfClass">The self class.</param> /// <param name="methodsToBuild">The methods to build.</param> /// <returns></returns> protected void GenerateCode(StringBuilder builder, string @namespace, string targetClassName, Type inheritedClass, Type selfClass, List <MethodInfo> methodsToBuild) { try { methodsToBuild.CheckNullObject(nameof(methodsToBuild)); //Start to build code WriteFileInfo(builder); WriteNamespaces(builder); builder.AppendLine(); // write namespace builder.AppendLineWithFormat("namespace {0}", Namespace); builder.AppendLine("{"); // write class declaration builder.AppendIndent(1); builder.Append(GenerateClassDeclarationPart(ClassName, selfClass.GetInterfaces())); builder.AppendIndent(1); builder.AppendLine("{"); // write constructor WriteConstructor(builder, ClassName); foreach (var one in methodsToBuild) { GenerateCoreMethod(builder, one); } // End of class builder.AppendIndent(1); builder.AppendLine("}"); // End of namespace builder.AppendLine("}"); builder.AppendLine(); //End of code build } catch (Exception ex) { throw ex.Handle(); } }
/// <summary> /// Writes the HTML document. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="packageDocumentDelegate">The package document delegate.</param> /// <param name="container">The container.</param> /// <param name="types">The types.</param> /// <returns>T.</returns> private T WriteHtmlDocumentByType <T>(Action <T, string, byte[]> packageDocumentDelegate, T container, params KeyValuePair <Type, IApiContractOptions>[] types) { var zipFiles = new Dictionary <string, byte[]>(); HashSet <Type> enumSets = new HashSet <Type>(); //HashSet<string> apiOperationHash = new HashSet<string>(); //Service List StringBuilder builder = new StringBuilder(types.Length * 1024); foreach (var one in types) { if (one.Value != null) { WriteApiServiceHtmlDocumentPanel(builder, one.Key, one.Value); } } packageDocumentDelegate?.Invoke(container, "index.html", Encoding.UTF8.GetBytes(WriteAsEntireHtmlFile(builder.ToString(), "API Documentation"))); //Api Files. foreach (var one in types) { builder = new StringBuilder(1024); builder.AppendLineWithFormat("<div style=\"display:block; background-color:#000000; color: #eeeeee\"><h1>{0} ({1})</h1></div>", one.Key.Name, one.Key.Namespace); WriteApiHtmlDocument(builder, one.Key, one.Value, one.Key.GetCustomAttribute <TokenRequiredAttribute>(true), enumSets); packageDocumentDelegate?.Invoke(container, one.Key.FullName + ".html", Encoding.UTF8.GetBytes(WriteAsEntireHtmlFile(builder.ToString(), "API - " + one.Key.Name))); } if (packageDocumentDelegate != null) { foreach (var one in enumSets) { packageDocumentDelegate(container, one.FullName + ".html", Encoding.UTF8.GetBytes(GetEnumValueTable(one))); } } return(container); }
/// <summary> /// APIs the trace log to string. /// </summary> /// <param name="log">The log.</param> /// <param name="level">The level.</param> /// <returns>System.String.</returns> private static string ApiTraceLogToString(ApiTraceLogPiece log, int level) { StringBuilder builder = new StringBuilder(); if (log != null) { builder.AppendIndent(' ', 2 * (level + 1)); builder.AppendLineWithFormat("Entry: {0}", log.EntryStamp.ToFullDateTimeString()); builder.AppendIndent(' ', 2 * (level + 1)); builder.AppendLineWithFormat("Exit: {0}", log.ExitStamp.ToFullDateTimeString()); builder.AppendIndent(' ', 2 * (level + 1)); builder.AppendLineWithFormat("Parameters: {0}", log.MethodParameters.ToJson()); builder.AppendIndent(' ', 2 * (level + 1)); builder.AppendLineWithFormat("Exception: {0}", log.Exception == null ? "NA" : log.Exception.ToJson()); builder.AppendIndent(' ', 2 * (level + 1)); foreach (var one in log.InnerTraces) { builder.AppendLineWithFormat("Inner trace: {0}", ApiTraceLogToString(one, level + 1)); } } return builder.ToString(); }
/// <summary> /// Generates the core method. /// </summary> /// <param name="builder">The builder.</param> /// <param name="methodInfo">The method information.</param> protected void GenerateCoreMethod(StringBuilder builder, MethodInfo methodInfo) { const string methodCallInfoVariableName = "methodCallInfo"; var currentIndent = 2; if (builder != null && methodInfo != null) { //Declaration builder.AppendIndent(currentIndent); builder.AppendLineWithFormat("public virtual {0}", methodInfo.ToDeclarationCodeLook()); builder.AppendBeginBrace(ref currentIndent); //Invoke body #region method body GenerateMethodCallInfoDeclarition(builder, methodInfo, currentIndent, methodCallInfoVariableName); builder.AppendIndent(currentIndent); builder.AppendLine("try"); #region try builder.AppendBeginBrace(ref currentIndent); //Injection of before event GenerateMethodInjectionInvoke(builder, "MethodInvokingEvent", methodCallInfoVariableName, currentIndent); //Core builder.AppendIndent(currentIndent); if (methodInfo.ReturnParameter.ParameterType != typeof(void)) { builder.Append("return "); } builder.AppendLineWithFormat("_instance.{0};", methodInfo.ToInvokeCodeLook(methodInfo.GetGenericArguments(), methodInfo.GetParameters())); builder.AppendEndBrace(ref currentIndent); #endregion try builder.AppendIndent(currentIndent); builder.AppendLine("catch (Exception ex)"); #region catch builder.AppendBeginBrace(ref currentIndent); builder.AppendIndent(currentIndent); builder.AppendLineWithFormat("{0}.Exception = ex;", methodCallInfoVariableName); // Injection of exception handle GenerateMethodInjectionInvoke(builder, "ExceptionDelegate", methodCallInfoVariableName, currentIndent, string.Format("throw ex.Handle((from item in {0}.InArgs where {0}.SerializableArgNames.Contains(item.Key) select item).ToDictionary());", methodCallInfoVariableName), callAfterInjection: methodInfo.ReturnType.IsVoid(false) ? string.Empty : string.Format("return default({0});", methodInfo.ReturnType.ToCodeLook())); builder.AppendEndBrace(ref currentIndent); #endregion catch builder.AppendIndent(currentIndent); builder.AppendLine("finally"); #region finally builder.AppendBeginBrace(ref currentIndent); //Injection of after event GenerateMethodInjectionInvoke(builder, "MethodInvokedEvent", methodCallInfoVariableName, currentIndent); builder.AppendEndBrace(ref currentIndent); #endregion finally //Body end #endregion method body builder.AppendEndBrace(ref currentIndent); builder.AppendLine(); } }
/// <summary> /// Formats to string. /// </summary> /// <param name="stringBuilder">The string builder.</param> /// <param name="exception">The exception.</param> /// <param name="level">The level.</param> private static void FormatToString(StringBuilder stringBuilder, Exception exception, int level) { if (stringBuilder != null && exception != null) { BaseException baseException = exception as BaseException; stringBuilder.AppendLineWithFormat(level, "Exception Type: {0}", exception.GetType().ToString()); if (baseException != null) { stringBuilder.AppendLineWithFormat(level, "Exception Code: {0}({1})", baseException.Code.ToString(), (int)baseException.Code); } stringBuilder.AppendLineWithFormat(level, "Exception Message: {0}", exception.Message); stringBuilder.AppendLineWithFormat(level, "Source: {0}", exception.Source); stringBuilder.AppendLineWithFormat(level, "Site: {0}", exception.TargetSite); stringBuilder.AppendLineWithFormat(level, "StackTrace: {0}", exception.StackTrace); if (baseException != null) { stringBuilder.AppendLineWithFormat(level, "Exception Code: {0}({1})", baseException.Code.ToString(), (int)baseException.Code); stringBuilder.AppendLineWithFormat(level, "Operator Credential: {0}", baseException.OperatorCredential.ToJson()); stringBuilder.AppendLineWithFormat(level, "Scene: {0}", baseException.Scene.ToJson()); stringBuilder.AppendLineWithFormat(level, "Hint: {0}", baseException.Hint.ToJson()); } stringBuilder.AppendLineWithFormat(level, "Data Reference: {0}", GenerateDataString(baseException?.ReferenceData?.ToJson())); if (exception.InnerException != null) { level++; stringBuilder.AppendLine(level, "-------------------- Inner Exception --------------------"); FormatToString(stringBuilder, exception.InnerException, level); } } }
/// <summary> /// Creates the dynamic assembly. /// </summary> /// <param name="provider">The provider.</param> /// <param name="referencedAssemblies">The referenced assemblies.</param> /// <param name="namespace">The namespace.</param> /// <param name="usingNameSpaces">The using nameSpaces.</param> /// <param name="classCodesToCompile">The class codes to compile.</param> /// <returns>Assembly.</returns> /// <exception cref="OperationFailureException">CompileAssemblyFromSource;null</exception> public SandboxAssembly CreateDynamicAssembly(CodeDomProvider provider, List<string> referencedAssemblies, string @namespace, IEnumerable<string> usingNameSpaces, string classCodesToCompile) { try { provider.CheckNullObject("provider"); classCodesToCompile.CheckEmptyString("classCodesToCompile"); @namespace = @namespace.SafeToString("Beyova.DynamicCompile.Sandbox"); var objCompilerParameters = new CompilerParameters { GenerateExecutable = false, GenerateInMemory = true }; // Prepare references. var references = GetCommonAssemblyNameList(); if (referencedAssemblies.HasItem()) { references.AddRange(referencedAssemblies); } objCompilerParameters.ReferencedAssemblies.AddRange(references.ToArray()); // Prepare references done. // Prepare namespace var nameSpaces = GetCommonNamespaces(); if (usingNameSpaces.HasItem()) { nameSpaces.AddRange(usingNameSpaces); } // Prepare namespace done; StringBuilder builder = new StringBuilder(512); foreach (var one in nameSpaces) { builder.AppendLineWithFormat("using {0};", one); } builder.AppendLineWithFormat("namespace {0}", @namespace); //Namespace start builder.AppendLine("{"); builder.AppendLine(classCodesToCompile); //End of namespace builder.Append("}"); var compilerResult = provider.CompileAssemblyFromSource(objCompilerParameters, classCodesToCompile); if (compilerResult.Errors.HasErrors) { List<dynamic> errors = new List<dynamic>(); foreach (CompilerError one in compilerResult.Errors) { errors.Add(new { one.ErrorText, one.ErrorNumber, one.Line }); } throw new OperationFailureException("CompileAssemblyFromSource", null, errors); } return new SandboxAssembly(compilerResult.CompiledAssembly, @namespace); } catch (Exception ex) { throw ex.Handle("CreateDynamicAssembly"); } }
/// <summary> /// Writes the API HTML document. /// </summary> /// <param name="builder">The builder.</param> /// <param name="apiServiceType">Type of the API service.</param> /// <param name="apiContractOptions">The API contract options.</param> /// <param name="classTokenRequiredAttribute">The class token required attribute.</param> /// <param name="enumSets">The enum sets.</param> protected void WriteApiHtmlDocument(StringBuilder builder, Type apiServiceType, IApiContractOptions apiContractOptions, TokenRequiredAttribute classTokenRequiredAttribute, HashSet <Type> enumSets) { if (builder != null && apiServiceType != null && apiContractOptions != null) { foreach (MethodInfo one in apiServiceType.GetMethodInfoWithinAttribute <ApiOperationAttribute>(true, BindingFlags.Instance | BindingFlags.Public)) { // Considering in interface, can NOT tell is async or not, check return type is Task or Task<T>. bool isAsync = one.IsAsync() || one.ReturnType.IsTask(); var apiOperationAttribute = one.GetCustomAttribute <ApiOperationAttribute>(true); if (apiOperationAttribute != null) { StringBuilder bodyBuilder = new StringBuilder(4096); #region Entity Synchronization Status var entitySynchronizationAttribute = one.GetCustomAttribute <EntitySynchronizationModeAttribute>(true); if (entitySynchronizationAttribute != null && !EntitySynchronizationModeAttribute.IsReturnTypeMatched(one.ReturnType)) { entitySynchronizationAttribute = null; } #endregion Entity Synchronization Status //Original declaration bodyBuilder.Append("<h3>.NET Declaration</h3>"); bodyBuilder.AppendFormat(isAsync ? "<div><span style=\"color:red;font-weight:bold;\" title=\"Async\">[A] </span> {0}</div>" : "<div>{0}</div>", one.ToDeclarationCodeLook().ToHtmlEncodedText()); bodyBuilder.Append("<hr />"); //Try append description var apiDescriptionAttributes = one.GetCustomAttributes <ApiDescriptionAttribute>(true); if (apiDescriptionAttributes != null && apiDescriptionAttributes.Any()) { foreach (var description in apiDescriptionAttributes) { if (!string.IsNullOrWhiteSpace(description.Description)) { bodyBuilder.AppendFormat("<div>{0}</div>", description.Description.ToHtmlEncodedText()); } } } // Customized headers var apiCustomizedHeaderAttributes = one.GetCustomAttributes <ApiHeaderAttribute>(true); if (apiCustomizedHeaderAttributes.HasItem()) { bodyBuilder.Append("<h3>Customized headers</h3><hr />"); bodyBuilder.Append("<ul>"); foreach (var item in apiCustomizedHeaderAttributes) { bodyBuilder.AppendFormat(customHeaderFormat, item.HeaderKey); } bodyBuilder.Append("</ul>"); } var obsolete = one.GetCustomAttribute <ObsoleteAttribute>(true); if (obsolete != null) { bodyBuilder.AppendFormat("<div style=\"color:red;\"> Obsoleted: {0}</div>", obsolete.Message.ToHtmlEncodedText()); } bodyBuilder.Append("<div>Following sample shows how to use via REST API.</div>"); #region Request bodyBuilder.Append("<h3>Request</h3><hr />"); bodyBuilder.Append("<url>"); if (string.IsNullOrWhiteSpace(apiContractOptions.Realm)) { bodyBuilder.AppendFormat("{0} /api/{1}/{2}/", apiOperationAttribute.HttpMethod, apiContractOptions.Version, apiOperationAttribute.ResourceName); } else { bodyBuilder.AppendFormat("{0} /{1}/api/{2}/{3}/", apiContractOptions.Realm, apiOperationAttribute.HttpMethod, apiContractOptions.Version, apiOperationAttribute.ResourceName); } if (!string.IsNullOrWhiteSpace(apiOperationAttribute.Action)) { bodyBuilder.AppendFormat("{0}/", apiOperationAttribute.Action); } var parameters = one.GetParameters(); var parameterIsHandled = false; if (parameters.Length == 0) { parameterIsHandled = true; } else if (parameters.Length == 1 && (apiOperationAttribute.HttpMethod.Equals(HttpConstants.HttpMethod.Get, StringComparison.OrdinalIgnoreCase) || apiOperationAttribute.HttpMethod.Equals(HttpConstants.HttpMethod.Delete, StringComparison.OrdinalIgnoreCase))) { if (parameters[0].ParameterType == typeof(string) || parameters[0].ParameterType.IsValueType) { bodyBuilder.AppendFormat("<span style=\"font-style:italic; font-weight:bold;color:#CC0000;\" title=\"Sample value for {0}\">", parameters[0].Name); FillSampleValue(bodyBuilder, parameters[0].ParameterType, enumSets, 0, fieldName: parameters[0].Name, ignoreQuote: true); bodyBuilder.Append("</span>"); parameterIsHandled = true; } } else if (parameters.Length > 1 && (apiOperationAttribute.HttpMethod.Equals(HttpConstants.HttpMethod.Get, StringComparison.OrdinalIgnoreCase) || apiOperationAttribute.HttpMethod.Equals(HttpConstants.HttpMethod.Delete, StringComparison.OrdinalIgnoreCase))) { bodyBuilder.Append("?"); foreach (var parameterItem in parameters) { bodyBuilder.AppendFormat("{0}=", parameterItem.Name); FillSampleValue(bodyBuilder, parameterItem.ParameterType, enumSets, 0, parameterItem.Name, true, true); bodyBuilder.Append("&"); } bodyBuilder.RemoveLastIfMatch('&', true); parameterIsHandled = true; } bodyBuilder.Append("</url>"); var currentTokenRequiredAttribute = one.GetCustomAttribute <TokenRequiredAttribute>(true) ?? classTokenRequiredAttribute; if (currentTokenRequiredAttribute != null && currentTokenRequiredAttribute.TokenRequired) { bodyBuilder.AppendLineWithFormat(requestHeaderFormat, TokenKey, "[YourTokenValue]"); } if (entitySynchronizationAttribute != null) { bodyBuilder.AppendLineWithFormat(requestHeaderFormat, entitySynchronizationAttribute.IfModifiedSinceKey, DateTime.UtcNow.AddDays(-2).ToFullDateTimeString()); } bodyBuilder.Append("<pre class=\"CodeContainer\" style=\"font-family: monospace;font-size:14px;\">"); if (!parameterIsHandled) { if (parameters.Length == 1) { FillSampleValue(bodyBuilder, parameters[0].ParameterType, enumSets, 0, fieldName: parameters[0].Name, followingProperty: false); } else { builder.AppendFormat(objectBrace, "{"); foreach (var parameterItem in parameters) { FillProperty(bodyBuilder, parameterItem.Name, parameterItem.ParameterType); AppendColon(bodyBuilder); FillSampleValue(bodyBuilder, parameterItem.ParameterType, enumSets, 1, followingProperty: true); AppendComma(bodyBuilder); } RemoveUnnecessaryColon(bodyBuilder); bodyBuilder.AppendFormat(objectBrace, "}"); } } bodyBuilder.Append("</pre>"); #endregion Request #region Response bodyBuilder.Append("<h3>Response</h3><hr />"); bodyBuilder.AppendLineWithFormat(requestHeaderFormat, HttpConstants.HttpHeader.ContentType, apiOperationAttribute.ContentType.SafeToString(HttpConstants.ContentType.Json)); if (entitySynchronizationAttribute != null) { bodyBuilder.AppendLineWithFormat(requestHeaderFormat, entitySynchronizationAttribute.LastModifiedKey, DateTime.UtcNow.ToFullDateTimeString()); } bodyBuilder.Append("<pre class=\"CodeContainer\" style=\"font-family: monospace;font-size:14px;\">"); var returnType = one.ReturnType; if (isAsync) { returnType = returnType.GetTaskUnderlyingType() ?? returnType; } if (returnType.IsVoid() ?? true) { bodyBuilder.Append("<span style=\"font-style:italic; font-weight: bold; color: #999999;\">void</span>"); } else { FillSampleValue(bodyBuilder, returnType, enumSets, 0); } bodyBuilder.Append("</pre>"); #endregion Response #region Http Status // Http Status bodyBuilder.Append("<h3>Http Status & Exceptions</h3><hr />"); bodyBuilder.Append("<ul>"); if (one.ReturnType.IsVoid() ?? false) { bodyBuilder.AppendFormat(httpStatusFormat, (int)HttpStatusCode.NoContent, HttpStatusCode.NoContent.ToString(), "If no error or exception.", "green"); } else { bodyBuilder.AppendFormat(httpStatusFormat, (int)HttpStatusCode.OK, HttpStatusCode.OK.ToString(), "If no error or exception.", "green"); if (entitySynchronizationAttribute != null) { bodyBuilder.AppendFormat(httpStatusFormat, (int)HttpStatusCode.NotModified, HttpStatusCode.NotModified.ToString(), "If no modified since specific time stamp", "green"); } } bodyBuilder.AppendFormat(httpStatusFormat, (int)HttpStatusCode.BadRequest, HttpStatusCode.BadRequest.ToString(), "If input value or/and format is invalid.", "red"); if (currentTokenRequiredAttribute != null && currentTokenRequiredAttribute.TokenRequired) { bodyBuilder.AppendFormat(httpStatusFormat, (int)HttpStatusCode.Unauthorized, HttpStatusCode.Unauthorized.ToString(), "If token is invalid or not given.", "orange"); } bodyBuilder.AppendFormat(httpStatusFormat, (int)HttpStatusCode.Forbidden, HttpStatusCode.Forbidden.ToString(), "If action is forbidden.", "orange"); bodyBuilder.AppendFormat(httpStatusFormat, (int)HttpStatusCode.NotFound, HttpStatusCode.NotFound.ToString(), "If resource is not found.", "orange"); bodyBuilder.AppendFormat(httpStatusFormat, (int)HttpStatusCode.Conflict, HttpStatusCode.Conflict.ToString(), "If data conflicts.", "orange"); bodyBuilder.AppendFormat(httpStatusFormat, (int)HttpStatusCode.InternalServerError, HttpStatusCode.InternalServerError.ToString(), "If server feature is not working or has defect(s).", "red"); bodyBuilder.AppendFormat(httpStatusFormat, (int)HttpStatusCode.NotImplemented, HttpStatusCode.NotImplemented.ToString(), "If server feature is not implemented yet.", "red"); bodyBuilder.Append("</ul>"); #endregion Http Status builder.AppendFormat(panel, one.Name, bodyBuilder.ToString(), one.Name, "#"); } } } }
/// <summary> /// Fills the sample value. /// </summary> /// <param name="builder">The builder.</param> /// <param name="type">The type.</param> /// <param name="enumSets">The enum sets.</param> /// <param name="indent">The indent.</param> /// <param name="fieldName">Name of the field.</param> /// <param name="ignoreQuote">if set to <c>true</c> [ignore quote].</param> /// <param name="followingProperty">if set to <c>true</c> [following property].</param> /// <param name="objectChain">The object chain.</param> public static void FillSampleValue(StringBuilder builder, Type type, HashSet <Type> enumSets, int indent, string fieldName = null, bool ignoreQuote = false, bool followingProperty = false, List <Type> objectChain = null) { if (builder != null && type != null && enumSets != null) { if (objectChain == null) { objectChain = new List <Type>(); } else if (OverThreshold(objectChain, type)) { builder.Append("<span class=\"Null\" style=\"color: #0000FF;font-style:italic; font-weight:bold;\">null</span>"); return; } if (type.IsNullable()) { FillSampleValue(builder, type.GetNullableType(), enumSets, indent, fieldName, ignoreQuote, followingProperty, AppendChain(objectChain, type)); return; } if (type.IsEnum) { var firstEnum = Enum.GetValues(type).FirstOrDefault <object>(); enumSets.Add(type); if (!followingProperty) { builder.AppendIndent(indent); } builder.AppendFormat(enumFormat, (firstEnum == null) ? string.Empty : ((int)firstEnum).ToString(), type.FullName); } else if (type == typeof(JObject)) { builder.Append("<span class=\"JSON\" style=\"font-style:italic; font-weight:bold;color:#3abd4d;\" title=\"Any JObject\">{ Any JObject }</span>"); } else if (type == typeof(JArray)) { builder.Append("<span class=\"JSON\" style=\"font-style:italic; font-weight:bold;color:#3abd4d;\" title=\"Any JArray\">[ Any JArray ]</span>"); } else if (type == typeof(JToken)) { builder.Append("<span class=\"JSON\" style=\"font-style:italic; font-weight:bold;color:#3abd4d;\" title=\"Any JToken\">{ Any JSON }</span>"); } else if (type.IsDictionary()) { // If dictionary type is inherited from dictionary (native), the generic might be totally different. if (type.BaseType.IsDictionary()) { FillSampleValue(builder, type.BaseType, enumSets, indent, fieldName, ignoreQuote, followingProperty, objectChain); } else { var keyType = type.GetGenericArguments()[0]; var valueType = type.GetGenericArguments()[1]; if (!followingProperty) { builder.AppendIndent(indent); } builder.AppendLineWithFormat(objectBrace, "{"); FillSampleValue(builder, keyType, enumSets, indent + 1, fieldName: "Key", followingProperty: false, objectChain: AppendChain(objectChain, type)); AppendColon(builder); FillSampleValue(builder, valueType, enumSets, indent + 1, fieldName: "Value", followingProperty: true, objectChain: AppendChain(objectChain, type)); builder.AppendLine(); builder.AppendIndent(indent); builder.AppendLineWithFormat(objectBrace, "}"); } } else if (type.IsCollection()) { var subType = type.GetGenericArguments().FirstOrDefault(); if (!followingProperty) { builder.AppendIndent(indent); } builder.AppendLineWithFormat(arrayBrace, "["); if (!OverThreshold(objectChain, subType)) { FillSampleValue(builder, subType, enumSets, indent + 1, "Item1", followingProperty: false, objectChain: AppendChain(objectChain, type)); builder.AppendIndent(indent + 1); AppendComma(builder); FillSampleValue(builder, subType, enumSets, indent + 1, "Item2", followingProperty: false, objectChain: AppendChain(objectChain, type)); builder.AppendLine(); } builder.AppendIndent(indent); builder.AppendLineWithFormat(arrayBrace, "]"); } else { switch (type.FullName) { case "System.Boolean": if (!followingProperty) { builder.AppendIndent(indent); } builder.Append("<span class=\"Boolean\">true</span>"); break; case "System.String": if (!followingProperty) { builder.AppendIndent(indent); } fieldName = string.IsNullOrWhiteSpace(fieldName) ? "AnyString" : fieldName + "String"; builder.AppendFormat(ignoreQuote ? "{0}" : "\"{0}\"", ignoreQuote ? fieldName : fieldName.SplitSentenceByUpperCases()); break; case "System.Guid": if (!followingProperty) { builder.AppendIndent(indent); } builder.AppendFormat(ignoreQuote ? "{0}" : "\"{0}\"", Guid.NewGuid()); break; case "System.UInt16": case "System.UInt32": case "System.UInt64": case "System.Int16": case "System.Int32": case "System.Int64": if (!followingProperty) { builder.AppendIndent(indent); } builder.AppendFormat("<span class=\"Number\" style=\"color: #AA00AA;\">123</span>"); break; case "System.Single": case "System.Double": case "System.Decimal": if (!followingProperty) { builder.AppendIndent(indent); } builder.AppendFormat("<span class=\"Number\" style=\"color: #AA00AA;\">1.5</span>"); break; case "System.DateTime": if (!followingProperty) { builder.AppendIndent(indent); } builder.AppendFormat(ignoreQuote ? "{0}" : "\"{0}\"", ignoreQuote ? DateTime.Now.ToFullDateTimeTzString().ToUrlPathEncodedText() : DateTime.Now.ToFullDateTimeTzString()); break; case "System.TimeSpan": if (!followingProperty) { builder.AppendIndent(indent); } builder.AppendFormat(ignoreQuote ? "{0}" : "\"{0}\"", ignoreQuote ? new TimeSpan(1234).ToString().ToUrlPathEncodedText() : new TimeSpan(1234).ToString()); break; default: if (!followingProperty) { builder.AppendIndent(indent); } builder.AppendLineWithFormat(objectBrace, "{"); foreach (var one in type.GetActualAffectedProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty).Where((x) => { return(x.GetCustomAttribute <JsonIgnoreAttribute>() == null); })) { var valueType = one.PropertyType; builder.AppendIndent(indent + 1); FillProperty(builder, one.Name, one.PropertyType); AppendColon(builder); FillSampleValue(builder, valueType, enumSets, indent + 1, one.Name, followingProperty: true, objectChain: AppendChain(objectChain, type)); AppendComma(builder); } foreach (var one in type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetField)) { var valueType = one.FieldType; builder.AppendIndent(indent + 1); FillProperty(builder, one.Name, one.FieldType); AppendColon(builder); FillSampleValue(builder, valueType, enumSets, 0, one.Name, followingProperty: true, objectChain: AppendChain(objectChain, type)); AppendComma(builder); } RemoveUnnecessaryColon(builder); builder.AppendIndent(indent); builder.AppendLineWithFormat(objectBrace, "}"); break; } } } }
/// <summary> /// Creates the temporary assembly. /// </summary> /// <param name="codeReferencedAssembly">The referenced assembly.</param> /// <param name="usingNameSpaces">The using name spaces.</param> /// <param name="namespace">The namespace.</param> /// <param name="coreCode">The core code.</param> /// <returns>Beyova.TempAssembly.</returns> public TempAssembly CreateTempAssembly(string coreCode, HashSet<string> codeReferencedAssembly = null, IEnumerable<string> usingNameSpaces = null, string @namespace = null) { try { provider.CheckNullObject("provider"); @namespace = @namespace.SafeToString("Beyova.RuntimeCompile"); if (codeReferencedAssembly == null) { codeReferencedAssembly = new HashSet<string>(); } foreach (var one in GetDefaultAdditionalAssembly()) { codeReferencedAssembly.Add(one.Location); } var nameSpaces = GetDefaultUsingNamespaces(); if (usingNameSpaces.HasItem()) { nameSpaces.AddRange(usingNameSpaces); } // Prepare namespace done; StringBuilder builder = new StringBuilder(512); foreach (var one in nameSpaces) { builder.AppendLineWithFormat("using {0};", one); } builder.AppendLineWithFormat("namespace {0}", @namespace); //Namespace start builder.AppendLine("{"); builder.AppendLine(coreCode); //End of namespace builder.Append("}"); return CreateTempAssembly(builder.ToString().AsArray(), codeReferencedAssembly: codeReferencedAssembly); } catch (Exception ex) { throw ex.Handle(new { codeReferencedAssembly, @namespace, coreCode }); } }
/// <summary> /// APIs the trace log to string. /// </summary> /// <param name="builder">The builder.</param> /// <param name="log">The log.</param> /// <param name="level">The level.</param> /// <returns>System.String.</returns> private static void ApiTraceLogToString(StringBuilder builder, ApiTraceLogPiece log, int level) { if (builder != null && log != null) { builder.AppendIndent(' ', 2 * (level + 1)); builder.AppendLineWithFormat("Entry: {0}", log.EntryStamp.ToFullDateTimeString()); builder.AppendIndent(' ', 2 * (level + 1)); builder.AppendLineWithFormat("Exit: {0}", log.ExitStamp.ToFullDateTimeString()); builder.AppendIndent(' ', 2 * (level + 1)); builder.AppendLineWithFormat("Exception Key: {0}", log.ExceptionKey); builder.AppendIndent(' ', 2 * (level + 1)); foreach (var one in log.InnerTraces) { builder.AppendLineWithFormat("Inner trace: "); ApiTraceLogToString(builder, one, level + 1); } } }