How can i pass the json output from controller action to its view ?
As I tried to send before, My code is :
public ActionResult Index()
{
Guid Id = new Guid("66083eec-7965-4f3b-adcf-218febbbceb3");
List<TasksToOfficer> officersTasks = tasks_to_officer_management.GetTasksToOfficers(Id);
return Json(officersTasks)
}
it is asking for JsonRequestBehavior.AllowJson like parameter. I know it is new in asp.net mvc 2 but as redirect to view there is nothis happens but asking for download the json output file. I want to work with returned data in my jQuery .But something going wrong there. and if I removed the parameter then it is showing error :
This request has been blocked because sensitive information could be disclosed to third party web sites when this is used in a GET request. To allow GET requests, set JsonRequestBehavior to AllowGet.
How to avoid this and get json data at view ?
Here is an example of what you are trying to do. First in your view you call $.getJSON to grab the JSON data from the action:
$.getJSON('/Data/StockQuote', function(data) {
if (data.success) {
ShowStockQuote(data);
}
});
Then your action will look like this:
public JsonResult GetStockQuote()
{
JsonResult result = new JsonResult()
{
Data = new {
lastTradePrice = 50,
lastUpdated = "10/1/2010",
expirationDate = "10/2/2010",
success = true
},
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
return result;
}
Once the JSON data is returned from your action to the $.getJSON you can use data to access all the values off of the JSON object. So data.success will give you the success and so forth.
Related
I am testing asynch task in MVC and creating asynchronous task following code. When I return model value along with view name return View("Index", EmpResponse), I am getting error. but if I simply return view return view(). it is working well.
public class AsynchController : Controller
{
string Baseurl = "http://dummy.restapiexample.com/api/v1/";
// GET: Asynch
public async Task<ActionResult> Index()
{
using (var client = new HttpClient())
{
//Passing service base url
client.BaseAddress = new Uri(Baseurl);
client.DefaultRequestHeaders.Clear();
//Define request data format
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
//Sending request to find web api REST service resource GetAllEmployees using HttpClient
HttpResponseMessage Res = await client.GetAsync("employees");
var EmpResponse = "";
//Checking the response is successful or not which is sent using HttpClient
if (Res.IsSuccessStatusCode)
{
//Storing the response details recieved from web api
EmpResponse = Res.Content.ReadAsStringAsync().Result;
//Deserializing the response recieved from web api and storing into the Employee list
}
//returning the employee list to view
return View("Index", EmpResponse);
}
}
In simply ActionResult, I know we can return view name and model both together. is it issue with Async task?
Your intention is to pass EmpResponse as the view-model for your Index view, but since you have already deserialized EmpResponse as a string, it matches the wrong overload of the View() helper method (the one which accepts both viewName and masterName).
Try to pass it as an object to match the correct overload:
return View("Index", EmpResponse as object);
A better approach would be to store the received data as a strongly-typed collection of objects:
var empResponse = await Res.Content.ReadAsAsync<IEnumerable<Employee>>();
Then pass it as a view-model:
return View("Index", empResponse);
This isn't really an async issue, but a model type issue. (Though there is an async issue waiting to become a problem... Don't call .Result directly, but instead use await to get the result.)
Your model is a string. But the overload for View() which takes a second string uses it to find a named view. Which is why it's looking for a view called your long JSON string. (Well, a "master view" in this case since you're sending it two strings.)
Don't use a string as a model. Use a model. Instead of sending one big JSON string to your view, deserialize it into a model of some sort. The type is up to you, but the deserialization might look something like:
var response = await client.GetAsync("employees");
YourModelTypeHere model = null;
if (response.IsSuccessStatusCode)
{
var responseString = await result.Content.ReadAsStringAsync();
model = JsonConvert.DeserializeObject<YourModelTypeHere>(responseString);
}
return View(model);
There may even be an option in result to read/deserialize as your model directly, saving you a line of code above. But the overall principle is the same. Use strongly typed models instead of complex serialized strings.
*In this case, YourModelTypeHere looks like it would in fact be an IEnumerable<YourModel> or perhaps an IList<YourModel>, based on the serialized JSON we're seeing.
*Note also that this uses your current logic of sending an empty model to the same view if nothing was successfully retrieved. For an empty string that may be okay, for null it may become problematic depending on what your view is doing. (Either way your view is going to have to change if it currently expects a string as a model.) Perhaps redirect or return an error in the case of no available model? The logic of how your system should behave is up to you.
I'm trying to build a very simple website to display some test data being added & updated using asp.net mvc (with razor) but whenever data is posted to my Post method, my data is not being updated. I'm trying to get a unordered list (for now) to be updated the second a post is triggered.
I'm posting my data as JSON using the following code:
string jsonDeviceData = SerializeHelper.Serialize<IDeviceData>(deviceData,
ContentTypeEnum.Json, false);
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(localServerUrl);
webRequest.Method = "POST";
webRequest.ContentType = "application/json"; //"application/x-www-form-urlencoded";
byte[] deviceDataBuffer = Encoding.UTF8.GetBytes(jsonDeviceData);
Task<Stream> requestTask = webRequest.GetRequestStreamAsync();
using (Stream requestStream = requestTask.Result)
{
requestStream.Write(deviceDataBuffer, 0, deviceDataBuffer.Length);
}
Task<WebResponse> responseTask = webRequest.GetResponseAsync();
using (StreamReader requestReader = new StreamReader(responseTask.Result
.GetResponseStream()))
{
string webResponse = requestReader.ReadToEnd();
Debug.WriteLine("Web Response: " + webResponse);
}
Below is the code I'm using in the POST method. Don't worry about the logic being so simplistic and probably horrible, but I'm just dabbling with this idea. Data will be stored in SQL Server database and I'll use EF if I decide to go further with this:
[HttpPost()]
public ActionResult Index(DeviceModel model)
{
if (ModelState.IsValid && model != null)
{
var deviceViewModelList = HttpContext.Application["DeviceList"]
as List<DeviceViewModel> ?? new List<DeviceViewModel>();
if (deviceViewModelList.All(m => !string.Equals(m.Name,
model.Name,
StringComparison.InvariantCultureIgnoreCase)))
{
deviceViewModelList.Add(new DeviceViewModel(model));
}
HttpContext.Application["DeviceList"] = deviceViewModelList;
var homePageViewModel = new HomePageViewModel
{
DeviceList = deviceViewModelList
};
return RedirectToAction("Index");
}
else
{
return View();
}
}
My model is passed correctly and everything works ok when the data is posted my page is not updated, even after calling RedirectToAction("Index");
The code below gets called the first time the page is loaded and after calling the RedirectToActio("Index"):
public ActionResult Index()
{
ViewBag.Title = "Test Server";
var deviceViewModelList = HttpContext.Application["DeviceList"]
as List<DeviceViewModel> ?? new List<DeviceViewModel>();
var homePageViewModel = new HomePageViewModel
{
DeviceList = deviceViewModelList
};
return View(homePageViewModel);
}
This is the code I have in my .cshtml page:
<ul>
#if (Model?.DeviceList != null)
{
foreach (var device in Model.DeviceList)
{
<li>#device.Name</li>
}
}
</ul>
If I check Fiddler, the data, in this case, the list is build correctly.
If I press F5 my data is displayed correctly.
I've read so many articles at this stage and I still haven't got a solution, one of them being View not updated after post and while I've tried ModelState.Clear(); and as you can see from my code I'm using #device.Name which is one of the suggestion. I'm not sure about the last one.
Another article I read was ASP NET MVC Post Redirect Get Pattern but again to no avail.
I'm obviously missing something.
Most articles/samples I've been looking at refer to posting via a Form and I know I'm posting, but is that the same as posting via a Form?
Also my page's viewModel is for my page and it contains a list of devices. Is that OK rather than passing the list of device as the viewmodel to the page? The reason I'm doing this is that I will want to access other lists at a later stage.
Has anyone got any suggestions?
Much appreciated.
I'm trying to simply create a json postback so I can update some controls on the client side. I cant find a good example to show this.
Here's what I got so far which appears to be firing off an alert from the controller but keeps saying 'undefined' object on client side.
What is best practice method of achieving this as I dont know how to debug javascript in the same manner as regular code? :( I'm using vs2012 express, mvc 4, jquery 1.7.1 and jquery mobile 1.1.
My controller Time/Index:
[HttpPost]
public JsonResult Index()
{
var msg = "hello there"; //test message
return Json(msg);
}
My client side:
function populateUserDetails() {
var user = {};
user.UserId = $("#UserId").val(); // potential fields i may use once i get it working
$.post('Time/Index', user, updateFields, 'json');
};
updateFields = function (data) {
alert("hi " + data.msg);
$("#textEntered").val(data.msg);
};
*** UPDATE *********
fixed it by wrapping returned object in controller into a temporary class:
[HttpPost]
public JsonResult Index()
{
var response = new {msg = "hello there"}; //here's what i changed
return Json(response);
}
Replace your last line of code as below.
return Json(response,JsonRequestBehavior.AllowGet);
so it should be like that
[HttpPost]
public JsonResult Index()
{
var response = new {msg = "hello there"};
//here's what i changed
return Json(response,JsonRequestBehavior.AllowGet);
}
I have this api controller action that takes an object "ContentList" as parameter.
[HttpPost]
public List<string> SendList(string param, ContentList list)
{
List<string> testReturn = new List<string> { "test1", "test2", "test3", "test4" };
return testReturn ;
}
What I have tried so far is to call a controller action like this:
Uri _uri = new Uri("http://localhost:xxxxx/api/FakeTest/SendList?param=test");
var serializer = new JavaScriptSerializer();
string requestData = serializer.Serialize(new
{
list = ContentList,
});
using (var client = new WebClient())
{
client.Headers[HttpRequestHeader.ContentType] = "application/json";
var result = client.UploadData(_uri, Encoding.UTF8.GetBytes(requestData));
var tempString = Encoding.UTF8.GetString(result);
}
In this example, tempString = ["test1","test2","test3","test4"] as reurned by the controller action..
In the controller action, I can access the properties of the passed in ContentList, and return their values (changing the actions return value accordingly ofcourse).
However, in the controller action, I need to send off the ContentList object for further processing, and this seems to fail. I get a 500 internal server error, and I can't put a breakpoint in the controller to follow the values passed in. The debugger never hits it...
I expect this has something to do with sending json to the controller action.
Anyway, it seems that the ContentList is rejected by the code it is sent to from the controller action, so I figure I need to do some sort of de-serializing, right?
Bottomline, the question is, what is the correct way to call a controller action from code, pass in a C# object, and make it usable from the controller action?
If you are using MVC 3 your controller should be able to reveive and parse json data in a direct way. If you are using MVC 2 you'll need to register a new factory on your application to take care of json parsing on the controller
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
ValueProviderFactories.Factories.Add(new JsonValueProviderFactory());
}
More info on the subject here:
http://haacked.com/archive/2010/04/15/sending-json-to-an-asp-net-mvc-action-method-argument.aspx
I'm using MVC 3 and C# I would like to know how to retrieve the value for form sent using POST.
her my code, but does not work, thevalue for eventTitle is null. Any idea what I'm doign wrong here? thanks for your time.
[HttpPostAttribute]
public JsonResult AddEventCustom()
{
string eventTitle = Request.Form["EventTitle"];
return Json(new { Message = "Success" }, JsonRequestBehavior.AllowGet);
}
You can simply put the vars you need in the method declaration.
MVC `will handle the mapping for you
[HttpPostAttribute]
public JsonResult AddEventCustom(string EventTitle)
{
}