Constructing URL using HtmlHelper in ASP.NET MVC - javascript

I am trying to construct a URL using a HTML helper extension method while trying pass in parameters to the extension method. For example
public static MvcHtmlString GenerateActionLink(this HtmlHelper html,string displayText,string id,int logicstatusId)
{
var actionName = string.Empty;
var controllerName = string.Empty;
if (logicstatusid == 5)
{
actionName = "Basic";
controllerName = "HighBasic";
}
else
{
action = "Advanced";
controllerName = "HighAdvanced";
}
var targetURL = UrlHelper.GenerateUrl("Default", action, controller, new RouteValueDictionary(new { id = id}), RouteTable.Routes, html.ViewContext.RequestContext, false);
//Create the hyper link tag
var anchorLinkBuilder = new TagBuilder("a");
//Merge the target URL with the href attribute
anchorLinkBuilder.MergeAttribute("href", targetURL);
return MvcHtmlString.Create(anchorLinkBuilder.ToString(TagRenderMode.Normal));
}
While this helper method is working, the problem I am facing is on the client side.
var cellHtml = '<div class="action-column">';
var id= row.encryptedId;
cellHtml += '#Html.GenerateHtmlLink("Blip","'+ id+'" , 4)';
cellHtml += "</div>";
return cellHtml;
In this case the URL is getting constructed but the id parameter is not passing on to the helper method. I am not sure if I have done the passing of the parameter the right way. I'd appreciate if anybody help out.

Your C# code (call to the GenerateActionLink helper method) gets executed in server when razor tries to render the view. At that time the js variable value will not be there. The output of razor executing all the C# code view file is just the html markup which the browser will render. Only after that your javascript will be executed and the js variable value will be avaialble.
If you absolutely need to generate the dynamic url (for each id/logicstatusId value) in your client side javascript code using the UrlHelper method, you might consider exposing that C# code via an action method. Whenever you need the link url in your javascript code, make an ajax call to the action method, pass the parameter value and get the url.
public string GenerateActionLink(string id, int logicstatusId)
{
var actionName = "Advanced";
var controllerName = "HighAdvanced";
if (logicstatusId == 5)
{
actionName = "Basic";
controllerName = "HighBasic";
}
var targetUrl = UrlHelper.GenerateUrl("Default", actionName, controllerName, new RouteValueDictionary(new { id = id }), RouteTable.Routes, Request.RequestContext, false);
return targetUrl;
}
And in client side
var id = 1;
$.get('/Home/GenerateActionLink?logicstatusId=5&id=' + id,function(res) {
var htmlMarkup = 'Blip';
// do something with htmlMarkup
// Ex : $('#SomeDivId').append(htmlMarkup);
});
But if you want to do this for many items, you might not want to make a call for each items, In that case,I would generate the base links and conditionally append the querystring values in javascript
var baseUrlBasic = "#Url.Action("Basic","HighBasic");
// Now later
var id = 1;
var newUrl = baseUrl+'?logicstatusId=5&id='+id;
// Use this to build the anchor tag

Related

How to determine if JavaScript is enabled through MVC

