Error :There is No ViewData - asp.net

I am new to mvc4(asp.net(vb.net), razor engine )..
This is annoying me. It works perfectly on the load and if I complete the form and submit it.
It shows the following error.
There is no viewdata of type'iEnumerable'that has
the key CustomerGroupId
In Controller(Get )
Function Create() As ActionResult
_Engine = CType(HttpContext.Application("Engine"), Engine)
ViewBag.CustomerSubGroup = New SelectList(_Engine.RteCustomerSubGroupFactory.CodeFactory.Values)
ViewBag.RateList = New SelectList(_Engine.RteRateListFactory.Values)
Return View()
End Function
In View(.vbhtml)
<table>
<tr><td>Code </td><td>#Html.TextBox("Code")</td></tr>
<tr><td>Name</td><td>#Html.TextBox("Name")</td></tr>
<tr><td>Customer Sub Group Name </td><td>#Html.DropDownList("CustomerSubGroupId")</td></tr>
<tr><td>Rate List</td><td>#Html.DropDownList("RateList")</td></tr>
<tr><td>IsDisabled</td><td>#Html.CheckBox("IsDisabled")</td></tr>
Shows the error in the line of
<tr><td>Customer Sub Group Name </td><td>#Html.DropDownList("CustomerSubGroupId")</td></tr>

In your Action of your Controll,er you have to add a key with the same Id you have used on the View, to apply on the DropDownList, for sample:
ViewBag.CustomerSubGroupId = New SelectList(_Engine.RteCustomerSubGroupFactory.CodeFactory.Values)
ViewBag.RateList = New SelectList(_Engine.RteRateListFactory.Values)
Return View()
in view, you can use:
#Html.DropDownList("CustomerSubGroupId")
#Html.DropDownList("RateList")
The reason is the ViewBag encapsulates the ViewData, that's why the message says you do not have the key on the ViewData.

Related

Displaying of the data in the gridview based on the search criteria using generics concept of .net

i am new to .net..i have to develop an asp.net application.
The UI of the web page will have a Data-bound Grid control on the Home page and there will be a Textbox where users can enter their search criteria.
I know to do this by using ado.net concept...
But i am supposed to do it using generics concept.How can i store the values in the generic list or dictionary of .net and filter the data based on the text entered in the text box.
Please help me out..
Thanks in advance..
You can indeed bind a GridView to List<T>, I do it all the time, like this:
Create a POCO for the data
public class SomeData
{
public string SomeField {get;set;}
public string SomeOtherField {get;set;}
}
Build the list (either manually or as a result a DB query) e.g.
var mylist = new List<SomeData>();
var myitem = new SomeData()
{
SomeField = "Hello",
SomeOtherField = "World"
};
To Filter the data do something like this:
myfilter = MyTextBox.Value;
mylist = mylist.Where(somedata => somedata.SomeField.Equals(myfiltervalue)).ToList();
Bind it to the GridView
mygridview.DataSource = mylist;
mygridview.DataBind();
And this is it!!
I assume you know ado.net and how to bind gridview.
You just need to iterate through your database resultset and add it to list and bind it.
Following link might help you to begin with:
http://www.aspsnippets.com/Articles/How-to-bind-GridView-with-Generic-List-in-ASPNet-using-C-and-VBNet.aspx
Pass your textbox value to your database query/stored procedure as parameter and return the result based on search value.
Edit:
You may want to use FindAll, Find method.
Check below link:
http://msdn.microsoft.com/en-us/library/aa701359(VS.80).aspx

Object reference not set to an instance of an object error

