I have trouble with building a web service can read information of NBA players from a txt file and then display it on the web page.
Firstly, I build a class in the Models folder.
namespace zuoye4.Models
{
public class Players
{
public string Registration_ID { get; set; }
public string Player_name { get; set; }
public string Team_name { get; set; }
public DateTime Date_of_birth { get; set; }
}
}
Secondly I create a Controller to read file and add all players to an list. I also define a GetAllPlayers method to return the list.
Testing shows this
Then I create a html page to display the list. Here is my code.
<!DOCTYPE html>
<html>
<head>
<title>PLALYERS</title>
<meta charset="utf-8" />
</head>
<body>
<div>
<h2>All Players</h2>
<ul id="players" />
</div>
<div>
<h2>Search by ID</h2>
<input type="text" id="prodId" size="5" />
<input type="button" value="Search" onclick="find();" />
<p id="product" />
</div>
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.0.3.min.js"></script>
<script>
var uri = 'api/Players';
$(document).ready(function () {
// Send an AJAX request
$.getJSON(uri)
.done(function (data) {
// On success, 'data' contains a list of players.
$.each(data, function (key, item) {
// Add a list item for the player.
$('<li>', { text: formatItem(item) }).appendTo($('#playerList'));
});
});
});
function formatItem(item) {
return item.Registration_ID + ': $' + item.Player_name;
}
</script>
</body>
</html>
It should shows something like this.
But I get nothing.
What I've done wrong???
Here is the tutorial follow.
https://www.asp.net/web-api/overview/getting-started-with-aspnet-web-api/tutorial-your-first-web-api
You seem to be appending the players list item to an element with id "playerList":
$('<li>', { text: formatItem(item) }).appendTo($('#playerList'));
Problem is, "playerList" doesn't seem to exist, I see you have a "players" instead?
<ul id="players" />
Related
I have a knockout model that is automatically created from a C#-ViewModel:
ViewModels:
public class SearchModel
{
public ActualLocationModel Location { get; set; }
}
public class ActualLocationModel
{
public string Address { get; set; }
}
search.js:
function Search(model) {
var self = this;
self._model = model;
ko.applyBindings(self._model, document.getElementById("searchForm"));
$('#submitButton').click(function () {
alert(self._model.ActualLocation.Address); // proof!
});
}
Search.cshtml:
#model ViewModels.SearchModel
<div id="searchForm">
<input data-bind="value: ActualLocation.Address" type="text">
<input type="submit" id="submitButton" value="Find" />
</div>
<script type="text/javascript">
$(function () {
window.search= new Search(#Html.Raw(Json.Encode(Model)));
});
</script>
So, the databinding is working as expected as long as I enter the values by hand. But in my case the values are filled automatically by geolocation. In this case the binding doesn't do what it should be (output is always null). Is there a way to get the Knockout databinding working on automatic filled inputs?
Thanks for any help!
Alright, here are the relevant bits to get this working for you:
<script type="text/javascript">
$(function() {
window.search = new Search(JSON.parse('#Html.Raw(Json.Encode(Model))'));
});
</script>
Notice we're parsing the model which was converted to JSON so we can use the resulting Javascript object in our model. If you want to go straight from JSON to your model, consider the ko.mapping library, though it is no longer actively maintained, I believe.
<form id="searchForm">
<input data-bind="value: Location.Address" type="text">
<input type="submit" id="submitButton" value="Find" />
</form>
Here, notice the change from AdditionalLocation.Address to just Location.Address.
function Search(model) {
var self = this;
self._model = model;
ko.applyBindings(self._model, document.getElementById("searchForm"));
$('#submitButton').click(function () {
alert(self._model.Location.Address); // proof!
});
}
Finally, we fix up the alert to reflect the shape of our data (AdditionaLocation to Location).
Using the above, everything works as expected for me.
Ok, so I have this class:
public class BackstoreInventoryUtility
{
public BackstoreInventoryInfo Item { get; set; }
public List<ItemListingUtility> ListItemUtility { get; set; }
public BackstoreInventoryUtility()
{
Item = new BackstoreInventoryInfo();
ListItemUtility = new List<ItemListingUtility>();
}
}
And here's the ListItemUtility class:
public class ItemListingUtility
{
public int Quantity { get; set; }
public string Duration { get; set; }
public List<string> AvailableDurations { get; set; }
public ItemListingUtility()
{
AvailableDurations = new List<string>();
}
}
In a view I am building, I am displaying 1 BackstoreInventoryUtility based on a BackstoreInventoryInfo item my user is currently browsing.
The ListItemUtility is a class allowing the user to proceed to certain action, like display for a set time a set quantity.
The view renders like this:
#model MyApp.Utilities.BackstoreInventoryUtility
#using (Html.BeginForm())
{
<div>
#if (Model.Item.Quantity > 0)
{
<input type="submit" value="Display"/>
}
#Html.HiddenFor(_item => _item.Item.BackstoreInventoryID)
<div class="bigFontSize bold formStyle">
<label class="center">Options will eventually be displayed here.</label>
<div>
<div class="float-left">Quantity Allocated:</div>
<div class="float-right">#Html.DisplayFor(_item => _item.Item.Quantity)
#Html.HiddenFor(_item => _item.Item.Quantity)
</div>
<div class="clear"></div>
</div>
<div class="formStyle" id="itemUtilityZone">
<label>Options</label>
#for (int i = 0; i < Model.ListItemUtility.Count; i++)
{
<div>
<div class="float-left">
Quantity To Display:
</div>
<div class="float-right">
#Html.TextBoxFor(_item => _item.ListItemUtility[i].Quantity, new { #class = "positive-integer numberTextBox" })
</div>
<div class="clear"></div>
</div>
}
</div>
#if (Model.Item.Quantity > 0)
{
<input type="submit" value="Display"/>
}
</div>
}
I'd like my user to dynamically add a new row to the view, and then when the view is submitted, all the rows would be included.
So far I am at the beginning and I am trying this:
[HttpGet]
public ActionResult AddItemUtilityRow()
{
return PartialView(new ItemListingUtility());
}
Where the partial view rendered would be identical to the div used in the table. But I am not sure how could I make this happen, should I use a jQuery call? How might I do this?
EDIT Okay, so I have tried something in jquery which VISUALLY does what I want:
<script type="text/javascript">
$(document).ready(function() {
$("#addUtility").click(function() {
$.get("#Url.Action("AddItemUtilityRow")", {
}, function(data) {
$('#itemUtilityZone').append(data);
});
});
});
</script>
So, as I said, this works but only partially because when the user submits only the default number of items in the list is submitted. How can I make it so that each time the user add a row it adds up to the model and gets later submitted?
Woah! It was more complex than I thought, but thanks to this link : http://blog.stevensanderson.com/2010/01/28/editing-a-variable-length-list-aspnet-mvc-2-style/ I was able to make the whole thing work!
I first transfered every row created in a partial view like this:
<div class="formStyle" id="itemUtilityZone">
<label>Options</label>
#foreach (var utilityRow in Model.ListItemUtility)
{
Html.RenderPartial("ItemUtilityRow", utilityRow);
}
</div>
Which renders like this:
#using HtmlHelpers.BeginCollectionItem
#model MyApp.Utilities.ItemListingUtility
#using (Html.BeginCollectionItem("listItems"))
{
<div>
<div class="float-left">
Quantity To Display:
</div>
<div class="float-right">
#Html.TextBoxFor(_item => _item.Quantity, new { #class = "positive-integer numberTextBox" })
</div>
<div class="clear"></div>
</div>
}
Note: for the Html.BeginCollectionItem Html Helper, I had to search a bit for Steven Sanderson's Helper which he mentions in the upper link. You can find it here:
https://github.com/danludwig/BeginCollectionItem
Next, my javascript call looks like this:
$(document).ready(function() {
$("#addUtility").click(function () {
$.ajax({
url: '#Url.Action("AddItemUtilityRow")',
cache: false,
success: function(html) {
$('#ItemUtilityZone').append(html);
}
});
});
});
And the controller method that adds a new row:
[HttpGet]
public ActionResult AddEbayUtilityRow()
{
return PartialView("ItemUtilityRow", new ItemListingUtility());
}
And the rows shows just fine now. The catch is, how do I catch it back in my post method? Well, following Steve Sanderson's blog, I understood that the listItems variable was actually the name of the collection which would be sent back to the post method.
So by adding this parameter to the controller post method:
IEnumerable<EBayListingUtility> listItems
The list is indeed sent back to the post method with the count being what it is supposed to be. Hurray!
We approach this in one of two ways:
1.) Client-side approach - you can use jquery/knockout whatever to append items to your table. This is fine for simple additions, but negates the use of c# in the view.
2.) Server-side approach (and usually used) - Basically, post your viewmodel back to an action that manually adds a list item;
[HttpGet]
public ActionResult AddItemUtilityRow()
{
return PartialView(new ItemListingUtility());
}
[HttpPost]
public ActionResult AddItemUtilityRow(BackstoreInventoryUtility viewModel)
{
viewModel.ListItemUtility.Add(new ItemListingUtility());
return PartialView(viewModel);
}
We have a number of ways using jquery of 'posting' to a different action (the one that simply adds an item). I would consider using jquery's ajax call to accomplish this.
But the premise is the same:
send the data from your page to the server
manipulate the data
reuse the view you created
I've been trying to figure out how to do this all afternoon, but can't seem to get a grip on how to get DatePicker to work with my site.
Also, if possible I would like to remove the Time part of the DateTime, as I'm only interested in the Date the entry gets posted.
I've included the code so far below, I've pretty much removed everything I've attempted so far so it is back to the beginning. I've referenced the JQuery files at the top of _Layout.cshtml which I think is correct.
I've looked at many guides on the web, but struggled to make much sense of them, although I will keep reading.
I've added these lines to the top of my _Layout.cshtml (I've also unpacked and copied the JQuery folders to the locations referenced below as well)
<link href="#Url.Content("~/Content/jquery-ui/redmond/jquery-ui-1.8.21.custom.css")" rel="stylesheet" type="text/css" />
<script src="#Url.Content("~/Scripts/jquery-1.8.11.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/modernizr-1.7.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/ui/minified/jquery.ui.core.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/ui/minified/jquery.ui.datepicker.min.js")" type="text/javascript"></script>
My View code looks like this:
#model dale_harrison.Models.News
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"> </script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>News</legend>
<div class="editor-label">
#Html.LabelFor(model => model.News_Entry)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.News_Entry)
#Html.ValidationMessageFor(model => model.News_Entry)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.News_Date)
</div>
<div class="editor-field">
#*#Html.EditorFor(model => model.News_Date)*#
#Html.EditorFor(model => model.News_Date, new object{ id = "news_date" } )
#Html.ValidationMessageFor(model => model.News_Date)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
<script type="text/javascript">
$(document).ready(function () {
$("#news_date").datepicker({ dateFormat: 'dd/mm/yy' });
});
</script>
My Model is here:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
namespace dale_harrison.Models
{
public class News
{
public int ID { get; set; }
public string News_Entry { get; set; }
public DateTime News_Date { get; set; }
}
public class NewsDBContext : DbContext
{
public DbSet<News> News_Entries { get; set; }
}
}
Many thanks in advance to anyone for helping
Try this first:
Add your html code without the html helper:
<input type="text" id="news_date" name="news_date" />
Or, if you want to add the id with the Html helper:
#Html.EditorFor(model => model.News_Date, new { id = "news_date" } )
And then add this javascript code:
$(document).ready(function () {
$("#news_date").datepicker({ dateFormat: 'dd/mm/yy' });
});
You can try this first to check if you have set it all the configuration in your project correctly. You should solve your problem with those lines.
After you get this working in your site, read about html helpers and how to encapsulate code so you do not have to rewrite this everytime.
Hope it helps!
On the Views/Shared/EditorTemplates folder you need to create a template for DateTime types, so every time you use #Html.EditorFor MVC display whatever you define on your Template
You may also wish to hide the time from the text box so that you see "08/11/2007" as opposed to "08/11/2007 00:00:00".
To do this, add "[DataType(DataType.Date)]" to your news class as below;
public class News
{
public int ID { get; set; }
public string News_Entry { get; set; }
[DataType(DataType.Date)]
public DateTime News_Date { get; set; }
}
EditorFor neglects extra attributes. Either use TextBoxFor or write EditorFor template...
I have a classes like this:
public class member
{
public string name {get;set;}
public IList<Note> notes {get;set;}
}
public class note
{
public string text {get;set;}
public datetime created {get;set;}
}
I want to have a page which inserts the member class - which i am fine with. My question lies in how to go about adding multiple notes to the member on the same page?
What would be the best way to go about this? (maybe some ajax solution to show sub forms for the note class)
Can anyone point me in the right direction of some related examples learning material?
Thanks in advance.
I'd create an Ajax form that posts to a method called AddNote(AddNoteViewModel viewModel) on your controller. AddNoteViewModel would contain all the information you need to create a new note. The AddNote Action Method would add the new note, SaveChanges and return a list of notes for the given Member. You can use a partial view for the content that is returned from AddNote.
On the Ajax form you should set UpdateTargetId to the id of the <div> you want to update with the latest list of notes.
Another option might be to use JQuery.
Here is a good example of both: Using Ajax.BeginForm with ASP.NET MVC 3 Razor
UPDATE : I've adapted Darin Dimitrov's example (from the link) to suit your scenario. This is off the top of my head so won't be perfect but it should give you a decent starting point
Model:
public class AddNoteViewModel
{
[Required]
public int MemberId { get; set; }
[Required]
public string Text { get; set; }
}
Controller:
[HttpPost]
public ActionResult AddNote(AddNoteViewModel model)
{
var member = //Get member from db using model.MemberId
member.Notes.Add(new Note{Text = model.Text, Created = DateTime.Now});
//SaveChanges();
var notes = //Get notes for member
return View(notes);
}
View:
#model AppName.Models.AddNoteViewModel
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script>
<div id="result"></div>
#using (Ajax.BeginForm(new AjaxOptions { UpdateTargetId = "result" }))
{
#Html.HiddenFor(x => x.MemberId)
#Html.EditorFor(x => x.Text)
#Html.ValidationMessageFor(x => x.Text)
<input type="submit" value="OK" />
}
Using JQuery:
View:
#model AppName.Models.AddNoteViewModel
<script src="#Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/index.js")" type="text/javascript"></script>
<div id="result"></div>
#using (Html.BeginForm())
{
#Html.HiddenFor(x => x.MemberId)
#Html.EditorFor(x => x.Text)
#Html.ValidationMessageFor(x => x.Text)
<input type="submit" value="OK" />
}
index.js:
$(function () {
$('form').submit(function () {
if ($(this).valid()) {
$.ajax({
url: this.action,
type: this.method,
success: function (result) {
$('#result').html(result);
}
});
}
return false;
});
});
I am trying to get POST data, but I'm having no luck. My code is below. When I click the form button nothing happens.
I expected at least my IDE to snap at A.Ret(), but nothing happens whatsoever.
File Test.cs
using System.Web;
public class A
{
public static string ret() {
var c = HttpContext.Current;
var v = c.Request.QueryString; // <-- I can see get data in this
return c.Request.UserAgent.ToString();
return c.Request.UserHostAddress.ToString();
return "woot";
}
}
File Default.aspx
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="aspnetCSone._Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server" method="post" action="Default.aspx">
<input type=hidden name="AP" value="99" />
<input type=button value="Submit" />
<div>
<a id="aa">a</a>
<% = A.ret() %>
</div>
</form>
</body>
</html>
Try using:
string ap = c.Request["AP"];
That reads from the cookies, form, query string or server variables.
Alternatively:
string ap = c.Request.Form["AP"];
to just read from the form's data.
c.Request["AP"] will read posted values. Also you need to use a submit button to post the form:
<input type="submit" value="Submit" />
instead of
<input type=button value="Submit" />
I'm a little surprised that this question has been asked so many times before, but the most reuseable and friendly solution hasn't been documented.
I often have webpages using AngularJS, and when I click on a Save button, I'll "POST" this data back to my .aspx page or .ashx handler to save this back to the database. The data will be in the form of a JSON record.
On the server, to turn the raw posted data back into a C# class, here's what I would do.
First, define a C# class which will contain the posted data.
Supposing my webpage is posting JSON data like this:
{
"UserID" : 1,
"FirstName" : "Mike",
"LastName" : "Mike",
"Address1" : "10 Really Street",
"Address2" : "London"
}
Then I'd define a C# class like this...
public class JSONRequest
{
public int UserID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
}
(These classes can be nested, but the structure must match the format of the JSON data. So, if you're posting a JSON User record, with a list of Order records within it, your C# class should also contain a List<> of Order records.)
Now, in my .aspx.cs or .ashx file, I just need to do this, and leave JSON.Net to do the hard work...
protected void Page_Load(object sender, EventArgs e)
{
string jsonString = "";
HttpContext.Current.Request.InputStream.Position = 0;
using (StreamReader inputStream = new StreamReader(this.Request.InputStream))
{
jsonString = inputStream.ReadToEnd();
}
JSONRequest oneQuestion = JsonConvert.DeserializeObject<JSONRequest>(jsonString);
And that's it. You now have a JSONRequest class containing the various fields which were POSTed to your server.
The following is OK in HTML4, but not in XHTML. Check your editor.
<input type=button value="Submit" />