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

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";
...

Related

How to post an object from MVC controller to Web Api controller?

Scenario is my MVC view is returning data to Controller action and from my action requirement is to build an object and pass it to an external Web API. I m getting data in my action and building an object as well. Can you please direct me how I should pass object to external Web API.
Also should it be JSON, object or xml ?
I m giving my controller and Web API code below:
Controller action:
public ActionResult Submit(FormCollection form)
{
Options lead = new Options();
lead.Situation = form.GetValue("InsuranceFor").AttemptedValue;
lead.State = form.GetValue("InsuranceState").AttemptedValue;
//Here I want to pass object to Web API
return RedirectToAction("Parameters");
}
Web API method:
public void Post(Lead_Options lead)
{
leadOptService.AddListOptions(lead);
}
I just completed a complex implementation just to satisfy similar requirement. I was assigned to post object from C# MVC Controller to an external RESTful Web API. In the future, the Web API will remain, but the C# MVC may be replaced with NodeJS / Angular application. So what I did was, assign the object to a TempData in a Serialized JSON format, then in the View where the page redirects to, conditionally added AngularJS, and implement AngularJS post to the external WebAPI. In your case, the TempData would look something like this:
this.TempData["lead"] = new JavaScriptSerializer().Serialize(this.Json(lead, JsonRequestBehavior.AllowGet).Data);
Then, in the redirected view "Parameters", you could add this angular code:
#if (this.TempData["lead"] != null)
{
<script type="text/javascript" src="#Url.Content("~/Contents/Scripts/angular.js")"></script>
<script type="text/javascript">
angular
.module('app', [])
.controller('controllerName', ['$http', '$scope', 'apiFactory', function ($http, $scope, apiFactory) {
var leadRecord = '#Html.Raw(this.TempData["lead"])';
var apiUrl = 'https://xxxxxxxxxxxxxx';
apiFactory({
method: 'POST',
url: apiUrl + '/api/apiControllerName/Post',
data: '=' + leadRecord,
headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8' }
}).then(function (result) {
console.log(result);
});
}])
.factory('apiFactory', function ($http, $q) {
return function (config) {
var defered = $q.defer();
$http(config)
.success(function (result, status, headers, config) {
defered.resolve(result);
})
return defered.promise;
}
})
</script>
}
<div ng-app="app" class="col-sm-12 sign-in-page">
<div class="row" ng-controller="controllerName">
..... contents of redirected page ....
</div>
</div>
Your WebAPI - (Assuming it's C# Web API 2.2 should look something like this:
[HttpPost]
public string Post([FromBody]string jsonString)
{
try
{
IDictionary<string, string> data = JsonConvert.DeserializeObject<IDictionary<string, string>>(jsonString);
Assuming your object's values are all strings ....
This implementation may not be ideal but it does its job for sure
Oh, alternatively, you could simply add the angular POST to your original view that contains the form controls. But in my case this was not an option because the View must make a full post, the data from the full post must be processed in the model, then the controller gets some of the data from the models and combine it with session information to make up the object, which then has to be sent to a Web API controller..

MVC C# application, Json data in model

This may seem strange, but I would like to have my model contain Json data, which I could then use javascript to render html with the contents. My code looks like the following -
My Controller -
public ActionResult Index()
{
Object myObject = FillMyObjectWithData();
string json = new JavaScriptSerializer().Serialize(myObject);
return View(json);
}
My View -
#model string /*Json data will be in the model*/
<div>
//standard html in here
</div>
<script>
$(document).ready(function() {
doCoolStuff(#Model);
});
</script>
I am getting the error - "Illegal characters in path."
What is the correct way to accomplish this?
The problem is in return View(json);
You are getting the wrong function overload View(string), that is the overload to get a view by name. Try:
return View((object)json);
Also you want the raw JSON without HTML encoding:
doCoolStuff(#Html.Raw(#Model));
Try:
#model string /*Json data will be in the model*/
<div>
//standard html in here
</div>
<script>
$(document).ready(function() {
var temp = #model;
doCoolStuff(temp);
});
</script>
What is your motivation for attempting it this way? If you really want to return json you may be better served making an ajax request after the view/page loads and using javascript/jquery to render your UI with. This would be a good candidate for KnockoutJS.

How to check in for a value in DB through jquery

How can i check in for a value in DB on blur event through jQuery.
I want to display a message if value exist in Data base.
I am using Asp.Net with csharp.
you can call C# function from your jQuery function like --
var isExist = <%=GetValueFromDB()%>;
GetValueFromDB in the codebehind should return a string result and you can check it in your jQuery. I hope this helps.
public string GetValueFromDB()
{
if(value is there)
return "your result";
return "emptystring";
}
Jquery runs on client, so you need to go to the server.
Ajax that calls a WebMethod might work for you
Do a webmethod and then do something along
$('#myInput').onblur(function()
{
$.get('myurl.aspx', {method : 'checkValue', mvalue : $(this).val()},function(data)
{
//handle your response
});
});

MVC 3 - How do you return a Display Template from an action method?

I have a view that displays a list of comments. It does this via the DisplayTemplate. All I have to do is something like #Html.DisplayFor(x => x.BlogPost.PostComments) and all the comments render appropriately.
There is a form at the bottom of the page to add a new comment. This page utilizes progressive enhancement. So if javascript is disabled then the form submits like normal, adds the comment to the database, then redirects to the action that renders the blog post. However, if javascript is available then jQuery hijacks the form's submit and makes the post via ajax. Well because the comment markup is in a display template, I don't know how to return it from the action method so that jQuery can drop it on the page.
I know how to do this with partial views. I would just have the action method return the right partial view and jquery would append the response to the comment container on the page.
Before I go chopping out my display template in favor of a partial view, is there a straight forward way that I'm missing to send back a display template from the controller?
Here is my action method:
public ActionResult AddComment(PostComment postComment)
{
postComment.PostedDate = DateTime.Now;
postCommentRepo.AddPostComment(postComment);
postCommentRepo.SaveChanges();
if (Request.IsAjaxRequest())
return ???????
else
return RedirectToAction("BlogPost", new { Id = postComment.BlogPostID });
}
When the page loads it doesn't need to worry about it because it uses the templates in the standard way:
<div class="comments">
#Html.DisplayFor(x => x.BlogPost.BlogPostComments)
</div>
I just want to know how I might send a single comment that utilizes the display template back to jQuery.
You may try returning the partial HTML representing the newly posted comment:
if (Request.IsAjaxRequest())
{
return PartialView(
"~/Views/Shared/DisplayTemplates/Comment.cshtml",
postComment
);
}
and on the client side append this comment to the comments container:
$.post('#Url.Action("AddComment")', { ... }, function (result) {
$('#comments').append(result);
// or $('#comments').prepend(result); if you want it to appear on top
});
Does this question give you what you are looking for? Seems to indicate that you can call a HTML helper from an action.
Create a partial view /Shared/DisplayTemplate.cshtml with the following razor code:
#Html.DisplayFor(m => Model)
Then in your controller (or preferably in a base controller class) add a method along these lines:
protected PartialViewResult PartialViewFor(object model)
{
return PartialView("DisplayTemplate",model);
}
In the OP's case then:
public ActionResult AddComment(PostComment postComment)
{
postComment.PostedDate = DateTime.Now;
postCommentRepo.AddPostComment(postComment);
postCommentRepo.SaveChanges();
if (Request.IsAjaxRequest())
return PartialViewFor(postComment);
else
return RedirectToAction("BlogPost", new { Id = postComment.BlogPostID });
}

Executing function located in code behind from JavaScript?

I am using ASP.NET 3.5.
In my code behind i have this code that i want to execute from my JavaScript.
Private Sub CreateName()
Dim Name as String
Name = txtName.text
End Sub
And this is my JavaScript Function
<script type="text/javascript">
function doSomething() {
document.elqFormName.action = 'http://now.eloqua.com/e/f2.aspx'
document.elqFormName.submit();
}
</script>
So what must I place inside my JavaScript function to execute my function in my code behind?
Thanks in advance!!
I'm not sure how VB works, but it's similar to C#. I've previously done this by making a WebMethod and using ajax.
Although you could do this using WebMethods as Jimmeh stated, another option would be to use a HTML generic handler. In this approach, your CreateName method wouldn't be in a ASPX page but in a ASHX page.
Check:
http://www.aspcode.net/Creating-an-ASHX-handler-in-ASPNET.aspx
Inside your doSomething method in the javascript part you'd need to call the ASHX using Ajax.
Check:
http://docs.jquery.com/Ajax
I had this same issue, and I found the easiest way to handle it was with an AJAX call. In your ASPX page (javascript):
//======================================
/* This function creates a new instance of an XMLHttpRequest object,
based on the users browser, and returns it */
//======================================
var xmlhttp
function GetXmlHttpObject()
{
if (window.XMLHttpRequest)
{
// code for IE7+, Firefox, Chrome, Opera, Safari
return new XMLHttpRequest();
}
if (window.ActiveXObject)
{
// code for IE6, IE5
return new ActiveXObject("Microsoft.XMLHTTP");
}
return null;
}
//======================================
/* This function issues a request and specifies which function should handle the ajax response */
//======================================
function doSomething()
{
xmlhttp = GetXmlHttpObject();
xmlhttp.onreadystatechange=stateChanged;
var url = "CreateName.aspx"
xmlhttp.open("GET", url, false);
xmlhttp.send(null);
}
//======================================
/* This function handles the ajax response text, places it in a label */
//======================================
function stateChanged()
{
if (xmlhttp.readyState==4)
{
var returned = xmlhttp.responseText;
document.getElementById("lbl_returnStatus").innerHTML = returned;
}
}
And then in the file CreateName.aspx:
<%
'Here is where you can do anything on the server side
Dim Name as String
Name = txtName.text
'This is what will be passed back and handled by the stateChanged function
Response.Write("Success!")
%>
You can also pass parameters through an AJAX call if you need to. Since the type of request we are making is a GET, you can just add the parameters to the URL in Javascript and access them server side with the Request.Querystring("paramName") function.
I wrote a more detailed post on starting AJAX on my blog, here, if you'd like to read that as well. Cheers!

Categories