ASP.NET - accessing ViewBag in a View - c#

I have a one page that uses Javascript to load several PartialViews. I am trying to access ViewBag in some Javascript but am having problems.
MyView:
<div>
<script>
var test = #ViewBag.test;
alert(test);
</script>
</div>
The controller which handles this view:
public PartialViewResult MyView()
{
ViewBag.test = "test";
return PartialView();
}
When I run it, the Javascript alert does not appear. I get a "Conditional compilation is turned off" highlight under the View's calling of ViewBag.

When your view is rendered, this is what is produced:
var test = test;
..that is obviously not valid javascript.
You need to enclose it in quotes:
var test = "#ViewBag.test";
Which produces:
var test = "test";
..valid Javascript.

Related

How to display an alert message from .cshtml view - asp.net mvc

I have two action result one sending a string and another loading the view
public ActionResult getTheString()
{
string message = //doing some thing ;
myModel myModel = new myModel();
myModel.property1 = message ;
return loadView(myModel);
}
public ActionResult loadView(myModel model)
{
return view (model);
}
loadView.cshtml
#model project.Models.myModel
#{
if(Model.property1 !=" ")
{what to do to show it as alert }
}
Here I am getting the prperty like model.property1 if it has some thing show the alert with that string and then load, if message does not contain anything then simply load.
Not permitted to use TempData , ViewBag , ViewData.
Not permitted to use Script tag in view . it has to be in a seperate js file
You could check with some simple Razor syntax
#if(!string.IsNullOrEmpty(Model.Property1)) {
<script>alert("#Model.Property1");</script>
}
you can use javascript and give alert once page is loaded.
<script type="text/javascript">
window.load = function() {
#if(!string.IsNullOrEmpty(Model.Property1)) {
alert("blah blah");
}
}
</script>

how i can bind data to model with post method asp.mvc [duplicate]