I have Default.aspx and Upload.aspx.
I'm passing Id through query string to default.aspx(like:http://localhost:3081/default.aspx?Id=1752).In default page i have a link button to open the upload.aspx to upload file.When i use the Request.QueryString["Id"] in upload.aspx,it is showiing error as "Object reference not set to an instance of an object".I'm dealing with RadControls.
To open when i click a link(OnClientClick="return ShowAddFeedBackForm()") i have code like:
<script>
function ShowAddFeedBackForm() {
window.radopen("Upload.aspx", "UserListDialog");
return false;
}
</script>
I'm using detailsview in upload page with a textbox and a fileupload control.
code to bind when a file upload in upload.aspx
protected void DetailsView1_ItemInserting(object sender, DetailsViewInsertEventArgs e)
{
string qString = Request.QueryString["Id"].ToString();
if (DetailsView1.CurrentMode == DetailsViewMode.Insert)
{
//string qString = Request.QueryString["Id"].ToString();
//int Projectid = Convert.ToInt32(Session["ProjectId"]);
ProTrakEntities objEntity = new ProTrakEntities();
TextBox txtTitle = DetailsView1.FindControl("txtTask") as TextBox;
//RadComboBox cmbStatus = DetailsView1.FindControl("cmbStatus") as RadComboBox;
//var id = (from project in objEntity.Projects where project.ProjectId == Projectid select project).First();
RadComboBox cmbTaskType = DetailsView1.FindControl("cmbTasktype") as RadComboBox;
//RadComboBox cmbTaskPriorty = DetailsView1.FindControl("cmbPriority") as RadComboBox;
string Description = (DetailsView1.FindControl("RadEditor1") as RadEditor).Content;
var guid = (from g in objEntity.Projects where g.ProjectGuid == qString select g).First();
int pID = Convert.ToInt32(guid.ProjectId);
ProjectFeedback objResource = new ProjectFeedback();
objResource.ProjectId = pID;
objResource.Subject = txtTitle.Text;
objResource.Body = Description;
objResource.CreatedDate = Convert.ToDateTime(System.DateTime.Now.ToShortDateString());
objResource.FeedbackType = cmbTaskType.SelectedItem.Text;
objEntity.AddToProjectFeedbacks(objResource);
objEntity.SaveChanges();
DetailsView1.ChangeMode(DetailsViewMode.ReadOnly);
ClientScript.RegisterStartupScript(Page.GetType(), "mykey", "CloseAndRebind('navigateToInserted');", true);
}
}
Getting error at querystring statement-"Object reference not set to an instance of an object"
The query string is not inherited when you open a new page. You have to include the id in the URL, i.e. Upload.aspx?id=1752.
Edit:
A simple solution would be to just copy the search part of the page URL:
window.radopen("Upload.aspx" + document.location.search, "UserListDialog");
However, typically you would use the id value that you picked up from the query string in the server side code and generate client code to use it.
I am not sure but if I had to guess I would question whether the window object has been instantiated at the time you call radopen in the script section of your page. You should put a msgbox before the call window.radopen() call to print the contents of the window object if it is null that is your problem otherwise this will take more digging. Just my two cents.
I also noted that if the guid query returns no results the call to .First() will cause this error as well. Just another place to check while researching the issue.
There is one last place I see that could also throw this error if the objEntities failed to construct and returned a null reference then any call to the properties of the object will generate this error (i.e objEntitiey.Projects):
ProTrakEntities objEntity = new ProTrakEntities();
var guid = (from g in objEntity.Projects where g.ProjectGuid == qString select g).First();
This error is occurring because, as the other answerer said, you need to pass the ID to the RadWindow since the RadWindow doesn't know anything about the page that called it. You're getting a null reference exception because the window can't find the query string, so it's throwing an exception when you try to reference .ToString().
To get it to work, make your Javascript function like this:
function ShowAddFeedBackForm(Id) {
window.radopen(String.format("Upload.aspx?Id={0}", Id), "UserListDialog");
return false;
}
In the codebehind Page_Load event of your base page (ie, the page that is opening the window), put this:
if (!IsPostBack)
Button.OnClientClick = string.Format("javascript:return ShowAddFeedBackForm({0});", Request.QueryString["Id"]);
Of course, Button should be the ID of the button as it is on your page.

avoiding the use of the viewdata enumerable object in controller - reg

