How to pass datastructure in MVC post - ajax

I have a form to update entity "Item", It has a drop down list for its category. So its model has two properties: string CategoryName, and List AvailableCategories. In my view, I will compose the combo box for user to select a category based on the value of both:
#if (Model != null && Model.AvailableCategories != null)
{
List<SelectListItem> selectListItem = new List<SelectListItem>();
foreach (var catName in Model.AvailableCategories)
{
selectListItem.Add(new SelectListItem() { Text = catName, Value = catName, Selected = (catName == Model.CategoryName) });
}
if (string.IsNullOrEmpty(Model.CategoryName))
{
#Html.DropDownList("CategoryName", selectListItem, "Select Category")
}
else
{
#Html.DropDownList("CategoryName", selectListItem)
}
}
So the drop down list is ready, and CategoryName will be updated when user submit. But the issue is the property List AvailableCategories is null when user submit the form. In my httppost controller code, If I need to perform some server side validation:
[HttpPost]
public ActionResult NewItem(NewItemViewModel itemModel, string submit)
{
if (contact server and find validation failed here)
{
ModelState.AddModelError("ItemName", "Server said it's not valid");
return View(itemModel);
}
}
Now the returned model "itemModel" has AvailableCategories set to null, since it's not present in the form. If I really needs to make this up on server side, I need to query database again to fill this list, which is not efficient. What is the most elegant way to compose this helper DataStructure back during submit?
What I can think of on client side is #1: Add a hidden field to save all strings so it can be post back, Or #2 Add submit function to compose all data into the model and then post from script. Then if there are server validation errors, I need to match those errors to the right validation field line by line...

Related

Kendo UI DropDown List does not accept JSON data?

