Call function from cshtml to cshtml.cs using Models - c#

I am new to asp.net core and Razor, i am trying to call a function from cshtml page to his inner cs page:
<button onclick="#{Model.GetUserInfo(1);};" type="submit">Search</button>
cshtsml.cs
public UserInfo GetUserInfo(int userId)
{
using (var client = new HttpClient())
{
var response = client.GetAsync($"localhost:44322/api/User/user/{userId}{userId}");
var body = response.Result.Content.ReadAsAsync<UserInfo>().Result;
return body;
}
}
I would like to get the information back from the api and display the information that i received.
With this code if i put { } around the Model.GetUserInfo(1); it doesn't display the button, without the { } it just doesn't compile.
Any of you can help me with it? thanks.

Step 1 - You can write a javascript function which will send an ajax request to your controller method
Step 2 - Return the data you want from this method
Assuming your controller name is Home, you can do something like this-
<button onclick="GetData()" type="submit">Search</button>
function GetData() {
$.get("/Home/GetUserInfo", function (data) {
// Here put what do you want from received data
});
}

Related

Ajax post to update model and reload page failing, controller receives empty model

I'm working on an asp.net core application. There is a settings page that is initially empty. The user can then update the settings by selecting a json file. These settings are then confirmed and sent to the controller. The controller should return the same page but displaying the updated settings.
The file is being read and sent to the controller, it is then correctly being deserialized into a settings object and stored in the session.
I have tried using a GET for updating the settings but the query string is too long.
This is the form the user submits, it's part of a dialog that is shared between multiple different functions so is very generic.
<form method="post">
<button type="submit" class="btn btn-primary" id="modalSubmitButton">Okay</button>
</form>
After the user chooses a file the content of it is retrieved and an event handler is set for the above button.
function OpenFile(event) {
const input = event.target
if ('files' in input && input.files.length > 0) {
var file = (event.target.files)[0];
var fileReader = new FileReader();
fileReader.onload = (function (file) {
return function (e) {
var contents = e.target.result;
document.getElementById("modalHeading").innerHTML = "Please confirm overwrite";
document.getElementById("modalSubmitButton").addEventListener("click", function (e) {
LoadSettings(contents);
});
$("#dialog").modal('show');
};
})(file);
fileReader.readAsText(file);
}
}
Adding this to the click event makes the controller only called once (but with null for the model)
e.preventDefault();
e.stopPropagation();
e.stopImmediatePropagation();
return false;
The ajax call to call the controller when the button is clicked.
function LoadSettings(settings) {
data = JSON.stringify(settings);
$.ajax({
type: "POST",
data: data,
url: "https://localhost:44365/Site/LoadSettings",
contentType: "application/json; charset=utf-8"
})
}
This is the function that is called, there are two different settings pages depending on the json.
[HttpPost]
public void LoadSettings([FromBody]SiteSettings config)
{
HttpContext.Session.SetObject("config", config);
if (config.Config.Count < 2)
{
return Settings();
}
return MultiSettings();
}
Which calls this (the controller function responsible for this page).
[HttpGet]
public IActionResult Settings()
{
var config = HttpContext.Session.GetObject<SiteSettings>("config");
Model = new SettingsViewModel();
if (config != null)
{
Model.Config = config;
}
return View(Model);
}
That constructor takes the settings json and deserializes it.
public SiteSettings Config { get; set; }
public SettingsViewModel(string settingsConfig)
{
try
{
Config = JsonConvert.DeserializeObject<SiteSettings>(settingsConfig);
}
catch (Exception ex)
{
Config = new SiteSettings();
}
}
I am getting a 415 error when calling this using Ajax. I am able to make a POST and send the settings via Postman and receive the page with the updated settings. Looking at it in Fiddler the function is called twice, the first with the json and the second without.
In Fiddler the first request has the 'Session was aborted by the client, Fiddler or the server' icon.

How do I pass multiple objects from a ViewModel to a jQuery function?