I have 2 points for today
I. I have a controller in which i have a public static method for getting the details for a checkbox like
public static List<country> GetCountryLists()
{
List<country> countries = new List<country>();
country _country = new country() { countryname = "Select a country", value = "0" };
country _country1 = new country() { countryname = "India", value = "India" };
country _country2 = new country() { countryname = "USA", value = "USA" };
countries.Add(_country);
countries.Add(_country1);
countries.Add(_country2);
return countries;
}
Currently , i am using this function via
ViewData["country"] = GetCountryLists();
is it ok for me to use this same function like this one in the view, so that I do not need to use the viewdata object,
<%: Html.DropDownList("country", new SelectList(UserController.GetCountryLists(), "value", "countryname", "0"))%>
Kindly suggest me the best practice.
II. Also i have another query, when i use the same id & name for the radiobuttons, validation at the client side is working fine.
If I use the same condition for a group of checkboxes, i get do not get the checkboxes highlighted during client validation and only during server validation, i get the error message, but the controls [checkboxes] do not have a red border indicating the error.
I have used my own html helper to generate the checkboxlist as per http://www.asp.net/mvc/tutorials/creating-custom-html-helpers-cs
Kindly let me know if there is any possible solution for this problem too. As i am new to asp.net mvc2, i am not sure of using these.. kindly suggest me accordingly.
is it ok for me to use this same function like this one in the view, so that I do not need to use the viewdata object
No, this is not good practice and violation of the MVC pattern for various reasons. Views shouldn't pull information. They should only use the information that it is being passed in the view model. It is the controller's responsibility to invoke various methods to fetch data and then construct a view model containing all the necessary information needed for the view and then pass this view model to the view. So here's the suggested way:
<%= Html.DropDownListFor(
x => x.Country,
new SelectList(Model.Countries, "value", "countryname")
) %>
or with the ugly/weakly typed/avoid to use/requiring magic strings ViewData:
<%= Html.DropDownList(
"Country",
new SelectList((IEnumerable)ViewData["Countries"], "value", "countryname")
) %>
and it is the responsibility of the control to populate either the view model properties or the ugly ViewData.
As far as your second question is concerned you will need to show your code in order to see what is wrong with it. From your description what I can say is that you cannot have two elements with the same id in the DOM or you get invalid markup.

enable html dropdown through controller in mvc

i have an scenario where i have to perform some action according to selection of the
dropdown .
for basic refrence you can use the example of country,state,city.
i am able to populate the country list at that time i have set the other two drop downs to
disable.
after the countries are populated i want to select the state.it is getting populated .
two problems
1) how to retain the state of country ddl as it is coming back to its orisnal state.
2) how to enable the drop down through my controller.
myview code
Country
<p>
<label>
State</label>
<%=Html.DropDownList("ddlState", ViewData["ddlState"] as SelectList, "--not selected--",new { onchange = "document.forms[0].submit()", disabled = "disabled" })%>
</p>
<p>
<label>
City</label>
<%=Html.DropDownList("ddlCities", ViewData["ddlCities"] as SelectList, "--not selected--", new { onchange = "document.forms[0].submit()", disabled = "disabled" })%>
</p>
my controller code
public ActionResult InsertData()
{
var customers = from c in objDetailEntity.Country
select new
{
c.Cid,
c.Cname
};
SelectList countriesList = new SelectList(customers.Take(100), "Cid", "Cname");
ViewData["ddlCountries"] = countriesList;
SelectList EmptyState = new SelectList(customers);
ViewData["ddlState"] = EmptyState;
ViewData["ddlCities"] = EmptyState;
Session["ddlSesCountry"] = countriesList;
return View();
}
//
// POST: /RegisTest/Create
[HttpPost]
public ActionResult InsertData(FormCollection collection)
{
try
{
CountryId = Convert.ToInt16(Request.Form["ddlCountries"]);
stateid = Convert.ToInt16(Request.Form["ddlState"]);
if (CountryId > 0 && stateid <= 0)
{
var stateslist = from c in objDetailEntity.State
where c.Country.Cid == CountryId
select new
{
c.Sid,
c.Sname
};
SelectList stateList = new SelectList(stateslist.Take(100), "Sid", "Sname");
ViewData["ddlState"] = stateList;
Session["StateList"] = stateList;
ViewData["ddlCities"] = stateList;
}
if (stateid > 0)
{
var citieslist = from c in objDetailEntity.City
where c.State.Sid == stateid
select new
{
c.Ctid,
c.Cityname
};
SelectList cityList = new SelectList(citieslist.Take(100), "Ctid", "Cityname");
ViewData["ddlCities"] = cityList;
ViewData["ddlState"] = Session["StateList"];
}
ViewData["ddlCountries"] = Session["ddlSesCountry"];
return View();
}
catch
{
return View();
}
}
My choice would be not to post back the form at all. I would write an action in the controller that takes a CountryID and returns a JsonResult holding a list of states. The onchange event could call a jQuery function that uses AJAX to call this action, loads the new list, and enables the second drop-down list.
However, if you stick with the postback, here's why it's not working:
The Country list isn't retaining its selected value because the view is being reloaded from scratch each time and you're setting it to "not selected." The SelectList constructor has an overload that takes a "SelectedItem" object as the fourth parameter. When you initialize your SelectList, you should pass the appropriate value to this parameter, and not force it in the View.
You need to write an "if" clause in your View to choose whether or not to enable the list based on some criteria. You could bind to a ViewModel that has a Boolean property like "EnableStates," or you could use something like the count of values in the StateList - if the count is greater than zero, enable it, for example.
A tricky thing to get used to when you move from Web Forms to MVC is that you don't have ViewState anymore - your application is stateless. There's nothing that "remembers" what value is selected in a drop-down for you, you have to set it each time you load the page.
I recommend using JSON & jQuery - like this posted answer.

