序列化从URI模板字符串的操作类型参数 [英] Deserialize a string from the uri template to an operation Type parameter

查看:152
本文介绍了序列化从URI模板字符串的操作类型参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有,我希望能够呼吁所有类在一定的空间或组装此REST风格的服务。而我将需要知道哪种类型的叫法里面的操作。总之我希望有一个模板,让这两种:

I have this restfull service that I want to be able to call for all classes in a certain namespace or assembly. And I'm going to need to know for which Type it is called inside the operation. In short I want a template that allows both of these:

../MyClass1/some/further/spec
../MyClass2/some/further/spec

我希望我的URI的模板看起来是这样的:

I want my uri templates to look something like this:

/{type}/some/further/{info}

和我的操作是这样的:

public void ClassSpecificOfSomeFurtherSpec(Type type, string info)

我假设有没有办法做到像下面,我猜是我真正想要达到什么。毕竟,仿制药必须在编译的时候我想决定。但它照亮了问题:

I'm assuming there's no way to do anything like the following, which I guess is what I'm really trying to achieve. After all, generics have to be decided at compile time I guess. But it illuminates the problem:

public void ClassSpecificOfSomeFurtherSpec<type>(string info)

这里的问题是输入类是A类的短名称,而不是真实姓名,这意味着Type.GetType(类,真,真)将无法正常工作。如果会,我可以用在我的自定义反序列化,一切都将被罚款。但是,因为它不会,我不愿意硬$ C C我的空间$到我一般反序列化,因为这将使它完全非通用。

The problem here is that the input for class is a the short Name of a Type, rather than the FullName, which means Type.GetType(class, true, true) won't work. If it would I could use that in my custom deserialization, and everything would be fine. But since it won't, I'm reluctant to hardcode my namespace into my generic deserialization, since it would make it utterly non-generic.

如果我是对的命名空间添加IParameterInspector,可能我再修改参数(或只检查它),和粘性反序列化发生前的地方,或将订单是周围的其他方法?

If I were to add an IParameterInspector, could I then modify the parameter (or only inspect it), and tack on the namespace before the deserialization takes place, or will the order be the other way around?

我有这种感觉,我是过于复杂的事情。是否有一个没有脑子的方式做这样的事情,我已经错过了,或者一些真正有说服力的理由,我不应该一概而论我服务这么多?

I've got this feeling that I'm overcomplicating things. Is there a no-brainer way to do this sort of thing that I've missed, or some really convincing reason why I shouldn't generalize my services this much?

底线是,我想避免这样的code,每一次操作:

Bottom line is that I want to avoid this sort of code for every single operation:

public Response ClassSpecificOfSomeFurtherSpec(string type, string spec)
{
    Type theType = Type.GetType("My.NameSpaced."+type, true, true);
    //.. and the stuff that does things
}

UPDATE1

Update1

所以,我发现这个漂亮的<一个href="http://blogs.msdn.com/b/carlosfigueira/archive/2011/04/12/wcf-extensibility-ioperationbehavior.aspx"相对=nofollow称号=博客文章>博客文章通过卡洛斯描述了如何添加一个转成IParameterInspector的改进版本,还可以修改参数的选项。在博客中他只修改返回值。我想要做的是修改输入值。所以,我补充说,能力和增加我的修饰符的类:

So, I found this nice blog post by Carlos describing how to add the option of turning an IParameterInspector into an improved version that can also modify parameters. In the blog he only modifies return values. What I wanted to do was modify the input value. So, I added that capability and added my modifier class:

public class EntityParameterModifier : IParameterModifier
{
    public OperationDescription Description { get; private set; }

    public EntityParameterModifier(OperationDescription description)
    {
        Description = description;
    }

    public object BeforeCall(string operationName, ref object[] inputs)
    {
        var parts = Description.Messages[0].Body.Parts;
        for (int i = 0; i < parts.Count; i++)
        {
            if (parts[i].Type == typeof(Type) && inputs[i].GetType() == typeof(string))
                inputs[i] = EntityStringToType((string)inputs[i]);
        }

        return null;
    }

    public void AfterCall(string operationName, object[] outputs, ref object returnValue, object correlationState) { }

    private Type EntityStringToType(string entityString)
    {
        Assembly assembly = Assembly.GetAssembly(typeof(Entity));
        Type type = (from t in assembly.GetTypes()
                     where t.Name == entityString || t.FullName == entityString
                     select t).SingleOrDefault<Type>();
        return type;
    }
}

不过,很显然,他们已经增加了一些区块prevent你做这样的事情:

But, of course they've added some blocks to prevent you from doing this sort of thing:

[InvalidOperationException: Operation 'ClassSpecificOfSomeFurtherSpec' in contract 
'IMyServiceContract' has a path variable named 'type' which does not have type 'string'.
Variables for UriTemplate path segments must have type 'string'.]
System.ServiceModel.Dispatcher.UriTemplateClientFormatter.Populate(Dictionary`2& pathMapping, Dictionary`2& queryMapping, Int32& totalNumUTVars, UriTemplate& uriTemplate, OperationDescription operationDescription, QueryStringConverter qsc, String contractName) +1128

这点我在一个完全新的方向。有没有什么办法来覆盖UriTemplateClientFormatter或相关的类来实现我想要什么?

Which points me in a completely new direction. Is there any way to override the UriTemplateClientFormatter or related classes to achieve what I want?

推荐答案

可能是这样,但你必须写自己的 IDispatchMessageFormatter 这既是认识UriTemplates的并且知道如何字符串和类型之间的转换 - 不是一件容易的事。这得到与WCF的Web API项目(见 HTTP简单://wcf.$c$cplex.com ),在那里你必须通过参数提供了更大的灵活性。

Possible it is, but you'll have to write your own IDispatchMessageFormatter which is both aware of UriTemplates and knows how to convert between string and types - not an easy task. This gets easier with the WCF Web API project (see http://wcf.codeplex.com), where you have more flexibility over the parameter providers.

这篇关于序列化从URI模板字符串的操作类型参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