I am coding a MVC 5 internet application and would like to know how to pass values from a ViewModel into a jQuery function where I have a list of data to pass.
Usually, I would create a hidden field in the MVC View code, and then retrieve this value in the jQuery code. However, in this situation, there is not just one value from the ViewModel, but a List of objects, where each object has many values.
My ViewModel has a List<MapMarker>, where each MapMarker has the following attributes:
latitude
longitude
title
draggable
This is the jQuery function that I need to call for each MapMarker object:
function LoadMapMarker(latitude, longitude, title, draggable)
How can I call the LoadMapMarker function, with data from each of the MapMarker objects in the ViewModel list?
Thanks in advance
You can serialize your list and storage it in a hidden field. Then call LoadMapMarker by means of Javascript on client side.
Server:
using System.Web.Script.Serialization;
var MapMarkers = new List<MapMarker>();
var jsonSerialiser = new JavaScriptSerializer();
var json = jsonSerialiser.Serialize(MapMarkers);
return View(new MyViewModel({JsonList = json }));
View:
<input type="hidden" id= "MyHiddenFieldForMapMarker" value="#Model.JsonList" >
Client:
var MapMarkers = $("#MyHiddenFieldForMapMarker").val();
for (var MapMarker in MapMarkers) {
LoadMapMarker(MapMarker["latitude"],
MapMarker["longitude"],
MapMarker["title"],
MapMarker["draggable"]);
}
You can serialize to JSON and then store in a hidden field, or as a Javascript object like :
myJsonData= [{"id":"15aea3fa","firstname":"John","lastname":"Doe"}];
Alternatively, you can retrieve the data via an ajax call.
If you don't want to use JSON and use the data you have on your page you can do this:
You can add class (or some other attribute, for me it is easier to use classes, but it is better "programming" to use another attribute)
#foreach ()...
{
<div class="main_Marker">
<input ... class="lat"/> //using the #Model render ofc...
<input ... class="long"/>
</div>
}
Then jQuery:
$("main_Marker").each(function(index, item)) {
var lat = $(item).child(".lat");
.
.
LoadMapMarker(lat, long....);
}
If your jQuery function is present in a view, use #Html.Raw(Json.Encode(Model.JSonData)) like this
//JavaScript or jQuery function
function javascriptFunction()
{
var data = #Html.Raw(Json.Encode(Model.JSonData))
}
In the above code, JSonData is the name of the collection variable that contains data from model. In your case a List.
If your jQuery function is in a separate JavaScript file, then an AJAX request can be used to get the data from model
Controller Code
public ActionResult GetData()
{
//Your logic to get data from model
//Here data is the variable that holds the collection List<MapMarker>
return Json(data);
}
JavaScript Code for AJAX Request
function myJavaScriptFunction()
{
$.ajax({
url: '/GetData',
type: 'post',
success: function (data) {
alert("data retrieved successfully");
},
error: function () {
alert("Error retrieving data");
}
});
}

How to make Angular POST to C# Asp.Net MVC Controller?

