Retrieving params from url with c# and angular - javascript

I am having issues retrieving parameters from my URL that is an API. Any
help would be greatly appreciated.
Here is my c# code
[Route("api/[controller]")]
public class PasswordController : Controller
{
private readonly AppSettings _options;
public PasswordController(IOptions<AppSettings> optionsAccessor)
{
_options = optionsAccessor.Value;
}
[HttpGet]
//this isnt returning anything...
public IActionResult Get([FromQuery]string emp)
{
var x = HttpContext.Request.Query["emp"].ToString();
Response.Headers.Add("x-emp-name", x);
return Json(_options.ClientSettings);
}
Here is my angular code ts
private GetData(): void {
this.http.get('api/password').subscribe(values => {
this.ViewOptions = values.json();
this.titleService.setTitle(this.ViewOptions.changePasswordTitle + " -
" + this.ViewOptions.applicationTitle);
if (this.ViewOptions.recaptcha.isEnabled) {
this.FormGroup.addControl('reCaptcha', new FormControl('',
[Validators.required]));
const sp = document.createElement('script');
sp.type = 'text/javascript';
sp.async = true;
sp.defer = true;
sp.src =
'https://www.google.com/recaptcha/api.js?onload=vcRecaptchaApiLoaded&render=explicit&hl='
+ this.ViewOptions.recaptcha.languageCode;
}
});
}
Here is my browser console screenshot

You can pass a parameter into your method:
private GetData(queryParam): void {
this.http.get('api/password?emp=' + queryParam).subscribe(values => {
this.ViewOptions = values.json();
///code omitted
note: I don't know the exact syntax for TypeScript parameters so this probably isn't copy/paste-able.

So as I understand your question, you try to call the api/password endpoint with the get parameter ?emp=Test from within an angular web app.
As I see you don't call the endpoint with the parameter but call the whole angular app with the parameter. So my suggestion was to call
this.http.get('api/password?emp=Test').subscribe
from the typescript code.

Related

How to pass special character in query string in .Net core API?

Net core application. I have one GET api as below:
[HttpGet]
[Route("configId={configId}&quoteId={quoteId}"), EnableQuery()]
public async Task<IEnumerable<Scenario>> GetScenario(string configId, int quoteId)
{
var result = await configScenarioService.GetScenarioAsync(configId, quoteId);
if (result.IsSuccess)
{
return result.scenarioResults;
}
return new List<Scenario>();
}
I am trying to hit from Postman as below:
https://localhost:44362/api/v1/Scenario/configId=JBEL+ASS_60_SG_5.2-145_MY21_T102.5_25y&quoteId=236
Unfortunately, this is giving 404 error. Maybe the '+' sign is causing the issue. After looking into some documentation, I tried as below:
1. https://localhost:44362/api/v1/Scenario/configId="+ encodeURIComponent(BEL+ASS_60_SG_5.2-145_MY21_T102.5_25y) +"&quoteId=236
This didn't work for me and still gave a 404 error.
How can this be fixed?
Try this
[HttpGet]
[Route, EnableQuery()]
public async Task<IEnumerable<Scenario>> GetScenario([FromQuery(Name = "configId")]string configId, [FromQuery(Name = "quoteId")]int quoteId)
{
since you have + sign you have to encode your url, for + url encoded is
%2B https://www.w3schools.com/tags/ref_urlencode.asp
..../Scenario?configId=JBEL%2BASS_60_SG_5.2-145_MY21_T102.5_25y&quoteId=236
and since you have 404 you have to fix an action route too
[Route("~/api/v1/Scenario")]
public async Task<IEnumerable<Scenario>> GetScenario([FromQuery] string configId, [FromQuery] int quoteId)
Then try this:
[ApiController]
[Route("api/v1/[controller]/[action]")]
public class YourController : ControllerBase
{
//... ctor and your other stuff
[HttpGet("{configId}/{quoteId}", Name = "Scenario")]
[ProducesResponseType(typeof(IEnumerable<Scenario>)]
public async Task<ActionResult<IEnumerable<Scenario>>> GetScenario(string configId, string quoteId)
{
}
}
what worked is const urlEncode = encodeURIComponent(encodeURIComponent(configId)) but still i am unable to figure it why i should use encodeURIComponent(encodeURIComponent) in my js

Pass a value to my controller with $.get() javascript to my controller method

Here is my goal:
I'm trying to display the details of an event in my modal.
For that, I execute a javascript script which returns to the "GetEventsDetails" method of my "Event" controller with the id of the event.
When I debug with Chrome, I see the id pass except that in my controller, the value is always 0.
I do not really understand why, I checked a lot on the net and everything seems right on my side!
Is it because I do not use an ajax call?
Thank you in advance!
function GetEventsDetails(id) {
//$('#myModal').find('.modal-title').text("Details ");
$.get("#Url.Action("GetEventsDetails", "Events")/" + id,
function (data) {
$('.modal-body').html(data);
})
$('#myModal').show();
}
</script>
}
[Authorize]
[HttpGet]
public async Task<ActionResult> GetEventsDetails(int Zkp)
{
ViewBag.sessionv = HttpContext.Session.GetInt32("idMember");
FileMakerRestClient client = new FileMakerRestClient(serverName, fileName, userName, password);
var toFind = new Models.EventsLines { Zkp = Zkp };
var results = await client.FindAsync(toFind);
bool isEmpty = !results.Any();
if (isEmpty)
{
return View();
}
Models.EventsLines oEventViewModel = new Models.EventsLines();
oEventViewModel = results.ToList().First();
Console.WriteLine(oEventViewModel);
return PartialView(oEventViewModel);
}
<script>
function GetEventsDetails(id) {
//$('#myModal').find('.modal-title').text("Details ");
var urlpath = "/ Events / GetEventsDetails /" + id;
$.get(urlpath, function (data) {
$('.modal-body').html(data);
});
$('#myModal').show();
}
</script>
And Your Controller
public async Task<ActionResult> GetEventsDetails(int id)

MVC 6 Change where a view block renders

My goal is to create an analog to the razor #section Scripts {...} syntax that will work equally well in Views and ViewComponents.
I can do this via helper methods if I convert the JavaScript to a windows string. However, this destroys intellisense, puts you into character escaping hell and doesn't allow you to de-dup and order the scripts just prior to rendering.
I'd like to make this work in a way that allows the Visual Studio Editor to edit the JavaScript as JavaScript. It seems like I should be able to do something like this:
<div class="StatsDisplay">
label id="#labelId">#Model.DisplayFormat</label>
</div>
#using (Html.BeginNamedScript($"StatDisplay{Model.UniqueId}"))
{
<script>
$.ajax({
url: "#Model.ResultUrl",
method:"POST"
})
.done(function (value) {
var statText = "#Model.DisplayFormat".replace(/\{\s * 0\s *\}/, value);
$("##labelId").text(statText);
});
</script>
}
HtmlHelperExtension:
public static NamedScript BeginNamedScript(this IHtmlHelper htmlHelper, string name, params string[] dependancies)
{
return new NamedScript(htmlHelper.ViewContext, name, htmlHelper, dependancies);
}
And class NamedScript:
using System;
using System.Diagnostics;
using System.IO;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.Mvc.ViewFeatures;
namespace WebUIB8.Helpers
{
public class NamedScript : IDisposable
{
private bool _disposed;
private readonly FormContext _originalFormContext;
private readonly ViewContext _viewContext;
private readonly TextWriter _writer;
private readonly string _name;
private readonly HtmlHelper _helper;
private readonly string[] _dependsOn;
public NamedScript(ViewContext viewContext, string name, params string[] dependsOn):this(viewContext, name, null, dependsOn)
{
}
internal NamedScript(ViewContext viewContext, string name, IHtmlHelper helper, params string[] dependsOn)
{
if (viewContext == null)
{
throw new ArgumentNullException(nameof(viewContext));
}
_name = name;
_dependsOn = dependsOn;
_helper = helper as HtmlHelper;
_viewContext = viewContext;
_writer = viewContext.Writer;
Debug.WriteLine("Beginning:\r\n" + _viewContext);
_originalFormContext = viewContext.FormContext;
viewContext.FormContext = new FormContext();
Begin();
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
public void Begin()
{
//No beginning action needed
}
private void End()
{
Debug.WriteLine("Ending:\r\n" + _writer);
//NOTE: This chunk doesn't work
//This is supposed to render the script to a string and
// pass it to the helper method that accumulates them, orders
// them, dedups them, and renders them at the proper location
// in the _Layout file so JavaScript loads last, and in dependancy order.
_helper?.AddJavaScript(_name, _writer.ToString(), _dependsOn);
}
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
_disposed = true;
End();
if (_viewContext != null)
//NOTE: This chunk doesn't work either.
//This is supposed to prevent the code from rendering here.
_viewContext.FormContext = _originalFormContext;
}
}
public void EndForm()
{
Dispose(true);
}
}
}
I've tried the below to render the script to string, but it throws an exception inside the .RenderAsync call and aborts the page with a 503.2 error:
private async Task<string> RenderView(ViewContext viewContext)
{
using (var sw = new StringWriter())
{
var newViewContext = new ViewContext(viewContext, viewContext.View, viewContext.ViewData, sw);
var razorView = newViewContext.View as RazorView;
razorView.RenderAsync(newViewContext).Wait();
sw.Flush();
return sw.ToString();
}
}
Am I missing a simpler solution? Is there an easier way to render the result of Razor markup and pass it into an html helper method?
How can I render the ViewContext of inside the #using block into text?
How can I prevent that ViewContext from rendering with the rest of it's view? (So that I can render it later on the page)
You can implement this behavior using tag helpers.
Let's say you create a tag helper InlineScriptConcatenatorTagHelper targetting the <script> tag, where you basically remove its contents from the output but keep them in memory for later use:
[HtmlTargetElement("script", Attributes = "inline-bundle-add")]
public class InlineScriptConcatenatorTagHelper: TagHelper
{
private IHttpContextAccessor httpContextAccessor;
public InlineScriptConcatenatorTagHelper(IHttpContextAccessor httpContextAccessor)
{
this.httpContextAccessor = httpContextAccessor;
}
[HtmlAttributeName("inline-bundle-add")]
public string BundleName { get; set; }
public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
{
//Get the script contents
var contents = await context.GetChildContentAsync();
var scriptContent = contents.GetContent();
//Save them into the http Context
if (httpContextAccessor.HttpContext.Items.ContainsKey(BundleName))
{
var scripts = httpContextAccessor.HttpContext.Items[BundleName] as ICollection<string>;
scripts.Add(scriptContent);
}
else
{
httpContextAccessor.HttpContext.Items[BundleName] = new List<string> { scriptContent };
}
//suppress any output
output.SuppressOutput();
}
}
You can then create a similar tag helper InlineScriptTagHelper where you will basically concatenate and render all the contents you collected from the previous helper:
[HtmlTargetElement("script", Attributes = "inline-bundle-render")]
public class InlineScriptTagHelper : TagHelper
{
private IHttpContextAccessor httpContextAccessor;
public InlineScriptTagHelper(IHttpContextAccessor httpContextAccessor)
{
this.httpContextAccessor = httpContextAccessor;
}
[HtmlAttributeName("inline-bundle-render")]
public string BundleName { get; set; }
public override void Process(TagHelperContext context, TagHelperOutput output)
{
//if no scripts were added, suppress the contents
if (!httpContextAccessor.HttpContext.Items.ContainsKey(BundleName))
{
output.SuppressOutput();
return;
}
//Otherwise get all the scripts for the bundle
var scripts = httpContextAccessor.HttpContext.Items[BundleName] as ICollection<string>;
//Concatenate all of them as set them as the contents of this tag
output.Content.SetContentEncoded(String.Join("", scripts));
}
}
With this in place, you could add as many script blocks in your views and assign them an inline bundle name:
<script inline-bundle-add="myInlineBundle">
var title = '#ViewData["Title"]';
var greet = function (message) {
console.log(message);
}
</script>
...
<script inline-bundle-add="myInlineBundle">
greet(title);
</script>
Then add a single script element in your _Layout.cshtml that will render the concatenated output of all the inline scripts with the same bundle name:
...
<script inline-bundle-render="myInlineBundle"></script>
</body>
The rendered output will contain a single script element concatenating all the scripts you included in the inline bundle:
...
<script>
var title = 'Home Page';
var greet = function (message) {
console.log(message);
}
greet(title);
</script>
</body>
DonĀ“t forget to register the tag helpers in your assembly by adding a #addTagHelper directive to the _ViewImports.cshtml file
EDIT
Check out the github project created by #SvdSinner. It has taken the approach described here and created a tag helper that supports deduplication and dependency ordering. (With the aim of supporting minification and provide a nuget package)

I want to pass value to AngularJS method in controller from android

Hello I want to Pass value to method defined in controller in AngularJS from Webview Controller android. I am sending my code please check. Thanks in Advance.
myBrowser = (WebView) findViewById(R.id.mybrowser);
client = new WebChromeClient();
final MyWebClient myJavaScriptInterface = new MyWebClient(this);
myBrowser.addJavascriptInterface(myJavaScriptInterface, "AndroidFunction");
myBrowser.setWebChromeClient(client);
myBrowser.getSettings().setJavaScriptEnabled(true);
myBrowser.loadUrl("file:///android_asset/angularjsandroid.html");
myBrowser.loadUrl("javascript:callFromActivity1(\'" + json+ "\')");
JS code
function personDetail($scope) {
$scope.getPersonDetail = function() {
var jsonString = JSON.stringify($scope.data);
showAlert(jsonString);
};
$scope.updatePersonDetail = function(details){
AndroidFunction.getJSONData($scope.id);
};
$scope.callFromActivity1 = function(msg) {
alert(msg);
};
});
Yes, got it that way indeed :
var angular_scope = angular.element($("#main_content")).scope();
And then you do whatever you want with it

GWT Native Method Warning

I'm doing a project in GWT to deploy in AppEngine and I'm getting a warning in Eclipse saying:
JavaScript parsing: Expected an identifier in JSNI
reference
Any ideas on what's causing this?
public void callFacebookAPI(String url) {
JsonpRequestBuilder requestBuilder = new JsonpRequestBuilder();
requestBuilder.requestObject(url, new AsyncCallback<FbUser>() {
public void onFailure(Throwable caught) {
System.out.println("FAIL" );
}
#Override
public void onSuccess(FbUser result) {
facebookUser = result;
System.out.println("Facebook name:" + facebookUser.getName());
}
});
}
private final native void doFbLoginFunction() /*-{
FB.login(function(response) {
if (response.authResponse) {
// connected
//return response.session;
var accessToken = response.accessToken;
var url = "http://graph.facebook.com/me?access_token=";
var facebookUrl = url + accessToken;
#com.google.gwt.smartpark.client.map.SmartPark::callFacebookAPI(Ljava/lang/String;Ljava/lang/
String;)(facebookUrl);
} else {
// cancelled
}
});
callFacebookAPI is not static so there must be something before the # in the reference in JSNI, e.g.
var that = this;
$wnd.FB.login($entry(function(response) {
// ...
that.#com.google.gwt.smartpark.client.map.SmartPack::callFacebookAPI(Ljava/lang/String;)(facebookUrl);
// ...
}));
Also, your callFacebookAPI takes a single argument, so the JSNI signature should have a single Ljava/lang/String;.

Categories

Resources