I read this and tried to implement the ViewDataDictionary in my app but did not work.
In my view, I've the below code:
#{
var myTest = new
{
UserId = "cdb86aea-e3d6-4fdd-9b7f-55e12b710f78",
UserName = "iggy",
};
}
#Html.Partial("~/Partials/test.cshtml", myTest)
and the test.cshtml is very simple, when I write #Model, I get { UserId = cdb86aea-e3d6-4fdd-9b7f-55e12b710f78, UserName = iggy }
How can I extract this as JSON, so I can read #Model.UserName
I tried using:
<script type="text/javascript">
#
{
<text>
var obj = JSON.parse(#Model);
</text>
}
</script>
and tried:
<script type="text/javascript">
#:var obj = JSON.parse(#Model);
</script>
and tried:
#Html.Raw(Json.Encode(object))
but nothing worked, any help!!
I came across similar problem when I was converting my .net application into .net core.
In .net I could just return Json(jsonModel) in my controller and use it in my view as data.UserID, data.UserName (see code below adjusted to match your sample).
In .net core I had to SerializeObject in my controller first and then use JSON.parse in the view javascript section to make it work.
The following works in .NET CORE. Assuming you have some model:
public class SomeModel
{
public string UserId { get; set; }
public string UserName { get; set; }
}
in your controller return Json object:
using Newtonsoft.Json;
[HttpPost]
public IActionResult someAction()
{
SomeModel jsonModel = new SomeModel();
jsonModel.UserId = "cdb86aea-e3d6-4fdd-9b7f-55e12b710f78";
jsonModel.UserName = "iggy";
var serializedJsonModel = JsonConvert.SerializeObject(jsonModel);
return Json(serializedJsonModel);
}
and in your view javascript section you can retrieve values from your model:
<script type="text/javascript">
$.post("#Url.Action("someAction", "YourController")",
function (data) {
var oJson = JSON.parse(data);
UserId = oJson.UserId;
UserName = oJson.UserName; });
</script>
If you're only interested in JSON serialization of your anonymous type, you can simply declare the #model of the partial as object.
In your main view:
#{
var myTest = new
{
UserId = "cdb86aea-e3d6-4fdd-9b7f-55e12b710f78",
UserName = "iggy",
};
}
#Html.Partial("~/Partials/test.cshtml", myTest)
And in your test.cshtml partial:
#model object
<script type="text/javascript">
var obj = #Html.Raw(Json.Encode(Model));
</script>
Related
I am calling and displaying a java web service using ASP.NET Web API. How do i make it such that when i run my ASP.NET Web API, the page shows JSON data instead of HTML?
Here are my codes:
DemoRestfulClient.cs
public class DemoRestfulClient
{
private string BASE_URL = "http://localhost:8080/";
public Task<string> AdditionJava2()
{
{
try
{
var client = new HttpClient();
client.BaseAddress = new Uri(BASE_URL);
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = client.GetAsync("AdditionJava2").Result;
return response.Content.ReadAsStringAsync();
}
catch (Exception e)
{
HttpContext.Current.Server.Transfer("ErrorPage.html");
}
return null;
}
}
}
DemoController.cs
public class DemoController : Controller
{
private DemoRestfulClient demoRestfulClient = new DemoRestfulClient();
public ActionResult Index()
{
var Result1 = demoRestfulClient.AdditionJava2().Result;
return Content(Result1);
}
}
Someone please help me. Thank you so much in advance.
public class DemoController : Controller
{
private DemoRestfulClient demoRestfulClient = new DemoRestfulClient();
public ActionResult Index()
{
var Result1 = demoRestfulClient.AdditionJava2().Result;
return Json(Result1);
}
}
The above method will return a json object .
You have wanted to get the json object, right? :)
You have to parse the Json object in order to separately view the content in json.
By using ajax, you can get the content of the json object separately.
For an example,
$.ajax({
url: $("#head").val() + "/Template/updatedTmpltView",
dataType: "html",
data: {},
type: "POST",
success: function (msg) {
data = $.parseJSON(msg)
var name = data.FieldName;
var type = data.FieldType;
var id = data.FieldId;
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
}
});
In the success (msg), you get the json object as **msg**.
data will include the parsed json object and you can obtain necessary data by data.yourFieldName
Hope this helped you! :)
I'm just starting out with MVC, JSON, AJAX, etc and as a side project have been trying to create a data viz dashboard.
Today I followed this guide on how to pass a simple table of data from SQL as JSON to my view: http://techfunda.com/howto/292/list-records-using-json
It mostly worked: the JsonResult comes through from my controller and contains the values but not the property names.
This causes a problem because I'm referencing the property names when I process the data for display in JavaScript.
Here's the SQL data:
Here's my Model:
public partial class vw_Dash_ChartData : IEnumerable<object>
{
[Key]
[JsonProperty(PropertyName = "Classification")]
public string Classification { get; set; }
[JsonProperty(PropertyName = "Count")]
public int Count { get; set; }
public IEnumerator<object> GetEnumerator()
{
yield return Classification;
yield return Count;
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
(You'll notice I tried to manually set the [JsonProperty(...)] stuff...it didn't help.)
And here's my JsonResult:
public JsonResult ChartDataJson()
{
var data = new List<vw_Dash_ChartData>();
data = db.vw_Dash_ChartDatas.ToList();
var jsonData = Json(data, JsonRequestBehavior.AllowGet);
return jsonData;
}
(Initially I was sending the data straight through from my DbContext but then thought perhaps it would help to use my vw_Dash_ChartData model. It didn't make a difference).
My view looks like the following:
#{
ViewBag.Title = "Charts";
AjaxOptions options = new AjaxOptions
{
//Confirm = "Are you sure?",
LoadingElementId = "divLoading",
OnSuccess = "processDataMethod",
Url = Url.Action("ChartDataJson")
};
}
<script type="text/javascript">
function processDataMethod(data) {
var output = $("#dataZone");
output.empty();
for (var i = 0; i < data.length; i++) {
var chartData = data[i];
output.append("<tr><td>" + chartData.Classification + "</td><td>" + chartData.Count + "</td></tr>");
}
}
</script>
<div>
<table>
<thead>
<tr>
<th>Classification</th>
<th>Count</th>
</tr>
</thead>
<tbody id="dataZone">
</tbody>
</table>
</div>
#using (Ajax.BeginForm(options))
{
<div id="divLoading" style="color: red; font-size: larger;">
Loading...
</div>
<div>
<button type="submit" id="btnClicky" >Clicky</button>
</div>
}
<script>
$("#btnClicky").trigger("click");
</script>
When I load the page, this is what I get:
and this is the JSON object shown in the browser developer tools;
Any tips/ideas gratefully received! Also, if I'm doing anything stupid do let me know as I'd like to learn best practice for this stuff.
How about?
var jsonData = Json(data.Select(x=> new {
Classification = x.Classification,
Count = x.Count
})
);
return jsonData;
i have to redirect to a different view if authenticated and I need to send JSON data containing the userid and username to be used by AngularJS.
The Redirect works but I am not sure how to send the authenticated user information as JSON data to the client-side.
Can some one help me?
Here are some code that I have in MVC side...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using TVS.Core.Interfaces;
using TVS.Domain;
using TVS.UI.Models;
namespace TVS.UI.Controllers
{
public class homeController : Controller
{
private readonly IUser _IUser;
public homeController(IUser IUser)
{
_IUser = IUser;
}
public ActionResult RedirectAngular()
{
return View();
}
[HttpGet]
public ActionResult Login()
{
return View();
}
[HttpPost]
public ActionResult Login(UserModel model)
{
if (ModelState.IsValid)
{
if (_IUser.IsValidUser(model.Login,model.Password))
{
FormsAuthentication.SetAuthCookie(model.Login, false);
return RedirectToAction("RedirectAngular", "home");
}
else
{
// ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
//}
}
return View();
}
public ActionResult LogOff()
{
FormsAuthentication.SignOut();
return RedirectToAction("Login", "home");
}
}
}
You could just put it in a model or ViewBag and render the view if the logon form is actually a page and whatever page you redirect to when authenticated is another. Then just use the model / ViewBag to populate a page / app Setting javascript global or push them into angular value or constant like so:
//Controller Action
public ActionResult Logon(string username, string password) {
//authentication successful...
//using ViewBag, but model will do as well..
ViewBag.UserId = 12; //for example...
ViewBag.UserName = "John Doe";
return View();
}
#* View
somewhere near end of <body> tag...
*#
<script src=".../angular.js">
<script>
//or load this from a file...
angular.module('moduleName', []);
</script>
<script>
//this need to be in page!!
angular.moduel('moduleName')
.value('appSettings', {
userId : #ViewBag.UserId,
userName: '#ViewBag.UserName'
});
</script>
<script>
//this can be loaded from file...
angular.controller('controllerName', ctrlFn);
ctrlFn.$inject = ['$log', 'appSettings'];
function ctrlFn($log, appSettings) {
//do something with appSetting here...
$log.info(appSettings.userId, appSettings.userName);
}
</script>
If this is not what you meant, and you are pushing the form info as Ajax and your Angular is actually a SPA then you need to use AJAX to marshal data between server and client side...
Just return a JsonResult like so...
[HttpPost]
public ActionResult Logon(string username, string password)
{
//authenticate here... assume succesful...
var user = new { userId = 12, userName = "John Doe" }
return Json(user, "application/json", Encoding.UTF8);
}
in your angular, just handle whatever getting returned back like so:
<script>
angular.module('moduleName')
.factory('loginSvc', svcFn);
svcFn.$inject = ['$http'];
function svcFn($http) {
var svc = {
login: login
};
return svc;
function login(username, password) {
return $http.post(
'/api/login',
angular.toJson({username: username, password: password});
}
}
angular.module('moduleName')
.controller('controllerName', ctrlFn);
ctrlFn.$inject = ['$log', 'loginSvc'];
function ctrlFn($log, loginSvc) {
var self = this;
self.username = "";
self.password = "";
self.login = login;
function login() {
loginSvc.login(username, password)
.then(handleLoginSuccess)
.catch(handleLoginFailure);
}
function handleLoginSuccess(userInfo) {
$log.info(userInfo); //this should contain logged in user id and username
}
//some other functions here...
}
</script>
How does MVC 6 renders a view. What's the actual method in Razor ViewEngine that generates the html output? Also if possible please explain the process of rendering a view.
May be you could point me to a file on mvc source on github. thanks!
Here is a complete solution of what you are looking for. I used dependency injection to get the HtmlHelper in the controller. You can inject your own helper if you want too.
using Microsoft.AspNet.Html.Abstractions;
using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.Mvc.ViewEngines;
using Microsoft.AspNet.Mvc.ViewFeatures;
using Microsoft.AspNet.Mvc.ViewFeatures.Internal;
using Microsoft.Extensions.WebEncoders;
using System.ComponentModel.DataAnnotations;
using System;
public class MyController : Controller
{
private readonly IHtmlGenerator htmlGenerator;
ICompositeViewEngine viewEngine;
IModelMetadataProvider metadataProvider;
private readonly IHtmlHelper helper;
IHtmlEncoder htmlEncoder;
IUrlEncoder urlEncoder;
IJavaScriptStringEncoder javaScriptStringEncoder;
public MyController(IHtmlHelper helper, IHtmlGenerator htmlGenerator, ICompositeViewEngine viewEngine, IModelMetadataProvider metadataProvider, IHtmlEncoder htmlEncoder, IUrlEncoder urlEncoder, IJavaScriptStringEncoder javaScriptStringEncoder)
{
this.htmlGenerator = htmlGenerator;
this.viewEngine = viewEngine;
this.metadataProvider = metadataProvider;
this.htmlEncoder = htmlEncoder;
this.urlEncoder = urlEncoder;
this.javaScriptStringEncoder = javaScriptStringEncoder;
this.helper = helper;
}
[HttpGet]
public IActionResult MyHtmlGenerator()
{
MyViewModel temp = new MyViewModel();
var options = new HtmlHelperOptions();
options.ClientValidationEnabled = true;
ViewDataDictionary<MyViewModel> dic = new ViewDataDictionary<MyViewModel>(this.metadataProvider, new ModelStateDictionary());
ViewContext cc = new ViewContext(ActionContext, new FakeView(), dic, TempData, TextWriter.Null, options);
var type = typeof(MyViewModel);
var metadata = this.metadataProvider.GetMetadataForType(type);
ModelExplorer modelEx = new ModelExplorer(this.metadataProvider, metadata, temp);
ViewData["Description"] = "test desc";
ViewData["Id"] = 1;
this.ViewData = new ViewDataDictionary(this.metadataProvider, new ModelStateDictionary());
IHtmlHelper<MyViewModel> dd = new HtmlHelper<MyViewModel>(this.htmlGenerator, this.viewEngine, this.metadataProvider, this.htmlEncoder, this.urlEncoder, this.javaScriptStringEncoder);
((ICanHasViewContext)dd).Contextualize(cc);
dd.ViewContext.ViewData = this.ViewData;
var desc = GetString(dd.TextBoxFor(m => m.ID));
var ID = GetString(dd.TextBoxFor(m => m.Description));
// Do whatever you want with the ID and desc
return new ContentResult() { Content = ID + desc };
}
public static string GetString(IHtmlContent content)
{
var writer = new System.IO.StringWriter();
content.WriteTo(writer, new HtmlEncoder());
return writer.ToString();
}
}
public class MyViewModel : BaseAssetViewModel
{
// [RegularExpression(#"^-?\d{1,13}(\.\d{0,5})?$|^-?\.\d{1,5}$")]
[Required]
public int ID { get; set; }
[MinLength(2)]
public string Description { get; set; }
// Property with no validation
public string Other { get; set; }
}
public class FakeView : IView
{
string IView.Path
{
get
{
throw new NotImplementedException();
}
}
public Task RenderAsync(ViewContext viewContext)
{
throw new InvalidOperationException();
}
Task IView.RenderAsync(ViewContext context)
{
throw new NotImplementedException();
}
}
I don't know if this may be of help, may be you have to start to look at tag helpers:
https://github.com/DamianEdwards/TagHelperStarterWeb
they're working to a different way to create helpers that integrate in the page in a more natural way.
I've implemented my cascading dropdown list with MVC3 almost exactly as explained in
Easiest way to create a cascade dropdown in ASP.NET MVC 3 with C#
My view had that
<script type="text/javascript">
$(function () {
$('#CategoryID').change(function () {
var selectedCategoryId = $(this).val();
$.getJSON('#Url.Action("SelectCategory")', { categoryid: selectedCategoryId }, function (subcategories) {
var subsSelect = $('#SubCategoryID');
subsSelect.empty();
$.each(subcategories, function (index, subcat) {
subsSelect.append(
$('<option/>')
.attr('value', subcat.SubCategoryID)
.text(subcat.SubCategoryName)
);
});
});
});
});
</script>
My controller had that
public ActionResult SelectCategory(int categoryid)
{
var subs = db.SubCategories.Where(s => s.CategoryID == categoryid).ToList();
return Json(subs, JsonRequestBehavior.AllowGet);
}
And that did not work.
However, it worked when I modified the controller the following way:
public class JsonSubCat
{
public int SubCategoryID { get; set; }
public string SubCategoryName { get; set; }
}
public ActionResult SelectCategory(int categoryid)
{
var subs = db.SubCategories.Where(s => s.CategoryID == categoryid).ToList();
var testsubs = new List<JsonSubCat>();
foreach (var sub in subs)
{
testsubs.Add(new JsonSubCat() { SubCategoryID = sub.SubCategoryID, SubCategoryName = sub.SubCategoryName });
}
return Json(testsubs, JsonRequestBehavior.AllowGet);
}
Looks like a question of converting my entities that I obtain from data source to proper format.
What would be the correct way to implement this?
What would be the correct way to implement this?
I suspect that you have circular references in your domain entities. This is not supported by the JSON serializer, because the JSON format doesn't support circular structures.
You should not pass your domain models to views. Please stop doing this and use view models. Why are you passing your entire subs entity to the view when all that this view cares about is a collection of text and value? That's all a dropdown list needs.
So use view models, not to mention that you already wrote one => the JsonSubCat class which is great:
public ActionResult SelectCategory(int categoryid)
{
var subs = db.SubCategories
.Where(s => s.CategoryID == categoryid)
.ToList()
.Select(x => new JsonSubCat
{
SubCategoryID = x.SubCategoryID,
SubCategoryName = x.SubCategoryName
});
return Json(subs, JsonRequestBehavior.AllowGet);
}