public Task ProcessRequestAsync(XmlRpcContext context) { var request = context.HttpContext.Request; if (!request.Method.Equals( HttpVerbs.Post.ToString(), StringComparison.OrdinalIgnoreCase)) { throw new InvalidOperationException(); } var requestInfo = XmlRpcRequestParser.GetRequestInformation( request.Body); if (string.IsNullOrWhiteSpace(requestInfo.MethodName)) { throw new InvalidOperationException( "XmlRpc call does not contain a method."); } var methodInfo = XmlRpcRequestParser.GetRequestedMethod(requestInfo, context.Services); if (methodInfo == null) { throw new InvalidOperationException( string.Concat( "There was no implementation of IXmlRpcService ", "found, that containins a method decorated with ", " the XmlRpcMethodAttribute value'", requestInfo.MethodName, "'.")); } var result = XmlRpcRequestParser.ExecuteRequestedMethod( requestInfo, methodInfo, context); var response = context.HttpContext.Response; response.ContentType = "text/xml"; var settings = new XmlWriterSettings { OmitXmlDeclaration = false, Encoding = new UTF8Encoding(false), // Get rid of BOM Indent = true, }; using (var writer = XmlWriter.Create(response.Body, settings)) { if (methodInfo.ResponseType == XmlRpcResponseType.Wrapped) { WriteWrappedResponse(writer, result); return(Task.CompletedTask); } WriteRawResponse(writer, result); return(Task.CompletedTask); } }
public async Task ProcessRequestAsync(XmlRpcContext context) { if (!context.Options.GenerateSummary) { // Not found context.HttpContext.Response.StatusCode = 404; return; } var title = string.Concat("XML-RPC Methods for ", string.Join(",", context.Services.Select(s => s.FullName))); var methods = XmlRpcRequestParser.GetMethods(context.Services); using (var ms = new MemoryStream()) { var writer = XmlWriter.Create(ms, new XmlWriterSettings { OmitXmlDeclaration = true, Encoding = Encoding.UTF8 }); writer.WriteStartDocument(); { writer.WriteDocType("html", "PUBLIC", "-//W3C//DTD XHTML 1.1//EN", "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"); writer.WriteStartElement("html"); { writer.WriteStartElement("head"); { //Version info writer.WriteComment($"AspNetCore.XmlRpc {Assembly.GetExecutingAssembly().GetName().Version}"); writer.WriteElementString("title", title); // <meta name="robots" content="noindex" /> writer.WriteStartElement("meta"); { writer.WriteAttributeString("name", "robots"); writer.WriteAttributeString("content", "noindex"); } writer.WriteEndElement(); //Style writer.WriteStartElement("style"); { writer.WriteAttributeString("type", "text/css"); writer.WriteRaw(@" body { font-family: Segoe UI Light, Segoe WP Light, Segoe UI, Helvetica, sans-serif; padding: 0; margin: 0; } body > div { padding: 0 20px; } body > div > div { margin-bottom: 50px; border-top: 1px solid #CCCCCC; width: 50%; } h1 { background-color: #1BA1E2; color: white; padding: 5px 20px; text-wrap: normal; word-break: break-all; } h2 { color: #1BA1E2; } ul { margin-bottom: 30px; } li { margin-bottom: 10px; } li > a { color: #000000; } table { width: 100%; } tr:nth-child(even) { background: #CCCCCC } tr:nth-child(odd) { background: #FFFFFF } td { height: 40px; vertical-align: middle; padding: 0 10px; }" ); } writer.WriteEndElement(); } writer.WriteEndElement(); writer.WriteStartElement("body"); { writer.WriteElementString("h1", title); writer.WriteStartElement("div"); { writer.WriteElementString("p", "The following methods are supported: "); // Method Names writer.WriteStartElement("ul"); { foreach (var method in methods) { // Method Name writer.WriteStartElement("li"); { writer.WriteStartElement("a"); writer.WriteAttributeString("href", $"#{method.Value.Name}"); writer.WriteString(method.Value.Name); writer.WriteEndElement(); } writer.WriteEndElement(); } } writer.WriteEndElement(); } writer.WriteEndElement(); writer.WriteStartElement("div"); { foreach (var method in methods) { var mi = method.Value.MethodInfo; writer.WriteStartElement("h2"); { writer.WriteStartElement("a"); { writer.WriteAttributeString("name", method.Value.Name); writer.WriteString(method.Value.Name); } writer.WriteEndElement(); } writer.WriteEndElement(); // "Parameters" headline writer.WriteElementString("h3", "Parameters"); // "Parameters" table writer.WriteStartElement("table"); { var parameters = mi.GetParameters(); foreach (var parameter in parameters) { writer.WriteStartElement("tr"); { writer.WriteStartElement("td"); { writer.WriteAttributeString("style", "width:30%"); writer.WriteString(parameter.ParameterType.Name); } writer.WriteEndElement(); writer.WriteElementString("td", parameter.Name); } writer.WriteEndElement(); } } writer.WriteEndElement(); // "Return Value" headline writer.WriteElementString("h3", "Return Value"); // "Return Value" table writer.WriteStartElement("table"); { writer.WriteStartElement("tr"); { writer.WriteStartElement("td"); { writer.WriteAttributeString("style", "width:30%"); writer.WriteString(mi.ReturnType.Name); } writer.WriteEndElement(); writer.WriteStartElement("td"); { writer.WriteString( !string.IsNullOrEmpty(method.Value.Description) ? method.Value.Description : "-"); } writer.WriteEndElement(); } writer.WriteEndElement(); } writer.WriteEndElement(); } } writer.WriteEndElement(); } writer.WriteEndElement(); } writer.WriteEndElement(); } writer.WriteEndDocument(); writer.Flush(); ms.Position = 0; context.HttpContext.Response.ContentType = "text/html"; await ms.CopyToAsync(context.HttpContext.Response.Body); } }
public bool CanProcess(XmlRpcContext context) { return(context.HttpContext.Request.Path.StartsWithSegments(context.Options.Endpoint)); }
internal static object ExecuteRequestedMethod( XmlRpcRequest request, XmlRpcMethodDescriptor methodDescriptor, XmlRpcContext context) { var parameters = new List <object>(); var method = methodDescriptor.MethodInfo; var requiredParameters = method.GetParameters(); for (var i = 0; i < requiredParameters.Length; i++) { var parameter = requiredParameters[i]; var type = parameter.ParameterType; if (type.IsPrimitive()) { try { var obj = Convert.ChangeType(request.Parameters[i], type); parameters.Add(obj); } catch (ArgumentOutOfRangeException) { // Add the default value for the requested type. parameters.Add(Activator.CreateInstance(type)); } catch (Exception) { parameters.Add(request.Parameters[i]); } } else if (type.IsArray) { var elementType = type.GetElementType(); var arrayParameters = (object[])request.Parameters[i]; var listType = typeof(List <>); var genericListType = listType.MakeGenericType(elementType); var list = Activator.CreateInstance(genericListType); foreach (Dictionary <string, object> values in arrayParameters) { var element = Activator.CreateInstance(elementType); foreach (var property in element.GetType().GetProperties()) { var nameKey = property.GetSerializationName(); if (values.TryGetValue(nameKey, out object value)) { property.SetValue(element, value); } } list.GetType() .GetMethod("Add") .Invoke( list, new[] { element }); } parameters.Add( list.GetType() .GetMethod("ToArray") .Invoke(list, null)); } else { var complexInstanceParameters = (Dictionary <string, object>)request.Parameters[i]; var complexInstance = Activator.CreateInstance(type); foreach (var property in complexInstance.GetType().GetProperties()) { var nameKey = property.GetSerializationName(); if (complexInstanceParameters.TryGetValue( nameKey, out object value)) { //TODO: to make it more generic, the whole function needs to be rewritten using similar approach as above. Not changing as the whole function needs to be refactored. var propertyType = property.PropertyType; if (propertyType.IsArray) { property.SetValue(complexInstance, ConvertValues(propertyType, value)); } else { property.SetValue(complexInstance, value); } } } parameters.Add(complexInstance); } } var instanceType = method.DeclaringType; if (method.DeclaringType != null && method.DeclaringType.IsInterface) { instanceType = _s_getImplementation(method.DeclaringType); } // ControllerContext is not avalilable in ASP.NET Core and all instance should be instantiated directly through instanceType though controller name and action name can be retrieved through context. using (var scope = context.ServiceScopeFactory.CreateScope()) { var instance = scope.ServiceProvider.GetRequiredService(instanceType); try { Trace.TraceInformation( "XmlRpcMvc: Invoking method {0} with '{1}'", method.Name, string.Join(", ", parameters)); return(method.Invoke(instance, parameters.ToArray())); } catch (XmlRpcFaultException exception) { return(exception); } } }