I have a View which calls the function 'Versions' on click of a href, which normally returns a 'Version.cshtml'.
I modified that Controllerfunction:
If i click on that link and JavaScript is enabled, it starts an ajax call which returns a JSON-result. It modifies the DOM so the page won't reload. Now my problem is to differentiate when JavaScript is enabled or not - If enabled, it should return the JSON result; if disabled it should return the 'Version.cshtml'. When I inspect the element, we have already a class called 'nojs-noborder' when JS is disabled. But how can i get that value through the controller without JS so I can fill the bool 'isJavaScriptenabled'?
Controller function looks like this:
if (isJavaScriptEnabled)
{
var tocstr = ControllerContext.RenderView(PartialView("Versiontoc", model));
var middlestr = ControllerContext.RenderView(PartialView("Versionmiddle", model));
var result = new JsonResult
{
Data = new { tocstr, middlestr },
JsonRequestBehavior = JsonRequestBehavior.AllowGet,
MaxJsonLength = MaxValue
};
return result;
}
return View("Version", model);
The class in the inspected element:
<div class="nojs-noborder" id="contentwrapper">
It's unclear from your answer whether you have done this but you need to update your view to make an AJAX request or follow the anchor tag depending on whether JavaScript is enabled or not.
Then, in your controller, you don't need to determine if JavaScript is enabled in the browser, but rather whether the request is an AJAX request. If it is, return JSON else return the view.
Most JavaScript libraries will append the X-Requested-With header with a value of XMLHttpRequest. You can check for the existence of this header.
I'm unsure what version of MVC you are using but you could use the built in Request.IsAjaxRequest() to determine this.
Your ActionMethod then becomes:
if (Request.IsAjaxRequest())
{
var tocstr = ControllerContext.RenderView(PartialView("Versiontoc", model));
var middlestr = ControllerContext.RenderView(PartialView("Versionmiddle", model));
var result = new JsonResult
{
Data = new { tocstr, middlestr },
JsonRequestBehavior = JsonRequestBehavior.AllowGet,
MaxJsonLength = MaxValue
};
return result;
}
return View("Version", model);
If this method isn't available you could roll your own based on this answer

Passing selected value to MVC view [duplicate]

