Restore AJAX handling for ASP.NET Core to previous functionality

Multi tool use
Multi tool use


Restore AJAX handling for ASP.NET Core to previous functionality



In previous MVC5 and below, you could make an ajax call that unwrapped the parameters properly:



JS:


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



CS:


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



In the new aspnetcore, it has changed:



CS:


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



To sum it up, in the new framework, you need to write a wrapper class and can only pass one [FromBody] parameter to the method. Previously, the params would be unwrapped by variable name correctly.



So, i'm trying to re-implement this functionality in an aspnetcore middleware component. I'm having difficulty in how to accomplish calling the controller method properly with the parameters.



My current cut-down code:


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);
}
}



I'm really just not sure about what to do after deserializing the parameters. I have the URL for the endpoint and also the params correctly. Just need to know how to call the method and return the result as JSON. Should i be using Reflection to get the controller method? Or is there a better way using MVC?





Why do you need the middleware? Is your ultimate call to call your .NET Core method "endpoint" with Ajax?
– Brian Ogden
Jun 25 at 23:49





Yes, but i need to unwrap the parameters passed.
– Steve
Jun 26 at 13:45





@Steve, Do you want to call public ActionResult endpoint(int intparam, string strparam) post method using AJAX call? and you don't want to use model. is that your requirement?
– Parth Akbari
Jun 27 at 13:08


public ActionResult endpoint(int intparam, string strparam)





Yeah pretty much.
– Steve
Jun 27 at 14:08





I am able to call ActionResult using AJAX and without using model. not required middleware
– Parth Akbari
Jun 28 at 4:50





2 Answers
2



it's very simple thing i don't know why it not working at your end



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);
}



MyJSCodeMyActionMetho





Did you do this in ASP.NET Core? This looks like old MVC.
– Steve
Jun 28 at 14:20





i did this in Core 2.0
– Parth Akbari
Jul 2 at 4:42



Try implement custom 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;
}
}



Be careful, the code above lacks error handling and etc.



And use it like this:


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



Also you could implement custom attribute to reduce complexity of declaration:


public class BodyFieldAttribute : ModelBinderAttribute
{
public BodyFieldAttribute()
: base(typeof(BodyFieldModelBinder))
{
}
}






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

m,PJmtlSq9h1 luB3qoPrnoz9jKFNsppm 87sG9T8wuSPlLhOI9,GvCm9pWXP eiQ5
UiBX7Q2dW uXoFaHBRIHr,fquTFizY4w Qa2DcLb6ag 1Ie1CdO4jx28LJoe15dy6i8C9Q9WmNk,9

Popular posts from this blog

Rothschild family

Cinema of Italy