Есть ли способ программно изменить параметр webmethod? - PullRequest
0 голосов
/ 06 января 2020

Необходимо манипулировать входными данными веб-метода asp. net перед его выполнением.

Например:

У меня есть один веб-метод с именем web1(string inp1). Теперь я вызываю этот веб-метод со значением inp1 ввода как «Jagan drop table», но мне нужно изменить значение inp1 как «Jagan», а затем передать его соответствующему веб-методу.

Я не хочу заменять это в каждом веб-методе, но в общем месте (например, общая функция или класс).

Ответы [ 2 ]

0 голосов
/ 06 января 2020

Один из способов выполнить это требование - использовать Soap Extensions -

Я беру код для сайта, указанного ниже, и пытаюсь объяснить то же самое соответственно -

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

  1. Создание класса расширения Soap.
  2. Вся обработка происходит в вызове processmessage. Если вы видите " updateMessage ", который вызывается beforeSerialize , этот метод анализирует и извлекает XML с входным узлом " inp1 "и заменяет значение оператором split, который соответствует вашему требованию. При необходимости вы можете изменить далее!
  3. Класс " ParameterValueChangedSoapExtensionAttribute ", который поможет указать класс Soap Extention.
  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";
    }
}

Пожалуйста, go через ссылку ниже для получения дополнительной информации о SOAP Расширениях -

Soap Расширения

SoapExtensionAttribute

0 голосов
/ 06 января 2020

Вы пытаетесь иметь дело с Sql инъекцией ? Просто используйте 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
    }
}

, и вы можете сделать это SampleMiddleware.InvokeAsync для каждого метода в контроллере с Microsoft.AspNetCore.Builder.UseMiddlewareExtensions

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