南希模型绑定到子类 [英] Nancy model binding to child class

查看:140
本文介绍了南希模型绑定到子类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正与南希的默认模型联编的问题。鉴于以下...

We are having an issue with Nancy's default model binder. Given the below...

public class Foo
{
    public Foo()
    {
    }

    public string Name { get; set; }

    public Bar Bar { get; set; }
}

public class Bar
{
    public string Name { get; set; }
}



像...

with elements like...

<input type="text" value="Name" />
<input type="text" value="Bar.Name" />

通过使用像这样..

无功富= this.Bind<富>();

这正确地结合Foo.Name但无法绑定Foo.Bar.Name

This correctly binds Foo.Name but fails to bind Foo.Bar.Name

有没有一种方法,使这种使用默认的粘结剂结合,或者是否需要推出自己的?如果是的话有什么好的例子?

Is there a way to enable this kind of binding with the default binder or do we need to roll our own? If so are there any good examples?

推荐答案

为什么不试试这个。我相当肯定的递归可以优化,这东西会拿出它不起作用,而且它可以放在某处比IModelBinder聪明,但它基本上你想要做什么。

Why not try this. I'm fairly sure the recursion could be optimised, and that something will come up where it doesn't work, and that it could be put somewhere cleverer than a IModelBinder, but it basically does what you want.

/// <summary>
/// Sample model binder that manually binds customer models
/// </summary>
public class CustomModelBinder : IModelBinder
{
    /// <summary>
    /// Bind to the given model type
    /// </summary>
    /// <param name="context">Current context</param>
    /// <param name="modelType">Model type to bind to</param>
    /// <param name="blackList">Blacklisted property names</param>
    /// <returns>Bound model</returns>
    public object Bind(NancyContext context, Type modelType, params string[] blackList)
    {
        var parentObject = Activator.CreateInstance(modelType);

        foreach (var key in context.Request.Form)
        {
            var value = context.Request.Form[key];
            this.SetObjectValue(parentObject, modelType, key, value);
        }

        return parentObject;
    }

    /// <summary>
    /// Sets the object value.
    /// </summary>
    /// <param name="instance">The instance.</param>
    /// <param name="type">The type.</param>
    /// <param name="key">Name of the property.</param>
    /// <param name="propertyValue">The property value.</param>
    private void SetObjectValue(object instance, Type type, string key, string propertyValue)
    {
        if (key.Contains("."))
        {
            this.SetObjectValueDeep(instance, type, key, propertyValue);
        }

        PropertyInfo propertyInfo = type.GetProperty(key);
        if (propertyInfo == null)
        {
            return;
        }

        propertyInfo.SetValue(instance, Convert.ChangeType(propertyValue, propertyInfo.PropertyType), null);
    }

    /// <summary>
    /// Sets the object value derp.
    /// </summary>
    /// <param name="instance">The instance.</param>
    /// <param name="type">The type.</param>
    /// <param name="key">The key.</param>
    /// <param name="propertyValue">The property value.</param>
    private void SetObjectValueDeep(object instance, Type type, string key, string propertyValue)
    {
        var propList = key.Split('.').ToList();

        PropertyInfo propertyInfo = type.GetProperty(propList.First());
        if (propertyInfo == null)
        {
            return;
        }

        var childObject = propertyInfo.GetValue(instance, null);

        if (childObject == null)
        {
            childObject = Activator.CreateInstance(propertyInfo.PropertyType);
            propertyInfo.SetValue(instance, childObject, null);
        }

        propList.RemoveAt(0);

        var newKey = propList.Aggregate(string.Empty, (current, prop) => current + (prop + ".")).TrimEnd('.');

        if (newKey.Contains("."))
        {
            this.SetObjectValueDeep(childObject, childObject.GetType(), newKey, propertyValue);
        }
        else
        {
            this.SetObjectValue(childObject, childObject.GetType(), newKey, propertyValue);
        }
    }

    /// <summary>
    /// Determines whether this instance can bind the specified model type.
    /// </summary>
    /// <param name="modelType">Type of the model.</param>
    /// <returns>
    ///   <c>true</c> if this instance can bind the specified model type; otherwise, <c>false</c>.
    /// </returns>
    public bool CanBind(Type modelType)
    {
        return true;
    }
}

这篇关于南希模型绑定到子类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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