Error while updating Database record with Entity Framework on ASP.NET MVC Page

I have an ASP.NET Page that updates registered User Address Details for a selected record.
Below is the update method that I am calling from my controller.
When I am calling the ApplyPropertyChanges method, I am getting an error. Did anyone run into the same error while updating the record with Entity Framework?
Appreciate your responses.
Error message:
The existing object in the ObjectContext is in the Added state. Changes can only be applied when the existing object is in an unchanged or modified state.
My Update method:
[HttpPost]
public bool UpdateAddressDetail([Bind(Prefix = "RegUser")] AddressDetail regUserAddress, FormCollection formData)
{
regUserAddress.AD_Id = 3;
regUserAddress.LastUpdated = HttpContext.User.Identity.Name;
regUserAddress.UpdatedOn = DateTime.Now;
regUserAddress.AddressType = ((AddressDetail)Session["CurrentAddress"]).AddressType ?? "Primary";
regUserAddress.Phone = ((AddressDetail)Session["CurrentAddress"]).Phone;
regUserAddress.Country = ((AddressDetail)Session["CurrentAddress"]).AddressType ?? "USA";
miEntity.ApplyPropertyChanges(regUserAddress.EntityKey.EntitySetName, regUserAddress);
miEntity.SaveChanges();
return true;
}
The error is the object is detached from the context, and ApplyPropertyChanges thinks the object is added because it isn't attached. So you would need to query from the data context or get an attached form and then apply the changes then.
HTH.
What Dave Said
+
You need to Attach() the disconnected entity to your object context:
http://msdn.microsoft.com/en-us/library/system.data.objects.objectcontext.attach.aspx
miEntity.Attach(regUserAddress);
miEntity.SaveChanges();
Just add the following code before miEntity.SaveChanges():
miEntity.Entry(regUserAddress).State = EntityState.Modified;
First select the record (object entity), search by key through the ObjectContext. For example if the search ArticleSet EntitySet called for there to record, and once you get it modified its properties with new values and then call SaveChanges() of ObjectContext.
Example:
ObjectQuery<Article> myArt=Context.ArticleSet.Where myArt = (row => row.ArticleId == value);
myArt.Description=" new value ";
etc. ..
etc ...
Context.SaveChanges ();

Resources