In my form I have a textbox as below
#Html.TextBox("first_name")
I need to pass the value of this textbox to controller through a actionlink.
I tried the below
#Html.ActionLink("View", "view_Details", new { name = first_name})
but this is giving error
"first_name" does not exist in the current context
Is this possible using a Actionlink?
My controller signature is
public ActionResult view_Details(string name)
{
return View();
}
Edited
#Html.ActionLink("View", "view_Details", new { name = getname()})
<script type="text/javascript">
function getname() {
return $("#first_name").val();
}
</script>
I tried above code. Its also giving error
getname() does not exist in the current context
You need javascript/jquery to get the value of the textbox and then update the url you want to redirect to
Html
#Html.ActionLink("View", "view_Details", new { id = "myLink" }) // add id attribute
Script
$('#myLink').click(function() {
var firstname = $('#first_name').val(); // get the textbox value
var url = $(this).attr('href') + '?name=' + firstname; // build new url
location.href = url; // redirect
return false; // cancel default redirect
});
Side note: further to you edit, the reason you receive that error is that razor code (the #Html.ActionLink() is parsed on the server before its sent to the view but getname() is a client side method which does not exist at that point - i.e it does not exist in the current context

Can I get the url parameters in html when I use webview.loadUrl()?

Here is my code:
private WebView mWebView;
String testValue="hello";
mWebView.loadUrl("http://192.168.64.13:8079/ctms-logistics/demo.html?test="+testValue);
and I want to get the value of parameter "test"(which is the value of variable testValue) from the url in my demo.js which included in demo.html, how? I know in browser we can use window.location.hash to get the url, but it doesn't work in webview.
You can have the function inside your js which will accept these parameters. And call that function from activity as shown below
mWebView.loadUrl("http://192.168.64.13:8079/ctms-logistics/demo.html?test="+testValue);
mWebView.setWebViewClient(new WebViewClient() {
public void onPageFinished(WebView view, String url)
{
mWebView.loadUrl("javascript:setTestValue("+testValue+")");
}
});
I have found the answer for my question, it is that use window.location.href to get the url from webview.loadUrl, and then parse that url to get the parameter I want. it is like this:
function getParamHref(paramName) {
var href = window.location.href;
var search = href.substr(href.indexOf("?") + 1, href.length);
var reg = new RegExp("(^|&)" + paramName + "=([^&]*)(&|$)", "i");
var r = search.match(reg);
if (!isUndeFinedOrNull(r)) return unescape(r[2]);
return null;
}
if I want to get the parameter "test" from the url, then I can call the method getParamHref("test") at the begining of my demo.js file.

$http Call to Web API 2 Not Passing Parameter

This is my C# WebAPI2 controller, which gets hit:
[HttpGet, Route("bycaseidlist/{idArray}")]
public async Task<IHttpActionResult> GetByCaseIdList([FromUri] List<int> idArray)
This is the call:
var idArray = [4,4,2,4];
var url = baseUrl + 'api/cases/bycaseidlist/' + idArray ;
$http.get(url)
The problem is that the API doesn't get the array, it gets ...this:
In other words an array with one value: 0. Why is this happening? How do I fix it? It seems to be in-line with this answer, but it doesn't work. Should I pass it in the body? I feel like I am missing something obvious.
Get ActionMethods can take objects as arguments. However, the default behavior is to look at the body when the parameter is not a .net primitive. In order to force the action method to use a model binder to read the object data from the request, the parameter can be decorated with the [FromUri] or [ModelBinder] attributes. (Note there are other ways to do this that include doing parameter binding rules but that is probably overkill for what you are trying to accomplish here). Here is an implementation that solves the original problem that you were posing.
<script type="text/javascript">
var ajaxCall = function (myArry) {
var ajaxProperties = {};
ajaxProperties.url = "/api/Mul/Mutiply";
ajaxProperties.type = "Get";
ajaxProperties.data = {};
ajaxProperties.data.numbers = myArry;
ajaxProperties.contentType = "application/json";
console.log(ajaxProperties);
ajaxProperties.success = function (data) {
console.log(data);
}
ajaxProperties.error = function (jqXHR) {
console.log(jqXHR);
};
$.ajax(ajaxProperties);
};
var getData = function (e) {
var myArry = new Array();
myArry.push($('input[name=num1').val());
myArry.push($('input[name=num2').val());
ajaxCall(myArry);
return false;
};
</script>
Controller
[HttpGet]
public IHttpActionResult Multiply([FromUri] int[] numbers)
{
int result = 0;
if(numbers.Length > 0)
{
result = 1;
foreach (int i in numbers)
{
result = result * i;
}
}
return Ok(result);
}
}
I think my mistake was using Get. I might be remembering incorrectly (someone confirm if you know offhand), but Get might not be able to take objects as arguments. Anyway, I changed the method to POST and then changed the param to be sent in the request body, rather than the url. It now works. Here is the working code:
[HttpPost, Route("bycaseidlist")]
public async Task<IHttpActionResult> PostByCaseIdList([FromBody] int[] sqlCaseIdArray)
and the call itself:
function runDbCall(url, sqlCaseIdArray){
return $http({
method: 'POST',
url: url,
data: sqlCaseIdArray
});
}
runDbCall(url, sqlCaseIdArray)
I will come back to this when I figure out if the problem was Get not being able to take objects, but I thought it could in url, just not in body...need to clarify. If someone posts an answer just on that part, I will accept, since that's probably the root of the prob.

Use URL based on razor method

I want to redirect to particular page.
For that I am using some Javascript function in MVC project as::
function rootUrl(url) {
var _rootUrl = '#Url.Content("~")';
var x = url;
if (url.indexOf(_rootUrl) != 0) {
x = _rootUrl + "/" + url;
x = x.replace(/\/\//g, "/").replace(/\/\//g, "/");
}
return x;
};
which is being used as ::
var url = rootUrl("Home/Company/") + $(this).val();
window.location.href = url;
But I am getting wrong URL in my browser as::
http://localhost:60294/Home/Company/#Url.Content(%22~%22)/Home/Company/7
Why not use Url.Action() directly which gives you url relative to root directory, instead of creating a javascript messy function:
var url = '#Url.Action("Company","Home")' + $(this).val();
Here,Home is the name of Controller and Company is the action of it
You can't access razor in Js file. When I need the urls from Razor in Js I just define them in the view, like:
<script>
var _rootUrl = '#Url.Content("~")';
</script>
This will work

Categories