Pass data from controller to view via JSONResult - json

I'd like to send ViewModel from controller to view in JSON format.
Controller:
public ActionResult Select(int pageLimiter)
{
var viewModel = new ArticlesViewModel
{
Articles = this.Service.GetArticles(0, 0, 0),
ArticlesTotal = this.Service.CountArticles(0),
Pages = new List<string>
{
"1", "2", "3"
}
};
return Json(viewModel, JsonRequestBehavior.AllowGet);
}
View:
<ul class="articleList">
#if (#Model != null)
{
foreach (var article in #Model.Articles)
{
<li>
<header>#article.Title</header>
<nav>
<span>#article.AuthorName</span> |
<time>#article.PublishDate.ToString("")</time> |
<span>#article.CategoryName</span> |
<span>#article.Comments Comments</span>
</nav>
<section>
#article.Content
</section>
</li>
}
}
</ul>
<script type="text/javascript">
$(document).ready(function () {
GetArticles(5);
$("#selectPager").change(function () {
var selectedItem = "";
$("#selectPager option:selected").each(function () {
selectedItem = $(this).text();
});
GetArticles(selectedItem);
});
});
function GetArticles(pageLimitValue) {
$.ajax(
{
url: "/Articles/Select",
dataType: "json",
data: { pageLimiter: pageLimitValue },
async: true,
beforeSend: function () {
alert("before");
},
complete: function (data) {
#Model = SOME_MAGIC_TRICKS
}
});
}
As you can see, in the complete event are words SOME_MAGIC_TRICKS. In this place I'd like to set #Model obtained from controller. Is it possible at all? How to insert data from ajax result to view model (it's null by default)?

You are trying to modify server variable from client's code. It's not possible.
If you want to re-render your page's content on complete, you may render <ul class="articleList"> with PartialView and return same partial view instead of JsonResult. Further, oncomplete handler will update your <ul class="articleList"> with returned content.

You can send data doing serialize it may be like:
public ActionResult Select(int pageLimiter)
{
var viewModel = new ArticlesViewModel
{
Articles = this.Service.GetArticles(0, 0, 0),
ArticlesTotal = this.Service.CountArticles(0),
Pages = new List<string>
{
"1", "2", "3"
}
};
string myjsonmodel = new JavaScriptSerializer().Serialize(viewModel );
return Json(jsonmodel = viewModel, JsonRequestBehavior.AllowGet);
}
dont forget using using System.Web.Script.Serialization;
Edit:
To deserialize object try this:
#{
JavaScriptSerializer jss= new JavaScriptSerializer();
User user = jss.Deserialize<User>(jsonResponse);
}

Related

need signalR polling for asp.net mvc