I have looked around, but have not found anything (Angular post) that can actually make a successful call to a MVC Controller. I know there are a lot of Angular/.Net devs out there. Can I get some help?
Let's keep answers bare bones simple!!!
If I set a linebreak on the controller, I can see that this code is not actually hitting the controller.
HTML
<!-- I click this button -->
<input type="button" value="click" onclick="postit()" />
Javascript/Angular Post
function postit() {
$http({
method: 'POST',
url: 'Home/Give/',
data: { id: 4 }
}).success(successFn).error(errorFn);
}
function successFn() {
alert("success");
}
MVC C# Controller
[AcceptVerbs("OPTIONS")]
public ActionResult Give(int id)
{
var response = "some response" + id.ToString();
return Json(new JavaScriptSerializer().Serialize(response));
}
king Puppy, I've seen a few responses that dictate that the controller parameters should be an object that matches the object that is being sent, however, it seems that it's a little more forgiving than that. Consider the following example (I've updated your function a little):
Javascript:
$scope.postIt = function() {
var data = {
id = 4
};
$http
.post('Home/Give', data)
.success(function(data, status, headers, config) {
successFn();
})
.errors(function(data, status, headers, config) {
errorFn();
});
};
function successFn() {
alert("success");
};
function errorFn() {
alert("error");
};
MVC:
public ActionResult Give(int id)
{
var response = "some response" + id.ToString();
return Json(new JavaScriptSerializer().Serialize(response));
}
If you set a breakpoint, you will see that the id passed in is 4.
If you needed to pass in an object (so more than just one id), you could either create a matching class or struct on the controller side, or have multiple parameters (provided that they are simple value types)
ie:
public JsonResult Give (int id, int reasonId)
{
...
}
Anyway, I realize the post is old, but perhaps it will help you or others.
#kingPuppy this is my way to how to make angularjs post to mvc controller
first, html button for passing the angular js button click function;
<button class="btn btn-info" id="runButton" ng-click="runService('Hi')">Run</button>
so runService angular click (ng-click) function;
// Operation Type is my mvc controller's param
$scope.runService = function (optionType) {
$http({
url: '/System/RunService',
method: "POST",
data: {operationType : optionType}
}).then(function onSuccess(response) {
// Handle success
console.log(response);
}).catch(function onError(response) {
// Handle error
console.log(response);
});
}
And finally this is system controller's action;
NOT : Dont forget to [HttpPost] attribute
[HttpPost]
public ActionResult RunService(string operationType)
{
// Codes
Response.StatusCode = 200;
return Json(JsonRequestBehavior.AllowGet);
}
Hope this could help to you for how to make angular post to mvc controller. Thanks.
There is nothing special you have to do to get Angular to post to a standard MVC controller, and in fact I have several Angular/MVC apps that are using code almost identical to what you have above to POST to controllers that work fine.
I would use Firebug to confirm that your app is posting to the right place. One thing I noticed is that you might not want that trailing / at the end of your URL (so Home/Give instead of Home/Give/)
Good luck!

Redirect after Ajax

I have a mvc project, what I want to do is this:
I am sending an ajax request from my JS script. After processing it I want to redirect to a page with a model.
Now I tried sending a form as the ajax response and submit it like so:
sb.Append("<html>");
sb.AppendFormat(#"<body onload='document.forms[""form""].submit()'>");
sb.AppendFormat("<form name='form' action='{0}' method='post'>", "url..");
sb.AppendFormat("<input type='hidden' name='result' value='{0}'>", val1);
.....
And on the JS:
success: function (result) {
var form = $(result);
$(form).submit();
}
But this way i need to specify each post param, I want to send the entire model object.
How can I do that?
Edit
Full steps:
1.Using an MVC APP.
2.I submit button in my view which redirects the user to my JS code.
3.Js code sends an Ajax request to a MVC page called 'Transaction'.
4.C# code doing some actions and now I need to redirect the usr to a page named EOF with ALOT of post params, thats why I want to pass it as a ViewModel.
As you are using ajax, you could return the URL from your action and have it redirected in javascript:
Controller
public ActionResult Transaction()
{
// Do stuff
return Json(new { success = true, redirecturl = Url.Action("RedirectedAction") });
}
Then add something like this to your success handler in javascript:
Javascript (within your success handler)
success: function (result) {
if (result.success == true)
{
window.location = result.redirecturl;
}
}
You can try this:
public ActionResult YourMethod(string param)
{
//what ever you want to do with reference no
return View("EOF");
// or, if you want to supply a model to EOF:
// return View("EOF", myModel);
}

C# how to call MVC action and assign result to js variable

I've been trying to achieve the following:
Call my action (which returns json):
#{ var response = Html.Action("Login", "Auth"); }
And assign my json response to a global javascript variable:
<script type="text/javascript">
var response = #response;
user = response.details;
</script>
However I can't seem to get this to work the way I need it to. The response is not assigned appropriately. Is there an action call which returns json? I know I could use ajax for this, but that's not a valid option since i have to set the global variable before the document.ready is called.
Any tips appreciated...
Kind regards
You can use JavaScriptResult directly. See MSDN Doc
public JavaScriptResult Example()
{
return new JavaScript("var response = 10");
}
Useful liks related to
How to use Asp.net mvc JavaScriptResult practically
Working example for JavaScriptResult in asp.net mvc
Beware of ASP.NET MVC JavaScriptResult
But I would suggest you to Use $.getJSON() or $.Ajax() instead
Use $.getJSON(), $.post(), $.Ajax() instead, if you want JSON response back
Instead of trying to use Html.Action like a method call, use Html.RenderAction and use that action to dump any necessary JavaScript to your page. e.g.
AuthController.cs
public class Auth : Controller
{
/* snip */
[ChildActionOnly]
public ActionResult Login()
{
return View(/* model? */);
}
}
~/Views/Auth/Login.cs
<script>
var auth = #whateverinformation;
</script>
Original View
#{ Html.RenderAction("Login", "Auth"); }
<script>
user = auth.details;
</script>
Now /Auth/Login can be placed on any page and the content is included at a server level (instead of supplementary with AJAX)
And if that doesn't do it for you, think about making an HTML helper that displays the information instead of trying to use a controller action like a normal method. Something like:
public static IHtmlString Auth_Login(Htmlhelper htmlhelper)
{
String response;
/* assign response */
return new HtmlString(response); /* or maybe MvcHtmlString */
}
Implemented:
<script>
var response = #Html.Auth_Login();
user = response.details;
</script>
You may check the Channel9 discussion on Evolving Practices in Using jQuery and Ajax in ASPNET MVC Applications.
You may also check the SO question on asp.net MVC3 and jquery AJAX tutorial
You should use quotes
<script type="text/javascript">
var response = "#response";
...

Categories