не удалось связать строковые индексированные параметры строки запроса - PullRequest
1 голос
/ 04 мая 2019

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

вот значения, которые я пытался связать

search[value]: Exception happ...
search[regex]: false

вот модель, с которой я пытаюсь связать getLogsAjax(DataTableAjaxPostModel model)

public class DataTableAjaxPostModel
{
    public int draw { get; set; }
    public int start { get; set; }
    public int length { get; set; }
    public List<Column> columns { get; set; }
    public search search { get; set; }
    public List<Order> order { get; set; }
}

public class search
{
    public string value { get; set; }
    public string regex { get; set; }
}

остальная часть модели привязывается правильно, за исключением объекта класса поиска, я утроил проверку того, что запрос содержит значения для этого объекта, что мне здесь не хватает? постскриптум этот же код якобы работал до .net core

Ответы [ 3 ]

3 голосов
/ 04 мая 2019

Немного больше информации о коде было бы полезно, например, раздел кода, который фактически выполняет связывание, однако вот пример контроллера dotnetcore с привязкой параметров запроса.Также в C # распространенной практикой являются имена классов, а оба поля пишутся в верхнем регистре.

using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;

[Route("api/[controller]")]
public class SampleController : Controller
{
    [HttpGet]
    [Route("")]
    public IActionResult ExampleGet([FromQuery] DataTableAjaxPostModel dataTableAjaxPostModel)
    {
        // You should be able to debug and see the value here
        var result = dataTableAjaxPostModel.search;
        return Ok();
    }

    public class DataTableAjaxPostModel
    {
        public int draw { get; set; }
        public int start { get; set; }
        public int length { get; set; }
        public List<Column> columns { get; set; }
        public search search { get; set; }
        public List<Order> order { get; set; }
    }

    public class search
    {
        public string value { get; set; }
        public string regex { get; set; }
    }
}
0 голосов
/ 06 мая 2019
  1. Вам не нужно связывать каждое поле вручную. Использование отражение сделает это легко.
  2. Кроме того, нет необходимости связывать свойства внешней модели (свойства DataTableAjaxPostModel) вручную. Это потому, что они будут выполняться с помощью встроенного связующего устройства .

Осуществление

создать пользовательскую папку QueryStringDictSyntaxBinder<TModel>:

internal class QueryStringDictSyntaxBinder<TModel> : IModelBinder
{
    public Task BindModelAsync(ModelBindingContext bindingContext)
    {
        if (bindingContext == null)
            throw new ArgumentNullException(nameof(bindingContext));
        try
        {
            var result = Activator.CreateInstance<TModel>();
            foreach(var pi in typeof(TModel).GetProperties())
            {
                var modelName = bindingContext.ModelName;
                var qsFieldName = $"{modelName}[{pi.Name}]";
                var field= bindingContext.HttpContext.Request.Query[qsFieldName].FirstOrDefault();
                if(field != null){
                    pi.SetValue(result,field);
                }
                // do nothing if null , or add model binding failure messages if you like
            }
            bindingContext.Result = ModelBindingResult.Success(result);
        }
        catch
        {
            bindingContext.Result = ModelBindingResult.Failed();
        }

        return Task.CompletedTask;
    }
}

А затем украсьте свойство search с помощью [ModelBinder(typeof(QueryStringDictSyntaxBinder<search>))]:

public class DataTableAjaxPostModel
{
    public int draw { get; set; }
    public int start { get; set; }
    public int length { get; set; }
    public List columns { get; set; }

    <b>[ModelBinder(typeof(QueryStringDictSyntaxBinder<search>))]</b>
    <b>public search search { get; set; }</b>

    public List order { get; set; }
}

Контрольный пример:

Я проверяю его по следующим запросам, и он прекрасно работает для меня:

?draw=1&search[value]=abc&search[regex]=(.*)&
?draw=1&sEarCh[value]=opq&Search[regex]=([^123]*)&
?draw=1&seaRch[value]=rst&Search[regex]=(.*)&
?draw=1&Search[value]=abc&
?draw=1&
0 голосов
/ 04 мая 2019

похоже, что ни у кого нет ответа на этот вопрос, поэтому я выбрал другой маршрут и написал свой собственный пользовательский переплет, если придет лучший ответ, я приму его вместо этого, вероятно, реорганизую его позже (хахаха IKR!)

public class DTModelBinder : IModelBinder
{
    public Task BindModelAsync(ModelBindingContext bindingContext)
    {
        if (bindingContext == null)
            throw new ArgumentNullException(nameof(bindingContext));

        try
        {
            var result = new DataTableAjaxPostModel();
            if (bindingContext.HttpContext.Request.Query.Keys.Contains("draw"))
                result.draw = int.Parse(bindingContext.ValueProvider.GetValue("draw").FirstValue);
            if (bindingContext.HttpContext.Request.Query.Keys.Contains("search[value]") &&
                bindingContext.HttpContext.Request.Query.Keys.Contains("search[regex]"))
                result.search = new search()
                {
                    regex = bindingContext.ValueProvider.GetValue("search[regex]").FirstValue,
                    value = bindingContext.ValueProvider.GetValue("search[value]").FirstValue
                };
            //...
            bindingContext.Result = ModelBindingResult.Success(result);
        }
        catch
        {
            bindingContext.Result = ModelBindingResult.Failed();
        }

        return Task.CompletedTask;
    }
}
...