Any kind soul can guide me how to use signalR on an existing mvc project to poll data in real time i'd be greatly appreciate.
example code:
[controller]
private ApplicationDbContext db = new ApplicationDbContext();
public PartialViewResult Chat(string people) // <---need to send real time data to partial
{
var model = new MessageVM()
{
sender = User.Identity.Name;,
messageList = db.messages.Where(x => x.receiver == people).ToList().Take(30)
};
return PartialView("_chat", model);
}
[view]
#Ajax.ActionLink(item.name, "Chat", new { people = item.name }, new AjaxOptions()
{ HttpMethod = "GET", UpdateTargetId = "divChat", InsertionMode = InsertionMode.Replace })
<div id="divChat"></div> // <---this area need real-time messages data from controller.
First create your signalr connection in js in client side. something like:
function signalrconnection() {
$.connection.hub.url = "http://localhost:54321/signalr";
chat = $.connection.myHub;
if (chat != undefined) {
$.connection.hub.start()
.done(function () {
chat.server.send("client", "Status\tasking for status");
chat = $.connection.myHub;
})
.fail(function () { NoLTConnectionAlert(); });
}
else {
///do something.
}
}
return chat;
}
Then add signalr call to your $(document).ready(function ()) in your js something like:
$(document).ready(function () {
chat = signalrconnection();
intervalstatus = setInterval(checkstatus, 1000);
// Create a function that the hub can call to broadcast messages.
chat.client.addMessage = function (name, message) {}
}
In your controller you should have a class for hub and method inside like:
public class MyHub : Hub
{
public void Send(string name, string message)
{
Clients.Caller.addMessage("parameter", reply);
}
}
Then again you should handle Clients.Caller.addMessage in you js to update <div id="divChat"></div>

MultipartMemoryStreamProvider and reading user data from MultiPart/Form Data

I have a file and user data that is being posted from Multipart/form data to a post method in my apicontroller class.
I am able to read the file without any problems but unable to read user data.
I tried couple of things like using model binding, passing the individual fields as a method parameter in the post method but i get: No MediaTypeFormatter is available to read an object of type 'FormDataCollection' from content with media type 'multipart/form-data'.
var provider = await Request.Content.ReadAsMultipartAsync(new MultipartMemoryStreamProvider());
foreach (var item in provider.Contents)
{
var fieldName = item.Headers.ContentDisposition.Name.Trim('"');
if (item.Headers.ContentDisposition.FileName == null)
{
var data = await item.ReadAsStringAsync();
if (fieldname == "name")
{
Name = data;
}
else
{
fileContents = await item.ReadAsByteArrayAsync();
}
}
}
Thanks.
It seems to me the OP, was really close. This is some code that tries to clearly show how to get the form variables, as well as the file upload data.
First the ApiController:
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Web.Http;
namespace WebApplication1.Controllers
{
public class FormAndFileDataController : ApiController
{
private class FormItem
{
public FormItem() { }
public string name { get; set; }
public byte[] data { get; set; }
public string fileName { get; set; }
public string mediaType { get; set; }
public string value { get { return Encoding.Default.GetString(data); } }
public bool isAFileUpload { get { return !String.IsNullOrEmpty(fileName); } }
}
/// <summary>
/// An ApiController to access an AJAX form post.
/// </summary>
/// <remarks>
///
/// </remarks>
/// <returns></returns>
public async Task<HttpResponseMessage> Post()
{
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
var provider = new MultipartMemoryStreamProvider();
await Request.Content.ReadAsMultipartAsync(provider);
var formItems = new List<FormItem>();
// Scan the Multiple Parts
foreach (HttpContent contentPart in provider.Contents)
{
var formItem = new FormItem();
var contentDisposition = contentPart.Headers.ContentDisposition;
formItem.name = contentDisposition.Name.Trim('"');
formItem.data = await contentPart.ReadAsByteArrayAsync();
formItem.fileName = String.IsNullOrEmpty(contentDisposition.FileName) ? "" : contentDisposition.FileName.Trim('"');
formItem.mediaType = contentPart.Headers.ContentType == null ? "" : String.IsNullOrEmpty(contentPart.Headers.ContentType.MediaType) ? "" : contentPart.Headers.ContentType.MediaType;
formItems.Add(formItem);
}
// We now have a list of all the distinct items from the *form post*.
// We can now decide to do something with the items.
foreach (FormItem formItemToProcess in formItems)
{
if (formItemToProcess.isAFileUpload)
{
// This is a file. Do something with the file. Write it to disk, store in a database. Whatever you want to do.
// The name the client used to identify the *file* input element of the *form post* is stored in formItem.name.
// The *suggested* file name from the client is stored in formItemToProcess.fileName
// The media type (MimeType) of file (as far as the client knew) if available, is stored in formItemToProcess.mediaType
// The file data is stored in the byte[] formItemToProcess.data
}
else
{
// This is a form variable. Do something with the form variable. Update a DB table, whatever you want to do.
// The name the client used to identify the input element of the *form post* is stored in formItem.name.
// The value the client input element is stored in formItem.value.
}
}
return Request.CreateResponse(HttpStatusCode.OK);
}
}
}
and the MVC View to test it:
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>
<script type="text/javascript">
var hiddenForm, hiddenFile;
function initialize() {
// Use a hidden file element so we can control the UI
// of the file selection interface. The built in browser
// UI is not localizable to different languages.
hiddenFile = document.createElement("input");
hiddenFile.setAttribute("type", "file");
hiddenFile.setAttribute("style", "display: none;");
// We don't need the form really, but it makes it easy to
// reset the selection.
hiddenForm = document.createElement("form");
hiddenForm.appendChild(hiddenFile);
hiddenFile.onchange = function () {
var elementToUpdate = document.getElementById("fileNameToUpload");
var filesToUpload = hiddenFile.files;
var fileToUpload = filesToUpload[0];
elementToUpdate.value = fileToUpload.name;
}
document.body.appendChild(hiddenForm);
}
function chooseFile() {
hiddenFile.click();
}
function clearFile() {
var elementToUpdate = document.getElementById("fileNameToUpload");
elementToUpdate.value = "";
hiddenForm.reset();
}
function testAJAXUpload() {
// We are going to use the FormData object and jQuery
// to do our post test.
var formToPost = new FormData();
var formVariableNameElement = document.getElementById("variableNameToUpload");
var formVariableValueElement = document.getElementById("variableValueToUpload");
var formVariableName = formVariableNameElement.value || "formVar1";
var formVariableValue = formVariableValueElement.value || "Form Value 1";
var filesToUpload = hiddenFile.files;
var fileToUpload = filesToUpload[0];
formToPost.append(formVariableName,formVariableValue)
formToPost.append("fileUpload", fileToUpload);
// Call the Server.
$.ajax({
url: '#Url.HttpRouteUrl("DefaultApi", new { controller = "FormAndFileData" })',
type: 'POST',
contentType: false,
processData: false,
data: formToPost,
error: function (jqXHR, textStatus, errorThrown) {
alert("Failed: [" + textStatus + "]");
},
success: function (data, textStatus, jqXHR) {
alert("Success.");
}
});
}
</script>
</head>
<body>
<input id="variableNameToUpload" type="text" placeholder="Form Variable: Name" />
<br />
<input id="variableValueToUpload" type="text" placeholder="Form Variable: Value" />
<br />
<input id="fileNameToUpload" type="text" placeholder="Select A File..." /><button onclick="chooseFile()">Select File</button><button onclick="clearFile()">Reset</button>
<br />
<button onclick="testAJAXUpload()">Test AJAX Upload</button>
<script type="text/javascript">
initialize();
</script>
</body>
</html>
I had considered adding this to your other post per your comment, but (as you also decided), it is a separate question.
public async Task<HttpResponseMessage> Post()
{
if (!Request.Content.IsMimeMultipartContent())
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
try
{
string root = HttpContext.Current.Server.MapPath("~/App_Data");
var provider = await Request.Content.ReadAsMultipartAsync(new MultipartFormDataStreamProvider(root));
// file data
foreach (MultipartFileData file in provider.FileData)
{
using (var ms = new MemoryStream())
{
var diskFile = new FileStream(file.LocalFileName, FileMode.Open);
await diskFile.CopyToAsync(ms);
var byteArray = ms.ToArray();
}
}
// form data
foreach (var key in provider.FormData.AllKeys)
{
var values = provider.FormData.GetValues(key);
if (values != null)
{
foreach (var value in values)
{
Console.WriteLine(value);
}
}
}
return Request.CreateResponse(HttpStatusCode.Created);
}
catch (Exception ex)
{
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex);
}
}

