LINQ to SQL datacontext passing data to a grid in view - asp.net-mvc

just trying to fathom out LINQ to SQL and datacontext class.
I am learning MVC coding and have a database with some test data.
I have created my datacontext and have been able to get this far in the controller.
ClientClassesDataContext context2 = new ClientClassesDataContext();
var result2 = context2.up_GetClient(4,1);
up_GetClientResult myObject = result2.SingleOrDefault();
return View(myObject);
This returns a list of clients, my part I'm stuck at is how to pass this to the view and put it in a grid style.
Even passing the object to the view with only one row of data, I'm kinda stuck on how t even access items and display in, say, a text box.
Even just any pointers or links on best practice for LINQ to SQL etc would be a great help. There seems to be a lot of varying info out there.
The View is empty with the code below.
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage<dynamic>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Test</h2>
</asp:Content>
Any help or pointers would be appreciated.

Model:
public class MyModel
{
IEnumerable<client> _getClient { get; set; }
}
Controller:
ClientClassesDataContext context2 = new ClientClassesDataContext();
var result2 = context2.up_GetClient(4,1);
MyModel _mymdl=new MyModel();
_mymdl._getClient = result2.SingleOrDefault();
return View(_mymdl);
VIew:
#model ProjectName.web.MyModel
#{
ViewBag.Title = "";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div>
foreach (var item in Model._getClient)
{
//Add your login to create Table
}
</div>

Related

AllowHtml not working for ASP.Net Mvc 3 site

