首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于URI的匹配OperationContract查找

基于URI的匹配OperationContract查找
EN

Stack Overflow用户
提问于 2011-06-15 15:40:00
回答 1查看 398关注 0票数 0

...or“如何根据URI确定将调用哪个WCF方法?”

在WCF服务中,假设调用了一个方法,并且我有用来调用它的URI。如何获得URI映射到的WCF端点、方法、参数等信息?

代码语言:javascript
复制
[OperationContract]
[WebGet(UriTemplate = "/People/{id}")]
public Person GetPersonByID(int id)
{
    //...
}

例如,如果URI为:GET http://localhost/Contacts.svc/People/1,我希望获得以下信息:服务名称(服务)、方法(GetPersonByID)、参数(PersonID=1)。关键是能够侦听请求,然后提取请求的细节,以便跟踪API调用。

该服务通过http托管。在.Net缓存启动之前,需要提供这些信息,以便能够跟踪每个调用(不管是否缓存)。这可能意味着在HttpApplication.BeginRequest中执行此操作。

我希望而不是使用反射。我想使用WCF使用的相同方法来确定这一点。例如MagicEndPointFinder.Resolve(uri)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-06-15 20:35:48

这就是我最后所做的,如果有一个更干净的方法,我仍然感兴趣!

休息

代码语言:javascript
复制
private static class OperationContractResolver
{
    private static readonly Dictionary<string, MethodInfo> RegularExpressionsByMethod = null;

    static OperationContractResolver()
    {
    OperationContractResolver.RegularExpressionsByMethod = new Dictionary<string, MethodInfo>();

    foreach (MethodInfo method in typeof(IREST).GetMethods())
    {
        WebGetAttribute attribute = (WebGetAttribute)method.GetCustomAttributes(typeof(WebGetAttribute), false).FirstOrDefault();

        if (attribute != null)
        {
        string regex = attribute.UriTemplate;

        //Escape question marks. Looks strange but replaces a literal "?" with "\?".
        regex = Regex.Replace(regex, @"\?", @"\?");

        //Replace all parameters.
        regex = Regex.Replace(regex, @"\{[^/$\?]+?}", @"[^/$\?]+?");

        //Add it to the dictionary.
        OperationContractResolver.RegularExpressionsByMethod.Add(regex, method);
        }
    }
    }

    public static string ExtractApiCallInfo(string relativeUri)
    {
    foreach (string regex in OperationContractResolver.RegularExpressionsByMethod.Keys)
        if (Regex.IsMatch(relativeUri, regex, RegexOptions.IgnoreCase))
        return OperationContractResolver.RegularExpressionsByMethod[regex].Name;

    return null;
    }
}

肥皂

代码语言:javascript
复制
private static void TrackSoapApiCallInfo(HttpContext context)
{
    string filePath = Path.GetTempFileName();
    string title = null;

    //Save the request content. (Unfortunately it can't be written to a stream directly.)
    context.Request.SaveAs(filePath, false);

    //If the title can't be extracted then it's not an API method call, ignore it.
    try
    {
    //Read the name of the first element within the SOAP body.
    using (XmlReader reader = XmlReader.Create(filePath))
    {
        if (!reader.EOF)
        {
        XmlNamespaceManager nsManager = new XmlNamespaceManager(reader.NameTable);
        XDocument document = XDocument.Load(reader);

        //Need to add the SOAP Envelope namespace to the name table.
        nsManager.AddNamespace("s", "http://schemas.xmlsoap.org/soap/envelope/");
        title = document.XPathSelectElement("s:Envelope/s:Body", nsManager).Elements().First().Name.LocalName;
        }
    }

    //Delete the temporary file.
    File.Delete(filePath);
    }
    catch { }

    //Track the page view.
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6360407

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档