AngularJS passing Json to controller and displaying in a DevExpress Chart

I have a JsonResult method in my controller. I have pulled in data from my database and set to an object. The method will return this object. I am trying pass this data into AngularJS data source. I would like to display a DevExtreme bar chart. Here is code so far.
AngularJS file:
var app = angular.module('customApp', ['dx']);
app.controller("chartControl", function ($scope, $http) {
$scope.sizeSettings = {
dataSource: 'http://localhost:53640/Home/PostChart',
commonSeriesSettings: {
argumentField: 'product_id',
valueField: "product_id", name: "Product Cost",
type: "bar"
},
seriesTemplate: {
nameField: 'Source',
}
};
});
Home Controller:
public JsonResult PostChart(int product_id)
{
Object prod = null;
using (ProductOrderEntities db = new ProductOrderEntities())
{
var product = db.Products.FirstOrDefault(p => p.product_id == product_id);
prod = new {productID = product.product_id, productName = product.product_name, productPrice = product.product_cost, productDescription = product.product_type};
}
return Json(prod, JsonRequestBehavior.AllowGet);
}
}
HTML
<div ng-app="customApp">
<div ng-controller="chartControl">
</div>
</div>
Seems like you forget add markup for chart:
<div dx-chart="chartOptions"></div>
I've made a simple ASP.NET MVC application here https://www.dropbox.com/s/hk3viceoa2zkyng/DevExtremeChart.zip?dl=0
Open the start page http://localhost:56158/Default1/ to see chart in action.
See more information about using DevExtreme Charts in AngularJS app here http://js.devexpress.com/Documentation/Howto/Data_Visualization/Basics/Create_a_Widget/?version=14_2#Data_Visualization_Basics_Create_a_Widget_Add_a_Widget_AngularJS_Approach
This is how I solved it.
HTML
<div ng-app="customCharts">
<div ng-controller="ChartController">
<div dx-chart="productSettings"></div>
</div>
</div>
AngularJS
var app = angular.module('customCharts', ['dx']);
app.controller("ChartController", function ($scope, $http, $q) {
$scope.productSettings = {
dataSource: new DevExpress.data.DataSource({
load: function () {
var def = $.Deferred();
$http({
method: 'GET',
url: 'http://localhost:53640/Home/PostChart'
}).success(function (data) {
def.resolve(data);
});
return def.promise();
}
}),
series: {
title: 'Displays Product Costs for items in our Database',
argumentType: String,
argumentField: "Name",
valueField: "Cost",
type: "bar",
color: '#008B8B'
},
commonAxisSettings: {
visible: true,
color: 'black',
width: 2
},
argumentAxis: {
title: 'Items in Product Store Database'
},
valueAxis: {
title: 'Dollor Amount'
}
}
})
Controller
public JsonResult PostChart()
{
var prod = new List<Object>();
using (ProductOrderEntities db = new ProductOrderEntities())
{
var product = db.Products.ToList();
foreach (var p in product)
{
var thing = new { Name = p.product_name, Cost = p.product_cost };
prod.Add(thing);
}
}
return Json(prod, JsonRequestBehavior.AllowGet);
}

