Привязка модели Нэнси к подклассу.Autodetection? - PullRequest
0 голосов
/ 16 сентября 2018

Мне интересно, смогу ли я заставить Нэнси автоматически связать запрос с подклассом типа, который я указываю в параметрах типа. Вот пример того, чего я пытаюсь достичь:

Учитывая эти классы:

public class Shape
{
    public int Height { get; set; }
    public int Width { get; set; }
}

public class Triangle : Shape
{
    public string SomeTriangleOnlyProp { get; set; }
}

public class Square : Shape
{
    public string SomeSquareOnlyProp { get; set; }
}

Тогда, учитывая это Json:

{
    "Height" : 10,
    "Width" : 20
}

Тогда это мой желаемый результат:

var shape = this.Bind<Shape>(); //Returns a Shape object

Учитывая это Json:

{
    "Height" : 10,
    "Width" : 20,
    "SomeTriangleOnlyProp" : "Triangle"
}

Тогда это мой желаемый результат:

var shape = this.Bind<Shape>(); //Returns a Triangle object

Учитывая это Json:

{
    "Height" : 10,
    "Width" : 20,
    "SomeSquareOnlyProp" : "Square"
}

Тогда это мой желаемый результат:

var shape = this.Bind<Shape>(); //Returns a Square object

Могу ли я достичь этого только с помощью пользовательского класса привязки? Я мог бы попытаться привязать к каждому типу отдельно и обработать любые ошибки, но это кажется действительно неоптимальным.

1 Ответ

0 голосов
/ 16 сентября 2018

Я нашел решение, я не уверен, что оно самое лучшее, но оно работает так, как мне нужно, поэтому я пойду сейчас.Я написал специальный механизм связывания модели, который смотрит на json, чтобы попытаться определить, к какому объекту он должен сериализоваться:

public class ShapeBinder : IModelBinder
{
    public object Bind(NancyContext context, Type modelType, object instance, BindingConfig configuration, params string[] blackList)
    {
        using (var sr = new StreamReader(context.Request.Body))
        {
            var json = sr.ReadToEnd();
            if (json.Contains("SomeTriangleOnlyProp"))
            {
                var triangle = new Nancy.Json.JavaScriptSerializer().Deserialize<Triangle>(json);
                return triangle;
            }
            else if (json.Contains("SomeSquareOnlyProp"))
            {
                var square = new Nancy.Json.JavaScriptSerializer().Deserialize<Square>(json);
                return square;
            }
            else
            {
                var shape = new Nancy.Json.JavaScriptSerializer().Deserialize<Shape>(json);
                return shape;
            }
        }
    }

    public bool CanBind(Type modelType)
    {
        return modelType == typeof(Shape);
    }
}

Вызов этого в NancyModule с var shape = this.Bind<Shape>(); возвращает Triangle, еслиу JSON была треугольная опора, Square, если у JSON была квадратная опора, или только обычный базовый класс Shape, если у JSON не было ни одной.

...