【问题标题】:Is there is any way to change the webmethod parameter programatically?有没有办法以编程方式更改 webmethod 参数?
【发布时间】:2020-04-23 17:11:43
【问题描述】:

在执行之前需要操作 asp.net web-service web 方法输入。

例如:

我有一个名为web1(string inp1) 的网络方法。现在,我将输入 inp1 值作为“Jagan drop table”调用此 Web 方法,但我需要将 inp1 值更改为“Jagan”,然后将其传递给相应的 Web 方法。

我不想在每个 web 方法中替换它,而是在通用的地方(如通用函数或类)。

【问题讨论】:

  • @SushantYelpale OP 在问题标签中提到了asmx
  • 我删除了 web api 标签
  • 我建议在这种情况下使用SOAP extension
  • 您应该使用参数,坦率地说,为数据处理编写一个通用类是生计——您应该已经知道如何做到这一点。

标签: c# asp.net sql-injection sqlparameter


【解决方案1】:

你想处理with Sql injection吗?只需在构建查询时使用 sql 参数即可避免它。

我不认为这是在不通知的情况下从传入参数中删除某些内容的好方法。最好检查一下sql注入,发现了就报错。

如果您正在寻找检查所有传入参数的方法,您可以使用 ASP.NET 中间件。 喜欢

public class SampleMiddleware
{
    private readonly RequestDelegate _next;

    public SampleMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext httpContext)
    {
        //you can have access for 
        httpContext.Request.Query
        httpContext.Request.Headers
        httpContext.Request.Body
    }
}

您可以使用Microsoft.AspNetCore.Builder.UseMiddlewareExtensions 为控制器中的每个方法执行此SampleMiddleware.InvokeAsync

public class Startup
{
public void Configure(IApplicationBuilder app)
{
app.UseMiddleware<SampleMiddleware>();
}
}

【讨论】:

  • 请记住,async 将取决于所使用的 .NET Framework 版本和编程方法(经典 ASP.NET、MVC、Razor Pages)。我不会做任何太花哨的东西,在这里,只要坚持基础。此外,跨多个函数的使用不依赖于异步执行;仅仅拥有一个可访问的类就足够了。在某些情况下,您甚至可以摆脱静态类函数。不过,请继续使用 SQL 参数。
【解决方案2】:

实现要求的一种方法是使用 Soap Extensions -

我正在获取以下网站的代码并尝试相应地解释 -

https://expertsys.hu/2017/10/11/renaming-asmx-webmethod-parameter-preserving-compatibility/

  1. 创建 Soap 扩展类。
  2. 整个处理过程发生在 processmessage 调用中。如果您看到名为 beforeSerialize 的“updateMessage”方法,则此方法会解析并提取带有输入的 XML节点“inp1”并根据您的要求用拆分运算符替换该值。如果需要,您可以进一步更改!
  3. ParameterValueChangedSoapExtensionAttribute”类有助于指定 Soap 扩展类。
  4. 所有其他方法都是帮助类来实现需求。
public class ParameterValueChangedSoapExtension : SoapExtension
{
    private Stream streamChainedAfterUs = null;
    private Stream streamChainedBeforeUs = null;

    private const int STREAMBUFFERSIZE = 65535;

    private ParameterValueChangedSoapExtensionAttribute ParameterValueChangedSoapExtensionAttribute = null;

    public override Stream ChainStream(Stream stream)
    {
        if (stream == null)
        {
            throw new ArgumentNullException("stream");
        }
        Stream ret = null;
        this.streamChainedBeforeUs = stream;
        this.streamChainedAfterUs = new MemoryStream();
        ret = this.streamChainedAfterUs;
        return ret;
    }

    public override object GetInitializer(Type serviceType)
    {
        throw new NotSupportedException();
    }

    public override object GetInitializer(LogicalMethodInfo methodInfo, SoapExtensionAttribute attribute)
    {
        if (attribute == null)
        {
            throw new ArgumentNullException("attribute");
        }
        object ret = attribute;
        return ret;
    }

    public override void Initialize(object initializer)
    {
        if (initializer == null)
        {
            throw new ArgumentNullException("initializer");
        }
        ParameterValueChangedSoapExtensionAttribute = initializer as ParameterValueChangedSoapExtensionAttribute;
        if (ParameterValueChangedSoapExtensionAttribute == null)
        {
            throw new InvalidOperationException(String.Format("initializer must be of type {0}, but its a {1}!", typeof(ParameterValueChangedSoapExtensionAttribute), initializer.GetType()));
        }
    }