how to return multiple variables with jsonresult asp.net mvc3

How to return multiple variables on JsonResult method
for example i want to return this two variables:
string result = "Successed";
string ID = "32"
I know how to return only one string:
return Json("Inserted");
public ActionResult YourAction()
{
var result=new { Result="Successed", ID="32"};
return Json(result, JsonRequestBehavior.AllowGet);
}
EDIT : As per the comment "How to get this data in client"
You can use getJSON from view to get this data like this
$(function(){
$.getJSON('YourController/YourAction', function(data) {
alert(data.Result);
alert(data.ID);
});
});
Make sure you have jQuery loaded in your view for this code to work.
Return an anonymous object.
return Json( new { Result = result, Id = ID } );
I normally do something like this:
public enum NoticeTypes
{
Default,
UpdateComplete,
ResponsePending,
Notice,
Error,
Redirect,
WaitAndRetryAttempt
}
public class AjaxJsonResponse
{
public UserNotice Notice { get; set; }
public object Data { get; set; }
private AjaxJsonResponse() { }
public static JsonResult Create(UserNotice Notice,object Data)
{
return new JsonResult()
{
Data = new
{
Notice = Notice,
Data = Data
}
};
}
}
So that I can write my javascript to always expect ajax calls to return data in a certain format.
return AjaxResponse.Create(NoticeTypes.UpdateComplete, new
{
Result = result,
Id = ID
});
Now you can do things like an Ajax Complete global handler that can intercept things like Redirect or WaitAndRetry before the normal handler gets it, and to have a standard way of communicating additional information about the returned data that is the same across your application.
On your controller use something like this:
var result = new { data= stuff, data2 = otherstuff };
return Json(result, JsonRequestBehavior.AllowGet);
If you are using .ajax() on your JavaScript you can use your data acessing like this:
$.ajax(
{
url: '/Controller/Method/',
type: 'POST',
data: 'data=' + data,
success: function (result) {
$('#id').html("");
$(result.data).appendTo('#id');
$('#id2').html("");
$(result.data2).appendTo('#id2');
$('#id').show();
$('#id2').show();
}
});
1. Return as collection inside anonymous type
This is the java script/ajax call and the complete html.
< script type = "text/javascript" >
$(document).ready(function() {
$("#ddlProduct").hide();
$("#ddlRegion").change(function() {
$("#ddlProduct").show();
$("#ddlProduct").empty();
$.ajax({
type: "Post",
url: "#Url.Action("
GetProducts ")",
dataType: "Json",
data: {
id: $("#ddlRegion").val()
},
success: function(jsonData) {
console.log($(jsonData).length);
if ($(jsonData.ProductList).length == 0) {
$("#divProduct").hide();
} else {
$("#divProduct").show();
}
$.each(jsonData.ProductList, function(i, Product) {
$("#ddlProduct").append('<option value=" ' + Product.Value + ' ">' + Product.Text + '</option>');
});
if ($(jsonData.FlavourList).length == 0) {
$("#divFlavour").hide();
} else {
$("#divFlavour").show();
$.each(jsonData.FlavourList, function(i, flavour) {
$("#ddlFlavour").append('<option value=" ' + flavour.Value + ' ">' + flavour.Text + '</option>');
});
}
},
error: function(ex) {
alert("Failed to return Products <br/>");
}
});
return false;
})
}); //Document Ready Ends
< /script>
#{ ViewBag.Title = "Products Drop Down Demo"; }
<h2>Products Drop Down Demo</h2>
#using (Html.BeginForm()) {
<div>#Html.Label("Select Region:")</div>
<div class="editor-field">
#if (ViewData.ContainsKey("Region")) { #Html.DropDownList("ddlRegion", ViewData["Region"] as List
<SelectListItem>) }
</div>
<div id="divProduct" hidden="hidden">
<br />
<div>
Select a Product:
</div>
<div>
#Html.DropDownList("ddlProduct", new SelectList(string.Empty, "Value", "Text"), "Please select a Product", new { style = "width:250px", #class = "dropdown1" })
</div>
</div>
<div id="divFlavour" hidden="hidden">
<div>
<br />Select a Flavour:
</div>
<div>
#Html.DropDownList("ddlFlavour", new SelectList(string.Empty, "Value", "Text"), "Please select a Flavour", new { style = "width:250px", #class = "dropdown1" })
</div>
</div>
}
This is the controller action that returns the data
I tested and it is working.
public ActionResult LoadRegion()
{
List<SelectListItem> Regions = new List<SelectListItem>();
Regions.Add(new SelectListItem { Text = "Select A Region", Value = "0" });
Regions.Add(new SelectListItem { Text = "Asea", Value = "1" });
Regions.Add(new SelectListItem { Text = "Australia", Value = "4" });
Regions.Add(new SelectListItem { Text = "America", Value = "5" });
Regions.Add(new SelectListItem { Text = "Europe", Value = "6" });
ViewData["Region"] = Regions;
return View();
}
public JsonResult GetProducts(string id)
{
List products = new List();
List flavours = new List();
products.Add(new SelectListItem { Text = "Select Product", Value = "0" });
products.Add(new SelectListItem { Text = "Cheese", Value = "1" });
products.Add(new SelectListItem { Text = "Sause", Value = "2" });
products.Add(new SelectListItem { Text = "Veberage", Value = "3" });
products.Add(new SelectListItem { Text = "Snacks", Value = "4" });
flavours.Add(new SelectListItem { Text = "Select Flavour", Value = "0", Selected = true });
flavours.Add(new SelectListItem { Text = "Sweet", Value = "1" });
flavours.Add(new SelectListItem { Text = "Sour", Value = "2" });
flavours.Add(new SelectListItem { Text = "Spicy", Value = "3" });
var myResult = new
{
ProductList = products,
FlavourList = flavours
};
return Json(myResult, JsonRequestBehavior.AllowGet);
}
Let me know if you have any issue running this code.
Thanks
Premjeet
You should return an object with multiple properties:
return Json(new {
result,
ID
});
The JSON serializer will convert C# anonymous types into JSON object literals.
In Action method :
Using new keywork
var genericResult = new { homeworkData = homework, attachmentData = homeworkAttachment };
var result = this.Json(genericResult, JsonRequestBehavior.AllowGet);
return result;
In jquery side :
function getHomewrokDetailResponse(dataSent, result) {
if (result && result.homeworkData) {
homeworkId = result.homeworkData.DASH_EMPLOYEE_HOMEWORK_ID;
....
}

How to populate a #html.dropdownlist mvc helper using JSon

I have a <select> which is loaded by a JSon. But I want to use "#html.dropdownlist helper" instead. My Json is:
function LoadSites() {
$("SelectSite").html("");
$.getJSON("/Pedido/GetSite", null, function (data) {
$("#SelectSite").append("<option value=0>Selecione...</option>");
$.each(data.Result, function (index, site) {
$("#SelectSite").append("<option value='" + site.Id + "'>" + site.Nome + "</option>");
});
});
this Json populate this...
<select id="SelectSite"></select>
My Controller:
[HttpGet]
public JsonResult GetSite()
{
Repository<Site> siteRepo = new Repository<Site>( unitOfWork.Session );
return this.Json( new { Result = siteRepo.All() }, JsonRequestBehavior.AllowGet );
}
I want my code more reusable and self-documenting.
How can I send the object "site" from JSon to "cshtml" using dropdownlist to do something like #html.dropdownlist(site.id, site.Nome)???
Is there a way?
Tks guys.
In your view:
#Html.DropDownListFor(x => x.SiteId, new SelectList(Enumerable.Empty<SelectListItem>()))
where SiteId is a property of your view model which will receive the selected site id when the form is submitted.
and then you could populate this dropdown using AJAX:
$(function() {
$.getJSON('#Url.Action("GetSite", "Pedido")', function(result) {
var ddl = $('#SiteId');
ddl.empty();
$(result).each(function() {
ddl.append(
$('<option/>', {
value: this.Id
}).html(this.Nome)
);
});
});
});
and the controller action that would return the JSON data:
public ActionResult GetSite()
{
var sites = new[]
{
new { Id = "1", Nome = "site 1" },
new { Id = "2", Nome = "site 3" },
new { Id = "3", Nome = "site 3" },
};
return Json(sites, JsonRequestBehavior.AllowGet);
}