I have this action method which return error message and it did:
var content = responsePost.Content.ReadAsStringAsync().Result;
model = JsonConvert.DeserializeObject<MyAPIResponse>(content);
ViewBag.Message = model.message;
In my Razor view page, I try to read it with the following code:
#{
var jss = new System.Web.Script.Serialization.JavaScriptSerializer();
var userInfoJson = jss.Serialize(ViewBag.Message);
}
<script>
var errors = JSON.parse('#Html.Raw(userInfoJson)');
$(document).ready(function () {
for (var i = 0; i < errors.Count; i++)
{
}
});
</script>
But the output rendered back is:
<script>
var errors = JSON.parse('"[\"Passwords must have at least one non letter or digit character. Passwords must have at least one lowercase (\u0027a\u0027-\u0027z\u0027). Passwords must have at least one uppercase (\u0027A\u0027-\u0027Z\u0027).\"]"');
$(document).ready(function () {
for (var i = 0; i < errors.Count; i++)
{
}
});
</script>
I am using C# MVC Razor for the UI and in my API is Identity for the password policy.
In the controller, just set the object in the bag:
public ActionResult Index()
{
var errors = new[] { "error1", "error2" };
ViewBag.Errors = errors;
return View();
}
Then in view serialize and use it:
<script>
var errors = #Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(ViewBag.Errors))
errors.forEach(item => { alert(item);});
</script>
Note:
In case you don't have an array in the bag, for example ViewBag.Errors = "error1", then don't use forEach, use alert(errors);
JSON.parse is unnecessary in this case. You are not receiving a string from server, you are rendering the html content and javascripts in the response.
Related
I'm a beginer with JavaScript and now I'm facing such problem.
I have an enum
#JsonFormat(shape = Shape.OBJECT)
public enum FinancialEventType {
Income("Income"),
Expense("Expense");
private String code;
private FinancialEventType(String code) {
this.code = code;
}
#JsonValue
public String getCode() {
return this.code;
}
}
and I'd like to pass the enum to my view trough a ModelAttribute(as an object and as an JSON)
#ModelAttribute()
public void addAttributes(Model model) throws JsonProcessingException {
String data1 = new ObjectMapper().writeValueAsString(FinancialEventType.values());
model.addAttribute("data1", data1);
model.addAttribute("eventTypes", FinancialEventType.values());
}
in my view I can get these attributes
<script>
var documentDate = "[[${documentDate}]]";
var eventTypes = "[[${eventTypes}]]";
var data1 = "[[${data1}]]";
console.log("data1: " + data1);
</script>
but the "JSON" looks a bit weird:
data1: ["Income","Expense"]
and when I try the generate a dropdown element via the JavaScript
//Create and append the options
for (var i = 0; i < data1.length; i++) {
var option = document.createElement("option");
option.value = data1[i];
option.text = data1[i];
selectList.appendChild(option);
}
row.appendChild(cell);
the generated list is not what I'm looking for:
thanks for any advice
Witold
Change this:
var data1 = "[[${data1}]]";
for this:
var data1 = [(${data1})];
Using "[[ ]]" in Thymeleaf is equivalent to use th:text, and Thymeleaf is escaping the text (that means, converting the symbol ' in the HTML equivalent "). So, use "[( )]" instead, which is equivalent to th:utext.
This will only work with Thymeleaf version 3, not version 2.
Source: https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#inlining
Tried using c# 7 Tuples like
public (string, bool) ProcessForm([FromBody]Dictionary<string,string> contactFormRequest)
But I get the error "CS1031: Type expected". I guess this isn't supported yet.
Then I tried
public Tuple<string, bool> ProcessForm([FromBody]Dictionary<string,string> contactFormRequest)
{
var message = "test";
var result = true;
var tuple = new Tuple<string, bool>(message, result);
return tuple;
}
This gives no error, but then I cannot pick it up in the view file
function handleResult(data) {
$("#custommessages").html(data.Item1);
}
$2sxc(#Dnn.Module.ModuleID).webApi.post("Form/ProcessForm", {}, newItem, true).then(handleResult);
This outputs nothing.
If I return a simple string from the controller, "data" picks it fine.
How do you pick up the values from a Tuple return?
Why not create a POCO class for serialization:
public class SomeResult
{
public string Message{get;set;}
public bool Result{get;set;}
}
then
public SomeResult ProcessForm([FromBody]Dictionary<string,string> contactFormRequest)
{
var message = "test";
var result = true;
return new SomeResult{Message = message, Result = result};
}
Why not just return a IActionResult?
You can simply write an Anonymous type instead of Tuple!
Named Types may take up some useless spaces (As I thinks that...)
Try This:
public IActionResult ProcessForm([FromBody]Dictionary<string,string> contactFormRequest)
{
var message = "test";
var result = true;
//This will create an anonymous type! (you can see its named as "a'")
var resultData = new { Message = message, Result = result };
return Json(resultData);
}
Wish it may help you.
I have a form in my ASP.NET MVC 5 application that is made up of several different entities that are stored in my database. I am trying to set it up so that, when a user types in the name of a particular entity (let's say a Shipper), the fields in the form that pertain to that entity (e.g. the fields in the Shipper section) are automatically populated with that Shipper's data. Here is what I have tried:
I wrote a class to connect to the database that returns a dataset of Shipper data.
public class DbConnection
{
private string _connectionString = "the connection string";
public DbConnection()
{
}
public DataSet GetShipperData()
{
DataSet shipperData = new DataSet();
try
{
//TODO: replace command with stored procedure name
using(SqlConnection dbConn = new SqlConnection(_connectionString))
{
using (SqlDataAdapter sda = new SqlDataAdapter("select * from dbo.shipper", dbConn))
{
sda.Fill(shipperData);
}
}
return shipperData;
}
catch
{
return null;
}
}
}
}
Here is the method I've written to get the shipper dataset in the controller for the form:
public string[] GetShipperData()
{
DbConnection conn = new DbConnection();
var shipperData = conn.GetShipperData();
List<Shipper> listOfShipperData = shipperData.Tables[0].AsEnumerable().Select(datarow => new Shipper { Name = datarow.Field<string>("Name") }).ToList();
return listOfShipperData;
}
Finally, here is the javascript code in the view where the form is located. I'm using jQuery to call the GetShipperData method in the controller. I have omitted the markup for brevity:
$("#theShipperField").blur(function () {
$.get('#Url.Action("GetShipperData")', function (data) {
var shipperFields = document.getElementsByClassName('form-control shipper');
$(shipperFields).attr("value", data);
});
});
The first error I'm getting is this: In the Shipper fields, I am getting this instead of the data I want: System.Collections.Generic.List1[appname.Models.Shipper]. I think it's because javascript obviously can't work with shipper data, so I need this to be in the form of strings. I'm unsure of how to do this. I would be open to doing this a completely different way, so any help is greatly appreciated. Please let me know if I can provide any additional information.
First: try use Entity Framework
Having your db model in Entity framework I should create web api
[System.Web.Http.Route("api/GetShippers")]
[System.Web.Http.HttpGet]
public IEnumerable<Shipper> GetShippers()
{
var shippers= unitOfWork.GetShippers();
return shippers;
}
After that in your js code
dataservice.js
var dataService = new function () {
getShippers = function (callback) {
$.getJSON(window.applicationBaseUrl + 'api/GetShippers', function (data)
{
callback(data);
});
};
}
index.cshtml
#section scripts{
<script type="text/javascript">
$(document)
.ready(function() {
dataService.getShippers(DoSomething);}
function DoSomething(shippersData) {console.log(shippersData);}
</script>
}
I have a variable
var result = client.DownloadString(query);
in mvc 4 rzaor. By hovering it in the debugging process, it likes the image below
What I want is to display it, so I return it to javascript with the code:
function myFunction() {
$('#response').text('#(Url.Action("result"))');
}
EDIT:
<div id="response"></div>
#{
var strSearch = "test";
var options = "include-passage-references=true";
var client = new WebClient();
var query = string.Format("http://www.xxx.org/v2/rest/passageQuery?key={0}&passage={1}&options={2}", "IP", Server.UrlEncode(strSearch), options);
var result = client.DownloadString(query);
}
However nothing found.
You have to use the ViewBag for that.
On C#:
ViewBag.result = client.DownloadString(query);
On HTML:
function myFunction() {
$('response').text('#ViewBag.result');
}
I have following Javascript line in my ASP.NET web app:
document.getElementById('<%=myTextBox[0].ClientID %>').value = "test";
how can I access myTextBox elements? for instance I want to change 5th element of this server side array, I want to pass a server side parameter to my function, how can I do it?
for instance:
server side:
ddl.Attributes.Add("onChange", "return OnFoodChange(this,'" + i + "');");
javascript function:
function OnFoodChange(myCmb,myIndex)
using document.getElementById('<%=myTextBox[myIndex].ClientID %>').value = "test"; gives me error, it says that myIndex is not defined, I think because myIndex is used like a server side parameter, how can I solve it?
it is my full JavaScript function:
function OnFoodChange(myCmb,myIndex) {
//alert('5');
try{
var q = document.getElementById('<%= HFFoodPrice.ClientID %>').value.toString();
var q2 = q.split(';');
var index = 0;
//alert(myCmb.selectedIndex.toString());
//var e = document.getElementById(myCmb);
var strUser = myCmb.options[myCmb.selectedIndex].value;
document.getElementById('<%=myTextBox[0].ClientID %>').value = strUser;
for (var j = 0; j < q2.length; j++) {
if (q2[j] != '') {
var q3 = q2[j].split(',');
{
}
}
}
}
catch(err)
{
alert(err.message);
}
}
Send this control id of textbox instead of sending index as asp.net control id might not be as you expect,
In Code behind
ddl.Attributes.Add("onChange", "return OnFoodChange(this,'" + myTextBox[i].ClientID + "');");
In HTML
function OnFoodChange(myCmb,myTextBoxId) {
currentTextBox = document.getElementById(myTextBoxId);
//Your code...
}
You are trying to Mix Server side with Client side. it does not work like this. you need to transfer your server array to javascript on server then you will be able access its index on clien side.