Using Kendo DropdownList for MVC, trying to identify why the DropdownList will not accept this data.
#(Html.Kendo().DropDownList()
.Name("CompanyList") //The name of the DropDownList is mandatory. It specifies the "id" attribute of the widget.
.DataTextField("Table")
.DataValueField("COM_NAME")
.DataSource(source =>
{
source.Custom() // Read(read =>
.Type("json")
.Transport(transport =>
{
transport.Read("GetallCompanies", "Home");
})
.ServerFiltering(true); //If true, the DataSource will not filter the data on the client.
})
.SelectedIndex(0) //Select the first item.
)
The raw data from the SQL action has this format:
"{\"Table\":[{\"ORG_ID\":265498,\"COMPORGID\":239597,\"COM_NAME\":\"ABC Rentals \"},{\"ORG_ID\":164929,\"COMPORGID\":239698,\"COM_NAME\":\"Asbury Machine Shop \"}]}"
Have referenced the Kendo docs and other SO examples. Put the JSON into a validator tool, says its correctly formatted.
In the page, the drop down has a left curly brace, { as the top item, and when clicking there are dozens of: Undefined.
The DataTextField was called "Table" because of the "Table" in the JSON array, but it was set to COM_NAME. The Controller Method,
[HttpGet]
public JsonResult GetallCompanies()
{
var ddx = CompInfo.GetAllCompanies(); //returns dataset
string thedata = JsonConvert.SerializeObject(ddx);
return Json(thedata, JsonRequestBehavior.AllowGet);
}
I don't think you need to use SerializeObject on ddx aswell as the Json method before returning to the client. Can you try changing GetAllCompanies to:
[HttpGet]
public JsonResult GetallCompanies()
{
var ddx = CompInfo.GetAllCompanies(); //returns dataset
//string thedata = JsonConvert.SerializeObject(ddx);
return Json(ddx);
}
Summary of the Json method:
Creates a Microsoft.AspNetCore.Mvc.JsonResult object that serializes the specified data object to JSON.
Try this:
Server-side: Leave the JsonConvert.SerializeObject line commented out.
Client-side: Add the following to the DropDownList configuration (e.g. after .SelectedIndex(0)):
.Schema(schema => schema.Data("Table"))

Pagemethod is throwing 'A circular reference was detected while serializing an object of type 'System.Reflection.RuntimeModule'

I have seen so many post on this error explaining about JSON issues. I am just having a classic web form that calls a web method. I have a bunch of radio buttons and 2 drop downs in a form. once I check one of the radio button and two of the drop downs, I have to click on Build template button to populate the form (basically am email form with to, cc, subject field and so on)
When I select the first radio button and then the drop downs, I get the required results. But when I select any of the other radio buttons that return data, I get this circular reference error. The last radio button does not return data, so it doesn't throw the serialization error.
Here is the javascript that calls the page method
function HandleIT() {
var ServiceID = document.getElementById("<%=ddServiceList.ClientID%>").value;
var Status;
// #code to set the drop downs to 1,2,3,4,5 on 'checked'# removed
PageMethods.FindAllRecipient(ServiceID, Status, onSucess, onError);
function onSucess(result) {
document.getElementById("<%=txtTo.ClientID%>").value = result[0];
document.getElementById("<%=txtCC.ClientID%>").value = result[1];
}
function onError(result) {
alert('Something wrong.');
}
}
Here is the code in server method:
[WebMethod]
public static object[] FindAllRecipient(string serviceID, string currentStatus)
{
RemoteObj1 = new ServiceEmailer();
Object[] results = RemoteObj1.FindAllRecipients(
Convert.ToInt16(serviceID),
Convert.ToInt16(currentStatus));
return results;
}
The code works fine in the server method. So no issues there. As the error says obviously, the issue is while serializing and returning the results.

ASP.Net MVC Validation (server side)

asp.net mvc server side validation when the javascript is disabled in the browser? i used "remote" in my modal class it validates only when the javascript is enabled it doesnt validate when the javascript is disabled.
Scenario for my problem is i have a table in my db with a column "code" with the datatype varchar. any one inserts the data they must insert the unique code.
Please do help me out
I would suggest to forget about remote because if you are using code first entity framework, you can't have more that one unique column in your table. I would just write code for it like this:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Register(RegisterModel model)
{
if (ModelState.IsValid)
{
// Insert a new user into the database
using (UsersContext db = new UsersContext())
{
UserProfile email = db.UserProfiles.FirstOrDefault(u => u.Email.ToLower() == model.Email.ToLower());
try
{
// Check if email already exists
if (email == null)
{
WebSecurity.CreateUserAndAccount(model.UserName, model.Password, new { Email = model.Email });
WebSecurity.Login(model.UserName, model.Password);
return RedirectToAction("Index", "Home");
}
else
{
ModelState.AddModelError("Email", "Email address already exists. Please enter a different email address.");
}
}
catch (MembershipCreateUserException e)
{
ModelState.AddModelError("", ErrorCodeToString(e.StatusCode));
}
}
}
Replace the email with the property you want to validate. At post, this will compare with entries with what already exists in your database, and depending on results, it will give you feedback. Throws exception if such data exists.

drop down list in mvc 3

Hey friends I am using drop down list in my mvc 3 project. Here the user choose one of the options and save it. And when he/she revisit the page than i have to make the initially saved value as selected value. Actually i am doing this with custom html helper as per need. But i am getting problem on it. I am doing this as:
else if (question_type == 7)
{
EAI.DAL.EaiEntities entities = new DAL.EaiEntities();
QuestionnaireRepository repository = new QuestionnaireRepository(entities);
SelectList typesList = repository.PopDdlList(qid);
output.Append(helper.Label(questiontext));
if (answer == "")
{
output.Append(helper.DropDownList("ddl" + question_id, typesList, "-- select type----));
}
else
{
output.Append(helper.DropDownList("ddl" + question_id, typesList, answer));
}
return helper.Raw(output.ToString());
}
Actually above code renders the selected value from database but it actually replacing the "-- select type ---" . So, After saving once if i visit the same page and save the page than i can get empty value in Formcollection.
So, please suggest the appropriate way of doing this
I usually add a few properties in my model:
int SelectedCategory { get; set; }
IEnumerable<SelectListItem> Categories { get; private set; }
and then load the data in my model constructor:
ProductService productService = new ProductService();
this.Categories =
productService.GetCategories()
.Select(c => new SelectListItem() { Text = c.Name, Id = c.Id.ToString() });
this.Categories.InsertAt(0, new SelectListItem() { Text = "--- Please Select ---", value = "" });
then in my Razor markup do something like:
#Html.DropDownListFor(m => m.SelectedCategory, Model.Categories)
This should auto wire up in the standard MVC way. Hope this helps.

maintain state of dropdownlist in MVC3

How do I maintain the selected value of dropdownlist in MVC3?
I'm using the following code to create the drop down list:
<%= Html.DropDownList("PEDropDown",
(IEnumerable<SelectListItem>)ViewData["PEDropDown"],
new { onchange = "this.form.action='/Screener/Screener';this.form.submit();" }
)%>
Here is one example, I use. I am not sure, this is the way you use to populate the DropDownList
<%=Html.DropDownList("ddlCategories", IEnumerable<SelectListItem>)ViewData["PEDropDown"], "CategoryId", "CategoryName", Model.CategoryId), "Select Category", new { onchange = "this.form.action='/Screener/Screener';this.form.submit();"})%>
Another way is, make a select list in controller as follows
List<SelectListItem> CategoryList = new List<SelectListItem>();
foreach (var item in Categories)
{
CategoryList.Add(new SelectListItem
{
Selected = Model.CategoryId,
Text = item.CategoryName, Value = Convert.ToString(item.CategoryId) });
}
ViewData["PEDropDown"]=CategoryList;
and use in view as
<%:Html.DropDownList("ddlCategories",IEnumerable<SelectListItem>)ViewData["PEDropDown"], "CategoryId", "CategoryName", new { onchange = "this.form.action='/Screener/Screener';this.form.submit();"})%>
I'm not 100% sure I get what you want to do, but I assume you want to get the selected value from the dropdown list?
In that case:
new { onchange = "alert(this.options[this.selectedIndex].value);" }
I put it in an alert for now, because I don't know what you want to do with the value
pass the value back into your controller and then populate a List of SelectListItems in the controller:
public actionresult yourmethod (int idToPass)
{
List<SelectListItem> SLIList = new List<SelectListItem>();
foreach (Model model in dropdownList)
{
SelectListItem SLI = new SelectListItem();
SLI.text = model.CategoryName;
SLI.selected = model.CategoryId == idToPass;
SLIList.Add(SLI);
}
ViewData["myDDL"] = SLIList;
}
You may try this.
Using ViewBag instead of ViewData (I suggest, it is better to use Model object)
Html.DropDownList("PEDropDown", new SelectList(ViewBag.PEDropDown, "Key", "Value", Model.PEDropDownSelectedValue), new { onchange = "document.location.href = '/ControllerName/ActionMethod?selectedValue=' + this.options[this.selectedIndex].value;" }))
The fourth argument in SelectList is the selected value. It must be passed using the model object.
When you call the particular action method, set the model object as below.
public ActionResult ActionMethod(string selectedValue)
{
ViewModelPE objModel = new ViewModelPE();
// populate the dropdown, since you lost the list in Viewbag
ViewBag.PEDropDown = functionReturningListPEDropDown();
objModel.PEDropDownSelectedValue = selectedValue;
return View(objModel);
// You may use the model object to pass the list too instead of ViewBag (ViewData in your case)
}

Resources