How to use AJAX for ViewComponent in Asp.Net Core? That is calling the method #Component.Invoke ("ComponentName", SomeData); ViewComponent will involve various views depending on SomeData without rebooting the main view.
Update
My solution is:
$(function () {
$(Container).load('ControllerName/ControllerAction', {
ArgumentName: ArgumentValue });
});
Controller :
public IActionResult ControllerAction(string value)
{
return ViewComponent("ViewComponent", value);
}
Is there a way to directly use a ViewComponent as AjaxHelpers in previous versions?
Your solution is correct. From the docs:
[ViewComponents are] not reachable directly as an HTTP endpoint, they're invoked from your code (usually in a view). A view component never handles a request.
While view components don't define endpoints like controllers, you can easily implement a controller action that returns the content of a ViewComponentResult.
So as you suggested, a lightweight controller can act as an AJAX proxy to our ViewComponent.
public class MyViewComponentController : Controller
{
[HttpGet]
public IActionResult Get(int id)
{
return ViewComponent("MyViewComponent", new { id });
}
}
Related
Just realised that my understanding about ASP.NET Core 6 Web API versioning is wrong.
This is my controller:
[ApiVersion("1.0")]
[ApiController]
[Authorize]
public class FundController
{
[MapToApiVersion("1.0")]
[Route("/Fund/v{version:apiVersion}/delta")]
public async Task<List<PortfolioHolding<Holding>>> Delta([FromQuery] Request dataModel)
{
}
}
What I want is to support route /Fund/v1.0/delta and /Fund/delta, when versioning not provided by the consumer (e.g. calling /Fund/delta), the default version will be hit.
So I configured the versioning like this. However, when I call /Fund/delta, I get a http 404 error.
But /Fund/v1.0/delta will hit the correct controller.
What am I doing wrong?
services.AddApiVersioning(option =>
{
option.DefaultApiVersion = new ApiVersion(1, 0);
option.AssumeDefaultVersionWhenUnspecified = true;
option.ReportApiVersions = true;
});
Usually, it's pretty easy to do this that way. The disadvantage of this approach is that you need to manually change the "default" version of API with this attribute
The problem is that you have not specified the routes in the controller.
You should add the default route as well as the formatted version route. Then you should ensure that your endpoints have the version specified in the MapToApiVersion attribute.
Here is a code sample of what your controller should look like:
[ApiVersion("1.0")]
[ApiVersion("2.0")]
[Route("[controller]")]
[Route("[controller]/v{version:apiVersion}")]
public class FundController : ControllerBase
{
[MapToApiVersion("1.0")]
[Route("delta")]
[HttpGet]
public async Task<List<PortfolioHolding<Holding>>> DeltaV1([FromQuery] Request dataModel)
{
}
[MapToApiVersion("2.0")]
[Route("delta")]
[HttpGet]
public async Task<List<PortfolioHolding<Holding>>> DeltaV2([FromQuery]
Request dataModel)
{
}
}
i have some action inside controller likes:
public class ValuesController : Controller
{
[HttpPost]
public string GetInfo()
{
Thread.Sleep(30000); // logics imitation
return "result";
}
}
when I send request from client-side on this action I'll receive "Main Thread blocking" (like deadlock) while awaiting "logics imitations"
how i can prevent it?
already tried:
public class ValuesController : Controller
{
[HttpPost]
public async Task<string> GetInfo()
{
return await Task.Factory.StartNew(() =>
{
Thread.Sleep(30000);
return "result";
});;
}
}
Not working...
already looked (ASP.NET MVC and Ajax, concurrent requests?), but SessionState.ReadOnly way is not for me...
also tried using .svc service instead controller-action but have same troubles.
MVC by default blocks parallel sessions, and there is only one way to avoid it:
[SessionState(SessionStateBehavior.ReadOnly)]
Attribute on Controller and clearly separating logics with using writing and reading sessions.
This question was posted by my colleague. Yes, we have the situation where we need to "fire and forget" (we are trying to call actions asynchronically, when different actions are executed at the same time, but still all we have managed to get is to call actions one after another)
I'm beginning to use WebApi and I'm having an issue with a URL being incorrectly generated
I have an ApiController like this:
public class EntriesController : ApiController
{
public HttpResponseMessage Post(Entry entry)
{
...
}
}
And I was trying to create a standard controller (i.e. not webapi) in the same project to test this api (I already tested the api with fiddler and everything is ok there).
I assumed I could use the standard HTML helpers like this:
#using (Html.BeginForm("Post", "Entries"))
However this generates the following markup:
<form action="/Entries/Post" method="post">
and I expected it to generate
<form action="/api/Entries" method="post">
What is the correct way to generate the API url from a view?
I am using the default api and controller routes.
Thanks
#using (Html.BeginForm("Post", "Entries"))
You can not put WebAPI controller and method in MVC BeginForm like above. You need to pass MVC Controller and action to the BeginForm.
You can create a WebAPI EntriesController instance in your MVC controller, then use this instance to call the WebAPI method. See below:
//MVC Controller
public class EntriesController : Controller
{
[HttpGet]
public ActionResult Entries()
{
return View();
}
[HttpPost]
public ActionResult Entries(SomeModels model)
{
if (ModelState.IsValid)
{
var api = new EntriesController(); // Create WebAPI instance Here
api.Post(model.entry);
return RedirectToAction("Index", "Home");
}
return View();
}
}
This is technically possible by doing:
#using (Html.BeginForm("Post", "api/Entries"))
Don't forget, the "Post" value in the .BeginForm() extension method doesn't mean anything to an out-of-box Web Api route setup. Only the url and HTTP action matter (and any additional values on the URL for method overloading)
You would need to use BeginRouteForm as link generation to Web API routes always depends on the route name. Also make sure to supply the route value called httproute as below.
#using (Html.BeginRouteForm("DefaultApi", new { controller="Entries", httproute="true" }))
I used to use asmx to handle ajax calls from pages, but I have read that it's a legacy product, and it is not very compatible with MVC applications. What's the replacement for asmx that is also compatible with MVC nowadays?
Use Action methods in your controllers to give you the Ajax response. You can return any form of data like HTML markup (using a view, Json, string . Image etc...)
public ActionResult GetItems()
{
var items=dbContext.Items;
return Json(items,JsonRequestBehavior.AllowGet);
}
public ActionResult GetAnother()
{
return Content("I am just string from ajax");
}
You can use same action result for returning HTML markup for an ajax request and normal request using the Request.IsAjax method
public ActionResul Getcustomer(int id)
{
var customer=dbcontext.Customer.Find(id);
if(Request.IsAjax())
{
return View("PartialCustomerForm",customer);
}
return View("RegularCustomerForm",customer);
}
To call these methods from your page, you can use jquery ajax
$.get("#Url.Action("GetItems","Customer")", { id: 3 },function(data){
//do whatever with the response. //alert(data);
});
I am in a legacy asp.net application and I need to call a method within a class via jQuery ajax post.
So far I have a class called NewClass with a single method;
[WebMethod]
public string jQuery_GetCategoryDescription(string CategoryName)
{
return "Slappy";
}
I then have the following jQuery;
$.post('/NewClass/jQuery_GetCategoryDescription', { CategoryName: "trippy" }, function (newHTML) {
alert(newHTML);
});
I've tried putting in the whole namespace in.
However I can't seem to call the method within the class.
EDIT
I am getting a 405 error
If the
[WebMethod]
public string jQuery_GetCategoryDescription(string CategoryName)
{
return "Slappy";
}
Is in side Index.aspx
You can call it by /Index.aspx/jQuery_GetCategoryDescription