Asp.net web api routing issue? - c#

I am using web api in my mvc application. I have a problem while calling web api using jquey.get function. Consider the following scenario:
I have 2 controller name:
HomeMVCController
TestAPIController (using mvc style routing i.e. api/{controller}/{action}/{id})
HomeMVC controller contains 2 actions
Index
About
TestAPI controller contains 1 action
Get
When i was on Index view of HomeMVC controller i.e.
http://localhost:1025/Home
and when i call $.get("api/TestAPI/Get") from the browser it returns the expected json response.
But when i was on About view of HomeMVC controller i.e.
http://localhost:1025/Home/About
and when i call $.get("api/TestAPI/Get") from the browser it returns error, resource not found, and the resource it is trying to locate is:
http://localhost:1025/Home/About/api/TestAPI/Get
instead of
http://localhost:1025/api/TestAPI/Get
Why browser added Home/About in the url to api and why it is not added Home/Index when i was on Index view. On Index view why api call is working as expected and why not working on About view ??

You used a relative url when you should be using an absolute url.
You should instead use an absolute url by doing:
$.get("#Url.RouteUrl("#Url.RouteUrl("DefaultApi", new {httproute="", controller="TestAPI", action="Get"}))
If you want to keep your javascript in separate js files (and not in the razor files) what you can do is have an initialize method that is called from a razor view.
The .js file:
var myPageJsUrls = {};
var MyPageInitialize = function(getItemsUrl, saveItemUrl, editItemUrl){
myPageJsUrls.getItemsUrl = getItemsUrl;
myPageJsUrls.saveItemUrl = saveItemUrl;
myPageJsUrls.editItemUrl = editItemUrl;
}
var getItems = function(){
return $.get(myPageUrls.getItemsUrl);
}
...
In the razor file:
<script>
myPageInitialize('#Url.Action("AllItems", "Items")', '#Url.RouteUrl("DefaultApi", new {httproute="", controller="TestAPI"}, ...)
</script>

Related

ASP.NET MVC controller method called via getJson not working on server

Obligatory "This works in my dev environment, but doesn't work on the server."
I have an ASP.NET 5 MVC project, using .NET Core, in which actions taken on a certain view trigger a "getJson" call in my javascript code, which in turn calls a function on the controller to obtain data from the server, in order to update the page without a postback.
When a valid entry is made in a textbox, this function is called in my javascript:
function getCustomerOptions(cn) {
$.getJSON('/Home/GetBillingCustomerByCustNum', { cust: cn }, function (data) {
// handle returned json data
}
}
... which calls function GetBillingCustomerByCustNum in my Home controller:
public async Task<JsonResult> GetBillingCustomerByCustNum(string cust)
{
var data = //[retrieve data from server thru repository function]
return Json(data);
}
In my dev environment, this works great. But after I publish the application to an IIS environment on a Windows Server 2016 machine, this fails. It seems that IIS is trying to call '/Home/GetBillingCustomerByCustNum' as though it were a view or a physical object, and so returns a 404 error.
I have tried altering my getJson controller call -- jquery function "getCustomerOptions" -- by adding
<%= Url.Content("~/") %>
so that the call becomes
$.getJSON('<%= Url.Content("~/") %>/Home/GetBillingCustomerByCustNum', { cust: cn }, function (data) { ...
but that still fails. According to the debugger console, the above url is being translated as
http://localhost/HC_RFQ/Home/%3C%=%20Url.Content(%22~/%22)%20%%3E/Home/GetBillingCustomerByCustNum?cust=[given value]
The only other step I could find suggested I prepare my url with an HTML helper, like so:
var url = '#Url.Content("~/Home/GetBillingCustomerByCustNum/")'
$.getJSON(url, { cust: cn }, function (data) {...
but of course that fails because HTML helpers don't work in separate javascript files. Var url is passed in as literally written.
Finally, I know this is not a case of my javascript files not being linked properly, because I can breakpoint my javascript in the debugger ahead of this failing call, and the breakpoints are hit at runtime.
What else can I try to fix this? Any advice is appreciated.
Have you tried a simple Home/GetBillingCustomerByCustNum, just without the starting /? From how you describe the error in production, that's basically a server issue when composing the final route to the controller.
Dropping the Home/ part works because you're calling that action from a view that resides on the same controller's folder path. Since you're using .NET Core, I suggest using the asp-action and asp-controller tag helpers as they let the server decide what's the actual route to the desired methods, even if you're POSTing or GETing without an actual postbacks. For example, this is what I do using javascript to call my methods on a form:
<form asp-controller="myController" asp-action="myAction">
and this is how I get my js code to retrive the corresponding url
let form = $(this).parents('form')[0];
let url = form.getAttribute('action');
the form doesn't have an actual submit button, so that the calls are all made from javascript.

ASP.NET MVC changed view name

I changed the name of view files (Index.cshtml -> Performance.cshtml), and when I execute the project, the application can't recognise the new view name. I changed the name of an action in controller accordingly (ActionResult Index() -> ActionResult Performance()). However, it keeps saying HTTP 404 error.
When you change your view name mvc application can't find a proper view for it's controller action method.
If it is your default page view( load on application start) than you also need to make changes in your Route_config file.
See the image below Change controller = " Name_of_controller" & action="name_of_action" in your case action name will be Performance.
Always Remember in mvc you can run any method using browser url
for example : controller is home & method is Performance than url will be localhost:port/home/Performance
Change the default route defined in App_Start/RouteConfig.cs file to set Performance as the default action.
Or, you can run the project with the following URL:http://localhost:port/home/Performance

How to pass anti forgery token to react via asp.net mvc?

I call my jsx file via the cshtml like so:
#model viewmodels
#Html.React("CreateStuff", new {
options = Model.KeyValues})
My jsx file contains a form which I'd like to POST back to my controller. However, the controller has a ValidateAntiForgeryToken attribute. How can I pass in the token from mvc land to react??
You should to include in your view this row:
#Html.AntiForgeryToken()

Jquery all ajax calls not picking relative url - ASP.NET MVC

$(document).ready(function () {
getDefaultPDF();
loadPDF();
});
function loadPDF() {
$('#reportsDiv').load("/Review/DisplayPdfPartial");
}
Our site is hosted under the Default website, within a folder. So the url should be
http://servername/foldername/Review/DisplayPdfPartial
but the following code tries to fetch
http://servername/Review/DisplayPdfPartial - doesn't add the foldername and fails obviously.
This doesn't happen on local, only when deployed under default website.
What am I missing?
As you have mentioned you are using Asp.Net MVC then in that case instead of specifying url's this way, a more efficient way is to use #Url.Action() helper method as shown :-
$(document).ready(function () {
getDefaultPDF();
loadPDF();
});
function loadPDF() {
//$('#reportsDiv').load("/Review/DisplayPdfPartial");
$('#reportsDiv').load('#Url.Action("DisplayPdfPartial","Review")');
}
You can use ResolveClientUrl
A fully qualified URL to the specified resource suitable for use on
the browser.
Use the ResolveClientUrl method to return a URL string suitable for
use by the client to access resources on the Web server, such as image
files, links to additional pages, and so on
.

Retrieve URL for Action from Controller

I am calling a Controller Action from a view, within that controller I need to invoke another Action which I will invoke to save the view to a network location as either HTML or Image.
How do I retrieve the URL to an Action from within a Controller. Please note I need the actual URL, this means RedirectionToAction or View() wont work.
Why? I need to pass in a URL which will contain a call to a View. This view will be used to generate an image or HTML document using the System.Windows.Forms.WebBrowser.
.NET 3.5; C#; MVC 1;
I could do something like this, but its dirty ... well it leaves me with that dirty feeling.
using(Html.BeginForm("Action", "MyWorkflowController",
new {
MyId = "bla",
URLToGenerateImage = Url.Action("GenerateImage", "MyWorkflowController")
}))
I ended up using the MvcContrib.UI.BlockRenderer to convert to View to Html instead of generating the image. I proceeded to save the html string to a file system location.
Here is a link for further information
http://www.brightmix.com/blog/how-to-renderpartial-to-string-in-asp-net-mvc/
How about ContentResult - Represents a text result, so you could have
/Controller/GetUrl/id
Public ActionResult GetUrl(int id)
{
// builds url to view (Controller/Image/id || Controller/Html/id)
var url = BuildImageUrl(id);
return ContentResult(url);
}
in view you could have:
GenerateImage

Categories