We're trying to use the [AllowHtml] decoration on one of our ViewModel properties so that we can avoid the YSOD:
A potentially dangerous Request.Form value was detected from the
client (RequestText="<br>").
when we try to submit html text, like: <br>. We want to then use Server.HtmlEncode within the controller action to prevent attacks, but when we decorate the property with [AllowHtml] it has no affect, and if we try to use [ValidateInput(false)] on the controller action, it has no effect either. We saw a StackOverflow Post saying that in MVC 3 RC2 that you have to add:
ModelMetadataProviders.Current = new
DataAnnotationsModelMetadataProvider(); to the global.asax
We tried that too, even though we are using the release version of MVC 3, not RC2, but that had no effect either. Does anyone know how to fix this?
Model:
namespace UI.Models.ViewModel
{
public class CustomerRequestSupport
{
/// <summary>
/// Gets or Sets the textual description entered by the Customer for
/// the support requested.
/// </summary>
[AllowHtml]
public string RequestText { get; set; }
}
}
Controller:
[HttpPost]
[TabsActionFilter]
public ActionResult RequestSupport(CustomerRequestSupport collection)
{
if (ModelState.IsValid)
{
Ticket ticket = new Ticket();
ticket.Requestor = LoggedInCustomer;
ticket.Summary = "General Support Ticket";
ticket.Notes = Server.HtmlEncode(collection.RequestText);
var errors = _ticketService.SubmitTicket(ticket);
if (errors.Any())
{
ModelState.AddModelError("collection",
String.Format("An error has occurred in your Request for Support: " +
"{0} Please try again later or call the help desk " +
"for immediate assistance.",
errors.Aggregate((acc, st) => acc + " " + st)));
}
else
{
TempData["FlashMessage"] = String.Format("Your request for support has been " +
"submitted, the Ticket Number is: {0}.", ticket.TicketNumber);
return AutoMapView<CustomerDetails>(View("Details", base.LoggedInCustomer));
}
}
//needed for tabs to show
ViewData.CustomerContactSet(base.LoggedInCustomer);
return View();
View:
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<UI.Models.ViewModel.CustomerRequestSupport>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Request Support
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="PageTitle" runat="server">
Request Support
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="MainContent" runat="server">
<% using (Html.BeginForm())
{ %>
<%= Html.ValidationSummary() %>
<h2>Enter a description of the support needed</h2>
<%: Html.TextAreaFor( m => m.RequestText, 4, 90, null) %>
<input type="submit" value="Submit" />
<% } %>
</asp:Content>
<asp:Content ID="Content4" ContentPlaceHolderID="JavaScriptContent" runat="server">
</asp:Content>
You gotta be doing something wrong. Unfortunately as you haven't shown your example we cannot know what you are doing wrong. So let me write you a full working example:
Model:
public class MyViewModel
{
[AllowHtml]
public string RequestText { get; set; }
}
Controller:
public class HomeController: Controller
{
public ActionResult Index()
{
var model = new MyViewModel
{
RequestText = "<strong>Hello World</strong>";
};
return View(model);
}
[HttpPost]
public ActionResult Index(MyViewModel model)
{
return View(model);
}
}
View:
#model MyViewModel
#using (Html.BeginForm())
{
#Html.TextAreaFor(x => x.RequestText)
<button type="submit">OK</button>
}
So you gotta be doing something different than what I showed here. What is it?
In his answer Darin is definitely onto something when he asks
So you gotta be doing something different than what I showed here.
What is it?
I am guessing you have something else affecting the ASP.NET pipeline that is accessing the FormCollection prior to your [AllowHtml] being taken into account. Off the top of my head some common ASP.NET MVC OSS libraries that touch the pipeline are ELMAH, Glimpse, WebActivator, MvcContrib, there are many more but you get the idea.
I have to believe you are using one of the tools above or something similar. Assuming you are make sure you are on the latest release of each and check their open bug reports.
Finally, a quick way to determine if its your code, your MVC instance or an OSS library would be to create a test project. Try creating a vanilla ASP.NET MVC project. Ensure that AllowHtml works. Then add in your various OSS components until it breaks. Just be sure when you are adding in OSS components that the versions match what you are using in your current project.

How to fetch one row from db in asp mvc

ASP.net mvc in new for me, for some time I used php (no mvc), but now i'm interested, how I can fetch one row from db? without foreach, for example in title...
here is some code:
controller
public ActionResult Index()
{
var pages = (from page in db.Pages where page.PageName == "index" select page).ToList();
return View(pages);
}
view:
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
<% foreach (var item in Model)
{ %>
<%= Html.Encode(item.Text) %>
<% }
%>
</asp:Content>
In your controller, instead of .ToList() you can use the .FirstOrDefault() method, this will return only the first row from the database.
Then in your view you won't need the foreach.
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
<%= Html.Encode(item.Model.Text) %>
</asp:Content>
What you're doing there is creating a List datatype variable and passing it in as the Model to your view. Assuming this is the only piece of data your page needs. Here's what you would do;
public ActionResult Index()
{
string page = db.pages.where(p => p.PageName == "index").FirstOrDefault().PageName;
return View(page);
}
There in your page, Model will now be that single string value and you can do this;
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
<%= Model %>
</asp:Content>
Although it is best practice to create a ViewModel for the page with the just the properties your page will need and pass that in as the Model.
public class MypageViewModel
{
public string PageName { get; set; }
}
Then do this in the controller
public ActionResult Index()
{
MypageViewModel MyModel = new MypageViewModel();
MyModel.PageName = db.pages.where(p => p.PageName == "index").FirstOrDefault().PageName;
return View(MypageViewModel);
}
Hope that helps.
If you are using Entity Framework:
var singleItem = db.pages.Find(id);
This will use the Primary Key of your entity.
If you have a composite primary key consisting of multiple properties, Find will still work (because it can take multiple values):
var singleItem = db.pages.Find(key1, key2);

ASP.Net MVC Model problems

Can you please help me understand what is the issue with generic collection? Thanks in advance!
Error: The model item passed into the dictionary is of type 'System.Collections.Generic.List1[DomainModel.Product]', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable1[DomainModel.Entities.Product]'.
MODEL:
namespace DomainModel.Concrete
{
public class SqlProductsRepository : IProductsRepository
{
private Table<Product> productsTable;
public SqlProductsRepository(string connString)
{
productsTable = (new ProaductDataContext(connString)).GetTable<Product>();
}
public IQueryable<Product> Products
{
get { return productsTable; }
}
}
}
INTERFACE
namespace DomainModel.Abstract
{
public interface IProductsRepository
{
IQueryable<Product> Products { get; }
}
}
VIEW
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/ViewMaster.Master"
Inherits="System.Web.Mvc.ViewPage<IEnumerable<DomainModel.Entities.Product>>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Products
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<% foreach (var product in Model)
{ %>
<div class = "item">
<h3> <%=product.Name%></h3>
<%= product.Description%>
<h4><%= product.Price.ToString("c")%></h4>
</div>
<%} %>
</asp:Content>
The error message tells you all your need to know;
The model item passed into the dictionary is of type
'System.Collections.Generic.List1[DomainModel.Product]',
but this dictionary requires a model item of type
'System.Collections.Generic.IEnumerable1[DomainModel.Entities.Product]'.
If you look at your view you can see
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/ViewMaster.Master"
Inherits="System.Web.Mvc.ViewPage<IEnumerable<DomainModel.Entities.Product>>" %>
The Inherits="System.Web.Mvc.ViewPage<IEnumerable<DomainModel.Entities.Product>>" is what's tripping you up. You're passing in an IEnumerable of DomainModel.Product, but you're expecting something else. It's a bit strange you have two classes named the same within close to the same namespace, but never mind, you need to ensure you're using the same class, in the same namespace in both the controller and the view.
So I'd try changing your view to become
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/ViewMaster.Master"
Inherits="System.Web.Mvc.ViewPage<IEnumerable<DomainModel.Product>>" %>
Then try to figure out why you have two Product classes :)