I want to send a message to userID=3 by going to /MyController/Message/3
This executes Message() [get] action, I enter some text in the text area and click on Save to post the form
Message() [post] action saves the changes, resets the value of SomeText to empty string and returns to the view.
At this point I expect the text area to be empty because I have set ViewData["SomeText"] to string.Empty.
Why is text area value not updated to empty string after post action?
Here are the actions:
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Message(int ID)
{
ViewData["ID"] = ID;
return View();
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Message(int ID, string SomeText)
{
// save Text to database
SaveToDB(ID, SomeText);
// set the value of SomeText to empty and return to view
ViewData["SomeText"] = string.Empty;
return View();
}
And the corresponding view:
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<% using (Html.BeginForm())
{ %>
<%= Html.Hidden("ID", ViewData["ID"])%>
<label for="SomeText">SomeText:</label>
<%= Html.TextArea("SomeText", ViewData["SomeText"]) %>
<input type="submit" value="Save" />
<% } %>
</asp:Content>
The problem is that your ModelState is re-filled with the posted values.
What you can do is clear it on the Action that has the Post attribute :
ModelState.Clear();
The problem is the HtmlHelper is retrieving the ModelState value, which is filled with the posted data. Rather than hacking round this by resetting the ModelState, why not redirect back to the [get] action. The [post] action could also set a temporary status message like this:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Message(int ID, string SomeText)
{
// save Text to database
SaveToDB(ID, SomeText);
TempData["message"] = "Message sent";
return RedirectToAction("Message");
}
This seems to me like more correct behaviour.
The html helpers read the value from the ModelState. And there's no elegant way to override this behaviour.
But if you add this line after SaveToDB(ID, SomeText), it should work :
ModelState["SomeText"].Value =
new ValueProviderResult("", "", CultureInfo.CurrentCulture);
I tried everything, but only worked when I did something like this:
ModelState.Clear();
//This will clear the address that was submited
viewModel.Address = new Address();
viewModel.Message = "Dados salvos com sucesso!";
return View("Addresses", ReturnViewModel(viewModel));
Hope this helps.
Instead of using ModelState.Clear() which clears the whole modelstate, you can do ModelState.Remove("SomeText"), if you want to. Or render the Input without the htmlhelper-extensions.
They are designed to take the Value from ModelState instead of the Model (or viewdata).
That is a clientside behavior. I would recommend using javascript. If you use JQuery, you can do it like this:
<script type="text/javascript">
$(function(){ $("#SomeText").val("");});
</script>
I don't use Javascript anymore, but I believe in regular JS that it is like:
document.getElementById("SomeText").value = "";
(You would do this on one of the load events.
<body onload="...">
Hope this helps.
I am fairly certain the textarea is grabbing the value from the Request.Form under the hood since ViewData["SomeText"] is empty.
Is it possible that the model state has been updated with an error? I believe that it will pull the attempted value from the model state rather than from view data or the model if the model state isn't valid.
EDIT:
I'm including the relevant section of the source code from the TextArea HtmlHelper extension below. It appears to me that it does exactly what I expected -- if there has been a model error, it pulls the value from the model state, otherwise it uses it from ViewData. Note that in your Post method the "SomeText" key shouldn't even exist until you set it, i.e., it won't be carried forward from the version of the code that responds to the GET.
Since you explicitly supply a value to the ViewData, useViewData should be false, attemptedValue should be false unless an error has been set in the model state.
// If there are any errors for a named field, we add the css attribute.
ModelState modelState;
if (htmlHelper.ViewData.ModelState.TryGetValue(name, out modelState)) {
if (modelState.Errors.Count > 0) {
tagBuilder.AddCssClass(HtmlHelper.ValidationInputCssClassName);
}
}
// The first newline is always trimmed when a TextArea is rendered, so we add an extra one
// in case the value being rendered is something like "\r\nHello".
// The attempted value receives precedence over the explicitly supplied value parameter.
string attemptedValue = (string)htmlHelper.GetModelStateValue(name, typeof(string));
tagBuilder.SetInnerText(Environment.NewLine + (attemptedValue ?? ((useViewData) ? htmlHelper.EvalString(name) : value)));
return tagBuilder.ToString(TagRenderMode.Normal);
Do s.th. like this:
add:
ModelState.Clear();
before the return statement of the submit buttons action method. Works for me. It could work for you.

Need to pass the Rowdata to another view on link click

Here is my JQGrid Code:
click: function (e) {
debugger;
var id = $(e.target).closest("tr.jqgrow").attr("id");
rowdata = jQuery("#EmpTable").getRowData(id);
Data = { Id: rowdata.Id, Name: rowdata.Name, Designation: rowdata.Designation };
var url = 'http://localhost:50428/Script/Edit/';
return $.post(url, Data);
}
here is my controller code where the data is collecting
[HttpPost]
public ActionResult Edit(FormCollection form)
{
gridmodel properties = new gridmodel();
properties.Id = Convert.ToInt32(form["id"]);
properties.Name = form["Name"];
properties.Designation = form["Designation"];
ViewBag.id = properties.Id;
ViewBag.name = properties.Name;
ViewBag.designation = properties.Designation;
return View();
}
Now here is my View code
the data that is passing from the controller to the view
#model MVC5_JQGrid.Models.gridmodel
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Edit</title>
</head>
<body>
<div>
Id:#ViewBag.id
<br />
Name:#ViewBag.name
<br />
Designation:#ViewBag.designation
</div>
</body>
</html>
But i am unable to load this page but in network ---> Response body i can see that these values are assigned
Update
Hello Venkata thanks for the answer i will keep the points which you mentioned and +1 from my side for the observation ,coming to the problem. it was resolved from oleg suggestion:(Here is the answer given by Oleg) The reason of your problem is the usage of $.post(url, Data); which just send data with respect of $.ajax({url: "/Script/Edit", data: Data, type: "POST"});. You need to do $.submit instead. If you would use HTTP GET then you can just assign new URL which includes parameters to location.href (something like location.href = "/Script/Edit?" + $.param(Data)). In case of HTTP POST one need to build with elements which contains (or just have on the page hidden form with all required elements with required name attributes) and use $.submit.
Thanks for the help from oleg and Venkata
Few Changes required in your code:
Observation and Notes:
Before fixing, we should know few points here regarding architecture, control-flow and standards
jQuery AJAX requests get response to its success callback handler(in your code you've missed success call)
In success function We should build or append or set HTML to target placeholder tag in existing page (let us say you have div for Edit section like <div id='editSection'>...</div> in your jqGrid page. you should bind the responseView to editSection div)
When we send AJAX request: In Controller.Action Instead of return View(); we should have return PartialView();
In your view.cshtml give preference to bind elements with Model rather than ViewData. You can get model to view if you do return PartialView(model); in the Action.
Try to reduce usage of ViewData or ViewBag in view.cshtml. Also business logic not recommended in Views.
Try to Follow best practices: Capitalization Conventions (in your code change gridmodel class name to GridModel)
By default routing url template will have {controller}/{action} (from your url Script is controller and Edit is action)
Make sure that you're passing correct Controller and Action names (Is Edit action located in the Controller with name ScriptController?)
Changes in JavaScript JQGrid Code:
url = '/Script/Edit/';
return $.post(url, Data).success(function(response){
//response datatype can be JSON or XML or HTML or text (In your case HTML Edit.cshtml View)
//update you target html tag with response view.
$('#editSection').html(responseView);
});
Changes in Controller:
[HttpPost]
public ActionResult Edit(FormCollection form)
{
var properties = new gridmodel();
properties.Id = Convert.ToInt32(form["id"]);
properties.Name = form["Name"];
properties.Designation = form["Designation"];
ViewBag.id = properties.Id;
ViewBag.name = properties.Name;
ViewBag.designation = properties.Designation;
return PartialView();
}
You can change above Edit Action like below if action require input parameters only id, name & designation
[HttpPost]
public ActionResult Edit(int id, string name, string designation)
{
var gridModel = new GridModel();
gridModel.Id = id;
gridModel.Name = name;
gridModel.Designation = designation;
ViewBag.id = gridModel.Id;
ViewBag.name = gridModel.Name;
ViewBag.designation = gridModel.Designation;
return PartialView(gridModel);
}
Hello Venkata thanks for the answer i will keep the points which you mentioned and +1 from my side for the observation ,coming to the problem. it was resolved from oleg suggestion:(Here is the answer given by Oleg) The reason of your problem is the usage of $.post(url, Data); which just send data with respect of $.ajax({url: "/Script/Edit", data: Data, type: "POST"});. You need to do $.submit instead. If you would use HTTP GET then you can just assign new URL which includes parameters to location.href (something like location.href = "/Script/Edit?" + $.param(Data)). In case of HTTP POST one need to build with elements which contains (or just have on the page hidden form with all required elements with required name attributes) and use $.submit. Thanks for the help from oleg and Venkata

How to execute jQuery in MVC Controller C#

Is it possible to run jQuery from a MVC C# controller?
if (ModelState.IsValid){
//lots of C# asp.net code here
jqueryFunctionName();
}
It's important that there is a check somehow before the jQuery runs
Perhaps i can do it straight from jQuery itself, but i'm not sure how to check it?
The idea is Form -> Submit -> SOMETHING checks if valid -> if yes then wait graphic -> 2 seconds pauze -> redirect to "thanks.cshtml"
In your controller's action:
var vm = new YourViewModelTypeWithPropertyIsValid();
vm.IsValid = ModelState.IsValid;
return View(vm);
In your view:
#model YourViewModelTypeWithPropertyIsValid
<script type="text/javascript">
var isModelValid = #Model.IsValid ? 'true' : 'false';
$( document ).ready(function() {
// Any JS code here
// ...
if (isModelValid) {
setTimeout(
function () {
location.assign('/redirect_path_after_2s_delay');
},
2000);
);
}
});
<script>
I prefer typed views.
If you use untyped views, use the code below.
In your controller's action:
ViewData["IsModelValid"] = ModelState.IsValid ? "true" : "false";
return View();
In your view:
<script type="text/javascript">
var isModelValid = #ViewData["IsModelValid"];
$( document ).ready(function() {
// Any JS code here
// ...
if (isModelValid) {
// See the code above.
}
});
<script>
If the code runs in the view then you can try something like this.
is a special asp tag.
If the should indeed run in controller, than it is not possible to run JS code there.
if (ModelState.IsValid){
//lots of C# asp.net code here
<text>
<script>
jqueryFunctionName();
</script>
</text>
}

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.

Categories