Here is my controller...
public class AccountController : BaseController
{
[Route("Account/json_account_log_in")]
public async Task<JsonResult> json_account_log_in(ValidateUserQuery query)
{
ValidateUserDto response = await Mediator.Send(query);
// Do stuf...
}
}
And here is the query class..
public class ValidateUserQuery : IRequest<ValidateUserDto>
{
public string Username { get; set; }
public string Password { get; set; }
}
But in my controller, the query Username and Password are null.
If I remove the IRequest<ValidateUserDto> then Username and Password are correct - but then I can't use Mediatr.
Can't I use classes that inherits from IRequest in ajax calls queries?
Solution ... I needed to add [FromBody]:
public async Task<JsonResult> json_account_log_in([FromBody] ValidateUserQuery query)
Related
Code
Web Api Interface
I now have an interface
[Route("api/[controller]/[action]")]
[ApiController]
public class TestController: ControllerBase
{
private readonly ICustomSession _session;
public TestController(ICustomSession session)
{
_session = session;
}
public async Task<CustomResult<string>> Search(TestSearch testSearch)
{
return new CustomResult<string>(string.Empty);
}
}
My CustomSession
public interface ICustomSession
{
public int SessionId { get; set; }
public Guid UserId { get; set; }
public string UserName { get; set; }
}
My TestSearch
public class SessionInfo
{
public Guid UserId { get; set; }
public string UserName { get; set; }
}
public class TestSearch: SessionInfo
{
public string Keyword { get; set; }
}
Problem
ICustomSession can only be used in the Controller layer, can not go deep into the business, but the business is the need for SessionInfo related information, and SessionInfo is actually read from the ICustomSession.
Now I need to inherit SessionInfo on the parameter class to handle it, but now I don't want to assign the value manually in each api interface
testSearch.UserId = _session.UserId;
I want to use an automatic assignment method that detects the class that inherits SessionInfo and automatically assigns the value from ICustomSession to it
Translated with www.DeepL.com/Translator (free version)
I want to use an automatic assignment method that detects the class that inherits SessionInfo and automatically assigns the value from ICustomSession to it
I'm looking for a way to have more than one action method with the same name in controller without changing Url (route).
[HTTPPost]
Public ActionResult Method1 (Dto1 param)
{
}
[HTTPPost]
Public ActionResult Method2 (Dto2 param)
{
}
[HTTPPost]
Public ActionResult Method3 (Dto3 param)
{
}
This throws error -
Microsoft.AspNetCore.Routing.Matching.AmbiguousMatchException: The request matched multiple endpoints
Dto1, Dto2 and Dto3 derive from a base Dto, each have properties specific to different request methods. I am trying to avoid having a single method with a common Dto which will require multiple validations such as validating mandatory fields based on the value of other fields, etc. If we can have 3 different Post methods with different Dtos, it would makes things much easier
Adding Dtos (Simplified)
public class BaseDto
{
public string CommonProp1 { get; set; }
public string CommonProp2 { get; set; }
}
public class Dto1: BaseDto
{
public enumType Type = enumType.Type1;
public string Property1 { get; set; }
}
public class Dto2 : BaseDto
{
public enumType Type = enumType.Type2;
public string Property2 { get; set; }
}
public class Dto3 : BaseDto
{
public enumType Type = enumType.Type3;
public string Property3 { get; set; }
}
You can use Routes or calling a private method from the three above methods, you shouldn't do this as you want. I think your problem is more deep.
But.... if you still want it, here is a workaround.
Instead of receiving an object, receive a string with json content and parse the object.
But you will have to have a property inside the "json object" or another parameter that defines you wich object it is (Dto1, Dto2 or Dto3). In any case will be the same that use different routes or methods because objects are different.
[HTTPPost]
Public ActionResult Method (string param)
{
//Decode your string called param with JSON with a property inside
}
or
[HTTPPost]
Public ActionResult Method (string param, int type)
{
//Decode your string called param with JSON switching "type" as 1, 2 or 3
}
UPDATE after your update:
I suggest you receive BaseDto and the type in other parameter.
[HTTPPost]
Public ActionResult Method (BaseDto param, int type)
{
}
I need assistance on how get the full URL of code below (object parameter). I tried to run the
http://192.168.1.1:80/api/APILogin/Login?username=admin&encryptedPassword=J+2eQXsuMp5mUBUlBqdkjg==
but it doesn't work.
[RoutePrefix("api/APILogin")]
public class APILoginController : ApiController
{
public APILoginController()
{ }
[HttpPost]
[Route("Login")]
public Object login(LoginRequestCredentials userRequest)
{
}
}
This is the LoginRequestCredentials object.
public class LoginRequestCredentials
{
public string username { get; set; }
public string encryptedPassword { get; set; }
}
Thank you.
this url http://192.168.1.1:80/api/APILogin/Login?username=admin&encryptedPassword=J+2eQXsuMp5mUBUlBqdkjg== will be ok if you use route like this
public Object login(string username, string encryptedPassword) { ... }
but your route waiting for one object so send data in BODY
{
username: "admin",
encryptedPassword: "J+2eQXsuMp5mUBUlBqdkjg=="
}
or send in url
http://192.168.1.1:80/api/APILogin/Login? userRequest. username=admin&userRequest. encryptedPassword=J+2eQXsuMp5mUBUlBqdkjg==
without spaces
I'm trying to validate the progress quantity (and other fields once this works) that belongs to the BeginCollectionItems server side. The request is being sent but the parameter progressQty is not being read by the action.
This is the action I'm trying to map to:
[AllowAnonymous]
[AcceptVerbs("Get", "Post")]
public IActionResult CheckValidProgressQty(int progressQty)
{
int a =progressQty;
var result = false;
if (a > 0)
result = true;
return Json(result);
}
This is the request:
:method: GET
:path: /Components/CheckValidProgressQty?ProgressItems%5B16bad1f2-155c-4a29-844c-34e88da80b7c%5D.ProgressQty=-300
This is the Query String Parameters:
ProgressItems[16bad1f2-155c-4a29-844c-34e88da80b7c].ProgressQty: -300
Here is the remote validation in the View Model Class:
[Remote(action: "CheckValidProgressQty", controller: "Components", HttpMethod ="GET", ErrorMessage = "BAD QTY!")]
public int ProgressQty { get; set; }
Right now it goes into the CheckValidProgressQty method but I'm just not able to access the progressQty parameter. One way I can access is:
Request.QueryString.Value
?ProgressItems%5B16bad1f2-155c-4a29-844c-34e88da80b7c%5D.ProgressQty=-8
and parse it. But I think there should be something more simple available.
ProgressItems[16bad1f2-155c-4a29-844c-34e88da80b7c].ProgressQty: -300
This is posted form data when you do POST method not for GET method.
You could not get the query string on your action parameters using ?ProgressItems%5B16bad1f2-155c-4a29-844c-34e88da80b7c%5D.ProgressQty=-300since they are not match.
Refer to my below demo which introduces how to pass querystring to action, assume that I have models:
public class TestUser
{
[Key]
public int Id { set; get; }
public string Name { get; set; }
public IList<UserInterest> Interests
{
get; set;
}
}
public class UserInterest
{
[Key]
public int Id { set; get; }
[Required]
public string InterestText { set; get; }
public int Option { set; get; }
}
You need to use an object like
public ActionResult UserTest(TestUser model)
And the querystring is ?Interests[0].InterestText=hello
I have a checkout page that has multiple methods for payment. Each method has its own partial view containing its own model. I am trying to get keep the url the same on each of the different methods so if there is an error the url doesn't change. Is there a way to achieve this? Thank you for any help, I have been mulling over this for a while now.
CheckOut Model
public class CheckoutForm
{
public Method1Form method1Form { get; set; }
public Method2Form method2Form { get; set; }
public Method3Form method3Form { get; set; }
}
CheckOut Controller
[HttpGet]
[Route("checkout/{guid}")]
public IActionResult Checkout([FromRoute] String guid)
{
....
return View(model);
}
[HttpPost]
[Route("checkout/{guid}")]
public IActionResult Checkout([FromRoute] String guid, Method1 model)
{
....
//Some Error Condition Triggered
return View(checkoutmodel);
}
[HttpPost]
[Route("checkout/{guid}")]
public IActionResult Checkout([FromRoute] String guid, Method2 model)
{
....
//Some Error Condition Triggered
return View(checkoutmodel);
}
[HttpPost]
[Route("checkout/{guid}")]
public IActionResult Checkout([FromRoute] String guid, Method3 model)
{
....
//Some Error Condition Triggered
return View(checkoutmodel);
}
Similar Question without an answer https://stackoverflow.com/questions/42644136
You cannot. There is no way for Route Engine to differentiate those 3 post methods.
You could append something at the end to the URL to make them different.
[HttpPost]
[Route("checkout/{guid}/paypal")]
public IActionResult Checkout([FromRoute] String guid, Method1 model)
{
....
}
[HttpPost]
[Route("checkout/{guid}/authorizenet")]
public IActionResult Checkout([FromRoute] String guid, Method2 model)
{
....
}