ASP.net MVC2 Passing data between strongly typed views

I have the following MVC2 view that is strongly typed with a viewmodel, the viewmodel contains a list of values from one db table, I need to display a single value from a second table in the view, this is my view code
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<CustomerDatabase.WebUI.Models.CustomerSitesListViewModel> " %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Customer Sites
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<% foreach (var customerSite in Model.CustomerSites) { %>
<% Html.RenderPartial("CustomerSiteSummary", customerSite); %>
<%} %>
</asp:Content>
This is the viewmodel, notice i am including a Customer member in the viewmodel as i want to display the customer name in addition to the list of customer sites
namespace CustomerDatabase.WebUI.Models
{
public class CustomerSitesListViewModel
{
public IList<CustomerSite> CustomerSites { get; set; }
public PagingInfo PagingInfo { get; set; }
public Customer customer { get; set; }
}
}
This is my controller code for the view
public ViewResult List([DefaultValue(1)] int page)
{
var customerSitesToShow = customerSiteRepository.CustomerSites;
var viewModel = new CustomerSitesListViewModel
{
CustomerSites = customerSitesToShow.Skip((page - 1) * PageSize).Take(PageSize).ToList(),
PagingInfo = new PagingInfo
{
CurrentPage = page,
ItemsPerPage = PageSize,
TotalItems = customerSitesToShow.Count()
}
};
return View(viewModel); //Passed to view as ViewData.Model (or simply model)
}
This is my partial view that renders the list,
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<CustomerDatabase.Domain.Entities.CustomerSite>" %>
<div class="item">
<div class="customer-list-item">
<h2><%:Model.customer.CustomerName%></h2>
<%: Model.AddressLine1 %>
<%: Model.AddressLine2%>
Although intellisense lets me access the customer object from the view with
<h2><%:Model.customer.CustomerName%></h2>
An error is thrown when i navigate to the view,
Object reference not set to an instance of an object.
Source Error:
Line 7: <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
Line 8: <% foreach (var customerSite in Model.CustomerSites) { %>
Line 9: <%:Model.customer.CustomerName%>
Line 10: <% Html.RenderPartial("CustomerSiteSummary", customerSite); %>
Line 11: <%}
I think the error is due to the view rendering a list, i tried changing the viewmodel member to
public IList<Customer> {get; set;}
but this doesn't work either.
Can anyone suggest a way i can achieve this or offer any advice on where i am going wrong this is one problem i haven't been able to resolve after hours or researching on the Internet?
It looks like one of the model properties are not initialized. If you add a breakpoint on that line and check the variables I'm pretty sure you'll find 1 that is null.

ASP.NET MVC best approach to provide data to Views

I'd like to to provide data to a table in the views. The data is not only from database but also from a csv file.
Should I store the data in the ViewData, or should I store it in a object and pass it to views? What is the best approach, or any other methods I can use? Thx!
Use strongly-typed views and pass the object directly to the view:
// Model (PersonRepository class)
public static Person Get(Int32 id) {
using (MyContext context = new MyContext()) {
Person p = context.Person.First(p => Person.id == id);
return p;
}
}
...
// Controller
public ActionResult Show(Int32 id) {
return View(PersonsRepository.Get(id);
}
...
// View
<%# Page Inherits="System.Web.Mvc.ViewPage<Models.Person>" Title="" Language="C#" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
<%= Model.Id %> <br />
<%= Model.Name %> <br />
</asp:Content>
You should create a model object, fill it in the controller with data from heterogeneous sources and pass that model to the view.

Resources