Восстановите обработку AJAX для ASP.NET Core до предыдущей функциональности - PullRequest
0 голосов
/ 11 июня 2018

В предыдущем MVC5 и ниже вы могли сделать ajax-вызов, который правильно развернул параметры:

JS:

$.post('/controller/endpoint',{intparam: 1, strparam: 'hello'})

CS:

public ActionResult endpoint(int intparam, string strparam){}

Inновый aspnetcore, он изменился:

CS:

public CustomClassWrapper{ 
    public int intparam {get;set;}
    public string stringparam {get;set;}
}
public ActionResult endpoint([FromBody]CustomClassWrapper item){}

Чтобы подвести итог, в новом фреймворке вам нужно написать класс-обёртку и передать только один [FromBody]Параметр к методу.Ранее параметры распаковывались по имени переменной правильно.

Итак, я пытаюсь повторно реализовать эту функцию в компоненте промежуточного программного обеспечения aspnetcore.У меня возникают трудности с правильным вызовом метода контроллера с параметрами.

Мой текущий сокращенный код:

public async Task Invoke(HttpContext context)
        {
            if (IsAjaxRequest(context.Request))
            {
                try
                {
                    string bodyContent = new StreamReader(context.Request.Body).ReadToEnd();
                    var parameters = JsonConvert.DeserializeObject(bodyContent);
                    ///What to do here?
                }
                catch (Exception ex)
                {
                    throw new Exception("AJAX method not found ", ex);
                }
            }
            else
            {
                await _next(context);
            }
        }

Я просто не уверен, что делатьсделать после десериализации параметров.У меня есть URL для конечной точки, а также параметры правильно.Просто нужно знать, как вызвать метод и вернуть результат в формате JSON.Должен ли я использовать Reflection, чтобы получить метод контроллера?Или есть лучший способ использования MVC?

Ответы [ 2 ]

0 голосов
/ 02 июля 2018

Попробуйте реализовать пользовательский IModelBinder.

public class BodyFieldModelBinder : IModelBinder
{
    public Task BindModelAsync(ModelBindingContext bindingContext)
    {
        bindingContext.HttpContext.Request.EnableRewind(); // required to read request body multiple times
        var inputStream = bindingContext.HttpContext.Request.Body;
        if (inputStream.Position != 0L)
            inputStream.Position = 0;
        var bodyValue = new StreamReader(inputStream, Encoding.UTF8).ReadToEnd();
        var jsonObject = (JObject)JsonConvert.DeserializeObject<object>(bodyValue);
        if (jsonObject.TryGetValue(bindingContext.FieldName, out var jToken))
        {
            var jsonSerializer = JsonSerializer.Create();
            var result = jToken.ToObject(bindingContext.ModelType, jsonSerializer);
            bindingContext.Result = ModelBindingResult.Success(result);
            return Task.CompletedTask;
        }
        bindingContext.Result = ModelBindingResult.Failed();
        return Task.CompletedTask;
    }
}

Будьте осторожны, в приведенном выше коде отсутствует обработка ошибок и т. Д.

И используйте его так:

[HttpPost]
public IActionResult Endpoint([ModelBinder(typeof(BodyFieldModelBinder))] int intparam)

Также вы можете реализовать пользовательский атрибут, чтобы уменьшить сложность объявления:

public class BodyFieldAttribute : ModelBinderAttribute
{
    public BodyFieldAttribute()
        : base(typeof(BodyFieldModelBinder))
    {
    }
}
0 голосов
/ 28 июня 2018

это очень простая вещь, я не знаю, почему она не работает на вашем конце

JS

$.post('actionMethodURl', { FirstName: '1', LastName: 'hello' }).done(Successfunction);

CS

[HttpPost]
public ActionResult endpoint(string FirstName,string LastName)
{
  object Message = string.Empty;
  if (ModelState.IsValid)
   {
     Message = "Pass";
   }
   else
   {
   Message = ModelState.Errors();
   }
   return Json(Message);
}

MyJSCode MyActionMetho

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...