I am trying to build a store front.
StoreViewModel
public class StoreViewModel
{
public IEnumerable<GetStoreFrontItems_Result> StoreFrontItems { get; set; }
}
Index.aspx
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<StoreViewModel>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
..:: Gods Creation Taxidermy :: Store ::..
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<div class="maintext">
<h2 class="sectionHeader2">:: Gods Creation Taxidermy : Store Items ::</h2>
<br />
At times I end up with items and mounts that the owner never came to pick up, so I put them up for sale to help generate
some revenue for Gods Creation Taxidermy.
<strong>NOTE:</strong> Now before you freak out and think I'm going to sell your mount remember the items for sale are several years old
and the owner simply didnt make the final payment or for some reason left it here.
<% Html.DataList(Model.StoreFrontItems).Columns(7).Item(item =>
{
item.Template(storeItems =>
{%>
<div style="margin-right:45px; line-height:150%;">
<span><%: Html.ActionLink(storeItems.CategoryName, "List", new { #animal = storeItems.CategoryName });%></span>
</div>
<%-- <div style="margin-right:45px; line-height:150%;">
<span><% = galleryImage.ItemName%></span>
</div>
<div style="margin-right:45px; line-height:150%;">
<span><% = galleryImage.ItemPrice%></span>
</div>--%>
<%});
}).Render(); %>
</div>
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="MetaTagsContent" runat="server">
</asp:Content>
<asp:Content ID="Content4" ContentPlaceHolderID="LeftColumnContent" runat="server">
</asp:Content>
GetStoreFrontItems_Result is generated with function import. Here is the code from Index in StoreController:
[CanonicalUrlAttribute("Store")]
[CompressionFilter(Order = 1)]
[CacheFilter(CacheDuration = 120, Order = 2)]
public virtual ActionResult Index()
{
GodsCreationTaxidermyEntities context = new GodsCreationTaxidermyEntities();
var viewModel = new StoreIndexViewModel() { StoreFrontItems = context.GetStoreFrontItems() };
return View(viewModel);
Here are some screenshots, one showing the error and the other showing what gets displayed.
As far as the error is concerned from what you have shown as code it is impossible to answer why does it happen (although the error message seems more than pretty self explanatory). As far as the garbage characters are concerned they are caused by the Compression filter you are using on your action. Here's a blog post which explains perfectly fine the reason and how to fix it.
The proposed solution is to put the following in your Global.asax to cancel the effect of ASP.NET stripping the custom compression HTTP headers that your CompressionFilter might have added in case of an exception:
protected void Application_PreSendRequestHeaders()
{
// ensure that if GZip/Deflate Encoding is applied that headers are set
// also works when error occurs if filters are still active
HttpResponse response = HttpContext.Current.Response;
if (response.Filter is GZipStream && response.Headers["Content-encoding"] != "gzip")
response.AppendHeader("Content-encoding", "gzip");
else if (response.Filter is DeflateStream && response.Headers["Content-encoding"] != "deflate")
response.AppendHeader("Content-encoding", "deflate");
}
Related
i am using ASP.NET MVC2 to implement google custom search. i am able to connect to googleAPI, pass my query, get the results back in JSON format and map those to .NET classes. However, when i create a view to show those results i am receving an error.
public ActionResult SiteSearch(string query)
{
var googleSiteSearchClient = new GoogleSiteSearchClient();
var model = googleSiteSearchClient.RunSearch(query);
return View(model);
}
I create a strongly typed View based on Model and try to use a FOREACH loop to get the results
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>SiteSearch</h2>
<% foreach (var item in Model) { %>
<%: item.Kind %> <br />
<% } %>
</table>
</asp:Content>
i am receving this error
The model item passed into the dictionary is of type 'AASD2.Models.GoogleAPI.GoogleSearchResponse', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable`1[AASD2.Models.GoogleAPI.GoogleSearchResponse]'.
any suggestion, where i am doing wrong?
Seems like the result of googleSiteSearchClient is not a collection. The search result collection is probably a property on the result of googleSiteSearchClient.
Either use
<% foreach (var item in Model.WhatEverTheCollectionIsNamed) { %>
<%: item.Kind %> <br />
<% } %>
Or
public ActionResult SiteSearch(string query)
{
var googleSiteSearchClient = new GoogleSiteSearchClient();
var model = googleSiteSearchClient.RunSearch(query);
return View(model.WhatEverTheCollectionIsNamed);
}
I am new to MVC architecture and I am struggling to get the Button onclick. Please help me trace the issue. I have a Telerik TreeView control, which is populated. Some of the nodes have child nodes and some of them doesn't.
Please let me know what changes need to be made to fix the issue
Here I am struggling to get it working.
<%# Page Language="C#" MasterPageFile="~/Views/Shared/PostLogin.Master" Inherits="System.Web.Mvc.ViewPage<IEnumerable<applications>>" %>
<%# Import Namespace="ApplicationGrps" %>
<%# Register assembly="Telerik.Web.UI" namespace="Telerik.Web.UI" tagprefix="telerik" %>
<script runat="server" type="text/javascript">
protected void Page_Load()
{
ApplicationGrps.Visible = true;
ApplicationGrps.DataSource = ODS1;
ApplicationGrps.DataFieldID = "ApplicationName";
ApplicationGrps.DataFieldParentID = "ParentID";
ApplicationGrps.DataBind();
BindCheckedTags(ApplicationGrps);
}
protected void BindCheckedTags(RadTreeView treeView)
{
// Displays the checked nodes
}
protected void ODS2_Selecting(object sender, ObjectDataSourceSelectingEventArgs e)
{
e.InputParameters["ClientID"] = ViewData["ClientID"];
}
protected void btnSave_Click(object sender, EventArgs e)
{
//Iterate through the tree and get all the nodes that are checked and submit it.
}
</script>
<asp:Content ID="Content2" ContentPlaceHolderID="HeadContent" runat="server">
<link href="<%: Url.Content("~/Content/script-libraries/jquery-ui-1.7.2.custom/css/smoothness/jquery-ui-1.7.2.custom.css") %>"
rel="stylesheet" type="text/css" />
<script src="<%: Url.Content("~/Scripts/jquery-1.4.1.js") %>" type="text/javascript"></script>
</asp:Content>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<form id="form1" runat="server" method="post">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<div>
<telerik:RadTreeView id="AppModulesTreeView" runat="server" CheckBoxes="True" Visible="true" >
</telerik:RadTreeView>
<asp:ObjectDataSource ID="ODS1" runat="server"
SelectMethod="GetAllApplicationModules"
TypeName="ELS.BOS.Services.EntitlementProxy.EntitlementServiceClient">
</asp:ObjectDataSource>
<asp:ObjectDataSource ID="ODS2" runat="server"
SelectMethod="GetApplicationModMappedByClientID"
TypeName="ELS.BOS.Services.EntitlementProxy.EntitlementServiceClient"
onselecting="ODS2_Selecting">
<SelectParameters>
<asp:Parameter Name="ClientID" Type="String" />
</SelectParameters>
</asp:ObjectDataSource>
<%-- <telerik:RadButton runat="server" onclick="btnSave_Click"
Text="Save">
</telerik:RadButton>
<telerik:RadButton ID="btnCancel" runat="server" Text="Cancel"
>
</telerik:RadButton>--%>
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="btnSave_Click" />
</div>
</form>
</asp:Content>
Please let me know if I need to use javascript or jquery to get this working. Please show me some samples on how to fire btnSave_click on button control click.
Thanks!
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="btnSave_Click" />, asp:ObjectDataSource, ScriptManager, ... in an ASP.NET MVC application?
No.
In an ASP.NET MVC applications you don't use server side controls (no runat="server"). You don't PostBack. There is no ViewState. There is no code behind. There are no events. There are no script managers. There are no object data sources. All this is specific to WebForms and is no longer used in MVC.
In an ASP.NET MVC application you have a Controller, a Model and a View. The view contains standard HTML markup which could be generated with the aid of HTML helpers. To call the controller you could use a normal link:
<%= Html.ActionLink("link text", "actionName", "controllerName") %>
The controller contains actions which manipulate the model and choose the view to be rendered by passing it all the information it needs to show.
I would strongly recommend you start reading the tutorials here: http://asp.net/mvc about how MVC works and familiarize yourself with the very basics of this framework.
I cannot make sense of this...
The simplified code below OUGHT to insert a new form field of the current time's second value.
Instead, even though the list manipulation happens correctly (as verifiable within the controller and in the debug output), the View does render an additional element, but seems to be just a copy of the final field's value (prior to submit). This can be verified by changing a field prior to submit - the values stick and the new element is a duplicate of the submitted final value.
The part that really cooks my noodle is that if I trivially change the operation from an Insert() to an Add(), the Add() works as expected!!
Using this example Model:
public class MyViewData
{
List<string> stringData = new List<string>();
public List<string> StringData { get { return stringData; } }
}
And this Controller:
public class TestController : Controller
{
public ActionResult Index()
{
return View(new MyViewData());
}
[HttpPost]
public ActionResult Index(MyViewData data)
{
data.StringData.Insert(0, DateTime.Now.Second.ToString());
return View(data);
}
}
And this View:
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<Forms.Controllers.MyViewData>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Test
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<%
System.Diagnostics.Debug.WriteLine("---");
for (var i = 0; i < Model.StringData.Count; i++)
System.Diagnostics.Debug.WriteLine("{0}", Model.StringData[i]);
%>
<% using (Html.BeginForm()) { %>
<% for (var i = 0; i < Model.StringData.Count; i++) { %>
<%: Html.TextBoxFor(model => model.StringData[i])%></br>
<% } %>
<div><input type="submit" value="Do it" /></div>
<% } %>
</asp:Content>
This is the normal behavior of standard HTML helpers and is by design. When rendering the input field they will first look at the request POSTed values and only after in the ViewData and view model. This basically means that you cannot change POSted values in your controller action.
So if you have a form with an input field:
<%= Html.TextBoxFox(x => x.Id) %>
which is posted to the following action
[HttpPost]
public ActionResult Index(MyModel model)
{
model.Id = "some new value";
return View(model);
}
when rendering the view back the html helper will use the posted value. You could either write a custom html helper that does the job for you or handle it manually (absolutely not recommended but for the record):
<input type="text" name="StringData[<%= i %>]" value="<%= Model.StringData[i] %>" />
I am trying out ASP.Net MVC2 by building a small sample website which, amongst other features provides the user with a 'Contact Us' page. The idea is to allow a user to enter their name, email address, message subject and message. To send the message the user clicks on an ActionLink. This is the view:
<% Html.BeginForm(); %>
<div>
<%: Html.Label("Name")%>
<br />
<%: Html.TextBox("txtName", "",new { style = "width:100%" })%>
<br />
<%: Html.Label("Email address")%>
<br />
<%: Html.TextBox("txtEmail", "", new { style = "width:100%" })%>
<br />
<%: Html.Label("Subject")%>
<br />
<%: Html.TextBox("txtSubject", "", new { style = "width:100%" })%>
<br />
<%: Html.Label("Message")%>
<br />
<%: Html.TextBox("txtMessage", "", new { style = "width:100%" })%>
</div>
<div style='text-align: right;'>
<%:
Html.ActionLink("Send", "SentEmail", new { name = Html.g, sender = "txtEmail", subject = "txtSubject", message="txtMessage" })
%>
</div>
<% Html.EndForm(); %>
The idea is once the ActionLink has been clicked a method in the controller is called into which the username, email address, subject and message will be passed. This is the method in the controller:
public ActionResult SentEmail(string name, string sender, string subject, string message)
{
//Send email here and then display message contents to user.
ViewData["Name"] = name;
ViewData["Message"] = message;
ViewData["ThankyouMessage"] = "Thank you for contacting us. We will be in touch as soon as possible.";
return View();
}
However... when I click the link the values which are passed into the method are null. I have tried creating a route to do this but it doesn't work either. Should I be using another method?
Thank you,
Morris
Actually to achieve what you want to is easier than in your sample. Never heard about Model classes, Model Binder and strong typed views? Here thery are
Model class
public class ContactUsModel
{
public string Name { get; set; }
public string Email { get; set; }
public string Subject { get; set; }
public string Message { get; set; }
}
Then in your controller you should have two action: the first that show the form with default values and the second that receive the form with the data placed by the user. These two actions maps exactly to the HttpGet and HttPost verbs.
[HttpGet]
public virtual ActionResult ContactUs() {
ContactUsModel model = new ContactUsModel();
return View(model);
}
[HttpPost]
public virtual ActionResult ContactUs( ContactUsModel model ) {
//e.g. Save the contact request to database
}
To use this your view shal be strong typed to the ContactUsModel class
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<ContactUsModel>" %>
<% using (Html.BeginForm()) { %>
<div>
<%: Html.LabelFor(model => model.Name) %><br />
<%: Html.TextBoxFor(model => model.Name, new { style = "width:100%" })%>
</div>
<div>
<%: Html.LabelFor(model => model.Email) %><br />
<%: Html.TextBoxFor(model => model.EMail, new { style = "width:100%" })%>
</div>
<div>
<%: Html.LabelFor(model => model.Subject) %><br />
<%: Html.TextBoxFor(model => model.Subject, new { style = "width:100%" })%>
</div>
<div>
<%: Html.LabelFor(model => model.Message) %><br />
<%: Html.TextAreaFor(model => model.Message, new { style = "width:100%" })%>
</div>
<div>
<input type="submit" value="Save" />
</div>
<% } %>
the magic of everything this is called ModelBinder. Please read more and more about MVC here.
The action link isn't going to trigger a http post nor will it pass in the values of your form fields, just a http get and not passing through any form data - ideally you'd use an input submit button to post the data. What is certain is that it is good practise that any request that causes creating/updating of data should be done via a http post.
Submit button would just be like.
<input type="submit" value="Send" />
You then have several ways of accessing the form data firstly you could use a FormCollection to access the data
[HttpPost]
public ActionResult SendEmail(FormCollection collection)
{
string email = collection["txtEmail"];
...
}
Secondly you could use the method parameters and rely on model binding, but you must make sure field names match the parameter name so
<%: Html.TextBox("txtEmail", "", new { style = "width:100%" })%>
...would require...
[HttpPost]
public ActionResult SendEmail(string txtEmail)
{
...
}
If this form isn't being posted to the same action thats return the view then you'd also need to change your begin form tag, ideal you should use 'using' with it as well. So you'd get:
<% using (Html.BeginForm("SendEmail", "<controller-name>"))
{ %>
.... form fields in here ...
<input type="submit" value="Send" />
<% } %>
If the button isn't suitable for your design you could use something like:
<input type="image" src="<%: Url.Content("~/Content/images/myimage.gif") %>" value="Send" />
This would have the same effect. To trigger a post from an a tag though you'd need to look at using javascript, I can't remember the exact syntax but off hand I think if you used jquery you'd be looking at something like: (form a single form page only)
Send
But then you create a dependency on javascript where as really you should try have your site degrade gracefully so it can be used by visitors with javascript disabled. There are perhaps more advanced way of achieving this whilst meeting design requirements but that can get heavily into client side code which is probably outside of what you want for your sample.
Is it possible that two different views use the same controller?
I have very complex controller that displays some data. Now I need to display this data (which is retrieved using ajax) in two partial views because I want to place them on different positions in layout.
the View() function can be passed arguments, for instance:
return View(); // The view with the same name as the action.
return View("MyView") // The view named "MyView"
There are a few more overloads too. Does this fit the bill?
If not, why not partial views, for instance, given this model:
public class BlogItem
{
public string Title { get; set; }
public int Id { get; set; }
}
And this action:
public ActionResult Index()
{
var items = new List<BlogItem>
{
new BlogItem { Title = "Test Blog Item", Id = 1 }
};
return View(items);
}
And this view:
<%# Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<List<BlogItem>>" %>
<asp:Content ContentPlaceHolderID="MainContent" runat="server">
<% Html.RenderPartial("List", Model); %>
<% Html.RenderPartial("Icon", Model); %>
</asp:Content>
I can have two partial views using the same model:
List:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<List<BlogItem>" %>
<ul>
<% foreach (var item in Model) { %>
<li><%= item.Title %></li>
<% } %>
</ul>
Icon:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<List<BlogItem>" %>
<div>
<% foreach (var item in Model) { %>
<div class="icon"><img src="..." /></div>
<div class="text"><%= item.Title %></div>
<% } %>
</div>
Would that work?
Based on my understanding so far, you want one controller action to return two views. I somehow think that this is not possible.
You have mentioned that the views are used to display identical data is different ways. My suggestion would to return a JsonResult from the controller action and build the view client side.