    public override void ProcessMessage(SoapMessage message)
    {
        if (message == null)
        {
            throw new ArgumentNullException("message");
        }
        switch(message.Stage)
        {
            case SoapMessageStage.BeforeSerialize:
                break;
            case SoapMessageStage.AfterSerialize:
                streamChainedAfterUs.Position = 0;
                Copy(streamChainedAfterUs, streamChainedBeforeUs);
                break;
            case SoapMessageStage.BeforeDeserialize:
                UpdateMessage(message);
                streamChainedAfterUs.Position = 0;
                break;
            case SoapMessageStage.AfterDeserialize:
                break;
            default:
                throw new NotImplementedException(message.Stage.ToString());
        }
    }

    private void UpdateMessage(SoapMessage message)
    {
        var soapMsgAsString = ReadOriginalSoapMessage();
        var soapMsgRootNode = XElement.Parse(soapMsgAsString);
        var callDescriptorNode = FindCallDescriptorNode(soapMsgRootNode, message.MethodInfo.Name);
        var ns = callDescriptorNode.Name.Namespace;
        var originalNameWeLookFor = ns + ParameterValueChangedSoapExtensionAttribute.OriginalParameterName;
        var nodeWithOriginalName = callDescriptorNode.Elements().FirstOrDefault(i => i.Name == originalNameWeLookFor);
        if (nodeWithOriginalName != null)
        {
            //Here implement according to your need!
            nodeWithOriginalName.Value = nodeWithOriginalName.split(' ')[0];
            var nodeWithCurrentName = new XElement(ns + ParameterValueChangedSoapExtensionAttribute.CurrentParameterName, nodeWithOriginalName.Value);
            nodeWithOriginalName.AddAfterSelf(nodeWithCurrentName);
            nodeWithOriginalName.Remove();
        }
        WriteResultSoapMessage(soapMsgRootNode.ToString());
    }

    private XElement FindCallDescriptorNode(XElement soapMsgRootNode, string methodName)
    {
        XElement ret = null;
        var soapBodyName = soapMsgRootNode.Name.Namespace + "Body";
        var soapBodyNode = soapMsgRootNode.Elements().First(i => i.Name == soapBodyName);
        ret = soapBodyNode.Elements().First(i => i.Name.LocalName == methodName);
        return ret;
    }

    private void WriteResultSoapMessage(string msg)
    {
        streamChainedAfterUs.Position = 0;
        using (var sw = new StreamWriter(streamChainedAfterUs, Encoding.UTF8, STREAMBUFFERSIZE, true))
        {
            sw.Write(msg);
        }
    }

    private string ReadOriginalSoapMessage()
    {
        string ret = null;
        using (var sr = new StreamReader(streamChainedBeforeUs, Encoding.UTF8, false, STREAMBUFFERSIZE, true))
        {
            ret = sr.ReadToEnd();
        }
        return ret;
    }

    private void Copy(Stream from, Stream to)
    {
        using (var sr = new StreamReader(from, Encoding.UTF8, false, STREAMBUFFERSIZE, true))
        {
            using (var sw = new StreamWriter(to, Encoding.UTF8, STREAMBUFFERSIZE, true))
            {
                var content = sr.ReadToEnd();
                sw.Write(content);
            }
        }
    }
}


[AttributeUsage(AttributeTargets.Method, AllowMultiple=true)]
public class ParameterValueChangedSoapExtensionAttribute : SoapExtensionAttribute
{
    public override Type ExtensionType
    {
        get { return typeof(ParameterNameChangedSoapExtension); }
    }

    public override int Priority { get; set; }
    public string CurrentParameterName { get; private set; }
    public string OriginalParameterName { get; private set; }

    public ParameterValueChangedSoapExtensionAttribute()
    {
        this.CurrentParameterName = "inp1";
        this.OriginalParameterName = "inp1";
    }
}

请通过以下链接了解有关 SOAP 扩展的更多信息 -

Soap Extensions

SoapExtensionAttribute

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-13
    • 1970-01-01
    • 1970-01-01
    • 2020-01-14
    • 1970-01-01
    • 2020-09-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多