Passing data from html to Web API via Angular - angularjs

I have a Web API where my repository class is:
public class myRepository
{
public myClasses.Type[] GetAllTypes()
{
return new myClasses.Type[]
{
new myClasses.Type
{
typeId="1",
typeVal = "New"
},
new myClasses.Type
{
typeId="2",
typeVal = "Old"
}
};
}
public myClasses.Employee[] GetAllEmployees()
{
return new myClasses.Employee[]
{
new myClasses.Employee
{
empId="111111",
empFName = "Jane",
empLName="Doe"
},
new myClasses.Employee
{
empId="222222",
empFName = "John",
empLName="Doe"
}
};
}
public bool VerifyEmployeeId(string id)
{
myClasses.Employee[] emp = new myClasses.Employee[]
{
new myClasses.Employee
{
empId="111111",
empFName = "Jane",
empLName="Doe"
},
new myClasses.Employee
{
empId="222222",
empFName = "John",
empLName="Doe"
}
};
for (var i = 0; i <= emp.Length - 1; i++)
{
if (emp[i].empId == id)
return true;
}
return false;
}
}
and here is my controller:
public class myClassesController : ApiController
{
private myRepository empRepository;
public myClassesController()
{
this.empRepository = new myRepository();
}
public myClasses.Type[] GetTypes()
{
return empRepository.GetAllTypes();
}
public myClasses.Employee[] GetEmployees()
{
return empRepository.GetAllEmployees();
}
[HttpGet]
public bool VerifyEmployee(string id)
{
return empRepository.VerifyEmployeeId(string id);
}
}
Now I have created a web application where I included angularJS. Here is my html (EmployeeLogin.html)
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Employee ID</title>
<script src="../../Scripts/jquery-2.2.0.min.js"></script>
<script src="../../Scripts/angular-ui/ui-bootstrap.min.js"></script>
<script src="../../Scripts/angular.js"></script>
<script src="EmployeeLoginCtrl.js"></script>
</head>
<body ng-app="myClassesApp">
<div ng-controller="myClassesController">
<form ng-submit="ValidateEmployeeId()" method="get" id="frmLogin" action="">
<input ng-model="empId" type="text" id="txtEmpId" />
<br />
<input type="submit" value="Submit" id="btnSubmit" />
<br />
<span id="lblMsg">{{EmployeeValidate}}</span>
</form>
</div>
</body>
</html>
What I want to accomplish is when the user enters their ID, I want to call myController function VerifyEmployee, pass it the ID entered by the user and output message of success or failure to the web page.
I am in need of some assistance fixing up my angular controller. here is what I got so far:
(function () {
angular.module("myClassesApp", []).controller("myClassesController", myValidateFunction);
myValidateFunction.$inject("$scope", "$http");
function myValidateFunction($scope, $http) {
$scope.ValidateEmployeeId = function () {
alert($scope.empId);
$http.get('http://localhost:49358/api/myClasses/VerifyEmployee/' + $scope.empId).
then(function (result) {
alert(result);
$scope.EmployeeValidate = result.data;
});
}
};
})();
My main question is how do I pass the id from the textbox to the angular controller?
Also how I ensure my angular function is only called when the form is submitted by the user, not when the page loads initially?
Can someone please point me in the right direction in regards to getting data from Web API and displaying it on the page?
So far the page loads, immediately displays "false" in the message label. then I enter ID and click submit and then nothing happens. ow can I ensure that angular function gets called?

So, in your UI, whatever you're data-binding to (ng-model, etc..) you have access to in Angular. In your example, you have <input ng-model="empId" type="text" id="txtEmpId" /> but I don't see a $scope.empId..Where is empId coming from then?
UI
<div ng-app ng-controller="myClassesController">
<div>Enter your User ID:</div>
<input ng-model="empId"></input>
<input type="submit" ng-click="checkUser()" value="Login"></input>
</div>
Controller
function myClassesController($scope) {
$scope.empId = '';
$scope.checkUser = function () {
// hit your api with user id
alert($scope.empId);
}
}
Here's a working example for you : JSFiddle

Related

Cannot recieve the values from JSON-string by angular.js

I have tried to implement some methods from a tutorial javasampleapproach.com/spring-framework/spring-boot/spring-jpa-postgresql-angularjs-example-spring-boot but it doesn't work for me.
When I hit the GET ALL CUSTOMERS-button nothing comes up. When I tried to add a testmessage with the json-text that I have requested from the RestController and just use #scope.allPersons.data the complete json-text come up but if I try to get the valuesin the json-responese it is either undefined or nothing comes up.
First of all, the RestController. I have tried with #RequestMapping(value="/findallresponse", produces = "application/json")and the default from the tutorial as showed in the code. The reason for making my own String Json is that if I responded with the Iteratable-object the response get recursive because of #ManyToMany-relation. And when I troubleshoot I left out the Hobbypart because that was the ManyToMany-relationship value.
#RequestMapping("/findallresponse")
public Response findAllResponse(){
ArrayList firstNameStr=new ArrayList<String>();
ArrayList lastNameStr=new ArrayList<String>();
ArrayList hobbyStr=new ArrayList<String>();
ArrayList idStr=new ArrayList<String>();
boolean startLoop=true;
String jsonPersonBeggining="{\"persons\":[";
String jsonPersonEnd="]}";
String jsonPerson="";
for(Person person : personService.findAll()){
if(startLoop==true)
{
startLoop=false;
}
else
{
jsonPerson+=",";
}
jsonPerson+="{";
jsonPerson+="\"firstName\":\""+person.getFirstName()+"\",";
jsonPerson+="\"lastName\":\""+person.getLastName()+"\",";
//jsonPerson+="\"hobby\":\""+person.getHobby()+"\",";
jsonPerson+="\"id\":\""+person.getId()+"\"";
jsonPerson+="}";
}
jsonPerson=jsonPersonBeggining+jsonPerson+jsonPersonEnd;
return new Response("Done",jsonPerson);
}
Here is the Response-class just as in the tutorial
public class Response {
private String status;
private Object data;
public Response() {
}
public Response(String status, String data) {
this.status = status;
this.data = data;
}
public String getStatus() {
return status;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public void setStatus(String status) {
this.status = status;
}
}
The javascript-file as in the tutorial. The #getResultMessage is to test that the json-string is recieved at all. And it is. But after that I can't access the post in it, for instance
firstName or
lastName
var app = angular.module('app', []);
app.controller('getallpersonsController', function($scope, $http, $location)
{
$scope.showAllPersons = false;
$scope.getAllPersons = function() {
var url = $location.absUrl() + "findallresponse";
var config = {
headers : {
'Content-Type' : 'application/json;charset=utf-8;'
}
}
$http.get(url, config).then(function(response) {
if (response.data.status == "Done") {
$scope.allpersons = response.data;
$scope.showAllPersons = true;
$scope.getResultMessage = $scope.allpersons.data;
} else {
$scope.getResultMessage = "get All Customers Data Error!";
}
}, function(response) {
$scope.getResultMessage = "Fail!";
});
}
});
This is the output on this is the #getResultMessage taken from #scope.allpersons.data
{"persons":[{"firstName":"Adam","lastName":"Johnson","id":"87"},{"firstName":"Anna","lastName":"Persson","id":"90"},{"firstName":"Nils","lastName":"Svensson","id":"93"}]}
And the jsp-file
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Spring Boot Example</title>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script
src="http://ajax.googleapis.com/ajax/libs/angularjs/1.6.0/angular.min.js">
</script>
<script src="/js/angular.js"></script>
<link rel="stylesheet"
href="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css"
/>
</head>
<body>
<div class="container" ng-app="app">
<h1>AngularJS - Spring JPA - PostgreSQL</h1>
<div class="row">
<div ng-controller="getallpersonsController" class="col-md-3">
<h3>All Customers</h3>
<button ng-click="getAllPersons()">
Get All Customers
</button>
<div ng-show="showAllPersons">
<ul class="list-group">
<li ng-repeat="persons in allpersons.data">
<h4 class="list-group-item">
<strong>Customer {{$index}}</strong><br />
Id: {{persons.id}}<br />
First Name: {{persons.firstName}}<br />
Last Name: {{persons.lastName}}
</h4>
</li>
</ul>
</div>
<p>{{getResultMessage}}</p>
</div>
</div>
</div>
</body>
</html>
UPDATE!!
Here is some calls on the response if that can give any clue?
data=[object Object] status=200
statustext=undefined
headers=function (d){b||(b=od(a));return d?(d=b[L(d)],void 0===d&&(d=null),d):b} config=[object Object]
Can anyone see if I missed something? In the jsp-file the ng-repeatloop is not working, it doesn't seems to be able to get the value from the json? Thanks

How to send list inside model - AngularJS

i have a problem with my model.
I need send a list of another object to my controller, but i dont know how to create this object using AngularJS.
I have three input field, homePhone, cellphone and contact, all fields are about phone, and my ClientModel has a list of phones. What i want to do, is get this three fields and include in a list inside client model.
**MVC Model "Client"**
public int Id { get; set; }
public string Name { get; set; }
public string Email{ get; set; }
public IEnumerable<Phone> Phones { get; set; }
**MVC Model "Phone"**
public int PhoneId { get; set; }
public int ClientId { get; set; }
public int PhoneType { get; set; }
public string Number { get; set; }
View
<div class="form-group col-lg-4">
<label>Home Phone</label>
<input class="form-control" ng-model="?">
</div>
<div class="form-group col-lg-4">
<label>Cellphone</label>
<input class="form-control" ng-model="?">
</div>
<div class="form-group col-lg-4">
<label>Contact Phone</label>
<input class="form-control" ng-model="?">
</div>
<button class="btn btn-primary" style="float: right" ng-click="saveClient(client)">Confirmar</button>
Controller JS
$scope.saveClient = function(client) {
clientesAPI.saveCliente(client).success(function() {
alert('OK');
}).error(function () {
alert('Error');
});`enter code here`
}
What you could do is create actual Constructor functions in JS and consistently model you current Server Side MVC Model.
So is would look something like this ...
angular.module('app', [])
.factory('Client', function() {
return Client;
function Client() {
this.id = 0;
this.name = '';
this.email = '';
this.phones = [];
}
Client.prototype.init = function(client) {
this.id = client.id;
this.name = client.name;
this.email = client.email;
this.phones = [];
}
})
.factory('Phone', function() {
return Phone;
function Phone() {
this.phoneId = 0;
this.clientId = 0;
this.phoneType = 'Default Phone Type';
this.number = 0;
}
Phone.prototype.init = function(phone) {
this.phoneId = phone.phoneId;
this.clientId = phone.clientId;
this.phoneType = phone.phoneType;
this.number = phone.number;
}
})
.factory('clientService', function($http, $log, Client, Phone) {
var service = {
getClient: getClient,
saveClient: saveClient
};
return service;
//////////////////////////
function getClient() {
return $http.get('clientApi')
.then(success)
.catch(error)
// This is where defining actual JS Quote unQuote Classes comes in handy
function success(response) {
var clients = response.data;
angular.forEach(clients, function(client) {
client = new Client().init(client);
angular.forEach(client.phones, function(phone) {
phone = new Phone().init(phone);
})
})
return clients;
}
function error(response) {
$log.error('Error getting Clients: ' + response.data);
}
}
function saveClient(client) {
return $http.post('clientApi', client)
.then(success)
.catch(error)
// This is where defining actual JS Quote unQuote Classes comes in handy
function success(response) {
$log('Saved Client Successfully');
}
function error(response) {
$log.error('Error saving Client: ' + response.data);
}
}
})
// I would use Controller As Syntax normally
.controller('clientController', function($scope, clientService, Client, Phone) {
$scope.client = new Client();
$scope.client.phones.push(new Phone());
$scope.savedClient;
$scope.saveClient = function() {
$scope.savedClient = $scope.client;
alert('Yeah we saved some data!!');
//Unconmment this to access the real service, Nowhere to call here :-)
//clientService.saveClient($scope.client);
};
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="clientController">
<!-- Use ngRepeat to simplify things a bit -->
<div class="form-group col-lg-4" ng-repeat="phone in client.phones track by phone.phoneId">
<label>{{phone.phoneType}}</label>
<input class="form-control" ng-model="phone.number">
</div>
<!-- You will already have access to the updated model in you controller -->
<button class="btn btn-primary" style="float: right" ng-click="saveClient()">Confirmation</button>
<!--Display Saved Data-->
<pre>{{savedClient | json}}</pre>
</div>
</div>
I like the idea of this approach for a couple of reasons.
You can new up a Client or a Phone in you controller and know for a fact that or expected model properties are there when Angular tries to render them. (This avoids the annoying client.phones.phoneId is not defined errors)
Your model definition is now in one spot on the JS side of the house. Even though this looks like duplication ... well it is, but you will have to define this somewhere to send it back to the server anyways. So I prefer to do it in one reusable spot.
You get and Arrays of Client and Phone when you are outputting the model properties to the Console. This just make me feel good :-)
This was a bit of an overkill for your question, but I like the clean feel of this approach to Front End Modeling.
You can create a new object for your model and add the phones property there.
View
<div class="form-group col-lg-4">
<label>Home Phone</label>
<input class="form-control" ng-model="homePhone">
</div>
<div class="form-group col-lg-4">
<label>Cellphone</label>
<input class="form-control" ng-model="cellPhone">
</div>
<div class="form-group col-lg-4">
<label>Contact Phone</label>
<input class="form-control" ng-model="contactPhone">
</div>
<button class="btn btn-primary" style="float: right" ng-click="saveClient()">Confirmar</button>
Controller
$scope.saveClient = function() {
var phones = [
{ClientId: $scope.client.Id, PhoneType: 1, Number: $scope.homePhone},
{ClientId: $scope.client.Id, PhoneType: 2, Number: $scope.cellPhone},
{ClientId: $scope.client.Id, PhoneType: 3, Number: $scope.contactPhone}
]; // Not sure about the PhoneTypes. There are multiple ways to implement this, I'll leave it up to you.
var data = {
Id: $scope.client.Id,
Name: $scope.client.Name,
Email: $scope.client.Email,
Phones: phones
};
clientesAPI.saveCliente(data).success(function() {
alert('OK');
}).error(function () {
alert('Error');
});
};
first you need to define ng-model for your view, suppose -
<input class="form-control" ng-model="hPhone">
<input class="form-control" ng-model="cellPhone">
<input class="form-control" ng-model="contactPhone">
Now you can make a json object and post that, then on server side you can access all the phones by for-each loop -inside your controller -
var vm = this;
var phnList = {
hphone: vm.hphone,
cellPhone: vm.cellPhone,
contactPhn: vm.contactPhone
};
Now u can post using $http service
$(http).({
url : "urULR",
data : phnList,
method :"post"
}).then(fuction(response) {
vm.message = "save success";
});

Pushing multiple entries and saving them in database through AngularJS

I am stuck saving multiple rows I pushed in "$scope.arr" to my SQL Server database. I have my code below and it works fine but when I click on "Save To DB" button after adding/pushing some entries by pressing "Add Person" button, it passes a row with null values to SQL Server database. Please guide me where I am doing the mistake:
I also heard about using angular.forEach loop but I am confused using that too.
I have my model class "TestModel.cs" here:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace TestProj.Models
{
public class TestModel
{
public int ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
}
My MVC Controller named TestController's Add method here:
[HttpPost]
public string AddPerson(TestModel test)
using (TestContext db = new TestContext())
{
if (test != null)
{
db.TestModels.Add(test);
db.SaveChanges();
return "Successful";
}
else
{
return "Failed";
}
}
}
My AngularJS script here:
var app = angular.module("TestApp", []);
app.controller("TestCtrl", function ($scope, TestService) {
$scope.arr = [];
$scope.addPerson = function () {
var myobj = {
FirstName: $scope.firstname,
LastName: $scope.lastname
}
$scope.arr.push(myobj);
};
$scope.savePerson = function () {
var TestData = TestService.AddPer($scope.arr);
TestData.then(function (msg) {
alert(msg.data);
}, function () {
alert('Error In Adding Person');
});
};
});
app.service("TestService", function ($http) {
this.AddPer = function (person) {
var response = $http({
method: "post",
url: "/Test/AddPerson",
data: JSON.stringify(person),
dataType: "json",
});
console.log(response);
return response;
}
});
And my Index.cshtml file here:
<div ng-controller="TestCtrl">
<form>
FirstName: <input class="form-control" ng-model="firstname" /><br />
LastName: <input class="form-control" ng-model="lastname" /><br />
<button class="btn btn-success" ng-click="addPerson()">Add Person</button>
<button class="btn btn-success" ng-click="savePerson()">Save To DB</button>
<table class="table table-bordered">
<tr>
<th>S. No</th>
<th>First Name</th>
<th>Last Name</th>
</tr>
<tr ng-repeat="a in arr">
<td>{{$index+1}}</td>
<td>{{a.FirstName}}</td>
<td>{{a.LastName}}</td>
</tr>
</table>
</form>
</div>
<script src="~/Scripts/MyAngular/Module.js"></script>
Your help will be appreciated. Thanks!
Then server side action should expect collection of TestModel, you could us List there. If you [FromBody] before parameter, you don't need to stringify data before posting it to server.
Code
[HttpPost]
public string AddPerson([FromBody] List<TestModel> test)
using(TestContext db = new TestContext()) {
test.forEach(t=> {
if (t != null) {
db.TestModels.Add(t);
return "Successful";
} else {
return "Failed";
}
});
db.SaveChanges(); //save context at the end, when no error occurs
}
}
The problem was in my Server Side Code i.e, my C# controller, this method worked:
[HttpPost]
public void AddPerson(List<TestModel> test)
{
using (TestContext db = new TestContext())
{
foreach(var t in test)
{
if (t != null)
{
db.TestModels.Add(t);
Console.WriteLine("Success");
}
}
db.SaveChanges(); //save context at the end, when no error occurs
}
}

The simplest example of Knockback js working with a RESTful webservice such as ServiceStack?

I am looking for a VERY simple example that shows wiring up Knockback code to a backbone model that connects via RESTful service. I am using ServiceStack|c# backend. All of the links below are too complicated and use localStore rather than a RESTful service via url. I also prefer to see examples in Javascript not CoffeeScript.
My example url is something like localhost/entities where hitting this will cause the RESTful webservice to return all of the entities. Hitting it with localhost/entity/1 would return the entity with an Id of 1.
_http://kmalakoff.github.com/knockback/index.html
_https://github.com/kmalakoff/knockback-reference-app/
_https://github.com/addyosmani/todomvc
The following is the example from knockback tutorial on the first link:
Models, Collection, ViewModel, and Bindings:
// Generated by CoffeeScript 1.3.3
var model, view_model;
model = new Backbone.Model({
first_name: "Planet",
last_name: "Earth"
});
view_model = kb.viewModel(model);
view_model.full_name = ko.computed((function() {
return "" + (this.first_name()) + " " + (this.last_name());
}), view_model);
ko.applyBindings(view_model, $('#kb_view_model_computed')[0]);
But there is no mention of how you would wire the backbone model up to your RESTful webservice.
There are examples of how do this via Backbone but I am uncertain as to how things change when using Knockback.
The following links were found, but not helpful:
_http://stackoverflow.com/questions/7992431/using-knockoutjs-backbone-together
_http://stackoverflow.com/questions/9704220/is-knockback-js-production-ready
_http://stackoverflow.com/questions/10434203/defining-models-on-server-side-when-using-mvvm-with-knockout-js
Thanks in advance for any assistance provided. Btw you don't want hyperlinks you get underscores... ;)
With much help and support from Kevin Malakoff from the great Knockback project I was able to get a small example working! I used the ServiceStack Backbone Todos project as a starting point.
c# file: Global.asax.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.SessionState;
using ServiceStack.Redis;
using ServiceStack.ServiceInterface;
using ServiceStack.WebHost.Endpoints;
namespace MyApp
{
public class Person
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class PersonService : RestServiceBase<Person>
{
public static Person kevin = new Person { Id = 1, FirstName = "Kevin", LastName = "Malakoff" };
public static Person scott = new Person { Id = 2, FirstName = "Scott", LastName = "Idler" };
public static List<Person> people = new List<Person> { kevin, scott };
public override object OnGet(Person person)
{
if (person.Id != default(int))
return people[person.Id-1];
return people;
}
public override object OnPost(Person person)
{
return base.OnPost(person);
}
public override object OnPut(Person person)
{
return OnPost(person);
}
public override object OnDelete(Person person)
{
return base.OnDelete(person);
}
}
public class AppHost : AppHostBase
{
public AppHost() : base("MyApp", typeof(PersonService).Assembly) { }
public override void Configure(Funq.Container container)
{
ServiceStack.Text.JsConfig.EmitCamelCaseNames = true;
Routes
.Add<Person>("/persons")
.Add<Person>("/persons/{Id}");
}
}
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
new AppHost().Init();
}
}
}
html file: default.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>MyApp2</title>
<script>window.JSON || document.write('<script src="http://ajax.cdnjs.com/ajax/libs/json2/20110223/json2.js">\x3C/script>')</script>
<script src="Scripts/jquery-1.8.0.js" type="text/javascript" ></script>
<script src="Scripts/knockback-full-stack-0.16.1.js" type="text/javascript" ></script>
<script src="myapp.js" type="text/javascript" ></script>
</head>
<body>
<div id="myapp">
<div class="title">
<h1>MyApp</h1>
</div>
<div class="content">
<div id='kb_observable'>
<p>First name: <input class='text' data-bind="value: firstName" /></p>
<p>Last name: <input class='input-small pull-right' data-bind="value: lastName" /></p>
<p>Hello, <span data-bind="text: fullName"></span>!</p>
</div>
<div id="kb_collection_observable">
<div data-bind="if: persons">
<span>Has Persons</span>
</div>
<div data-bind="foreach: persons">
<p>First name: <input class='text' data-bind="value: firstName" /></p>
<p>Last name: <input class='input-small pull-right' data-bind="value: lastName" /></p>
</div>
</div>
</div>
</div>
</body>
</html>
javascript file: myapp.js
$(function() {
//model
var PersonModel = Backbone.Model.extend({ urlRoot: '/MyApp/persons' });
var model = new PersonModel({ id: 1 });
model.fetch();
//viewmodel
var PersonViewModel = function (person) {
this.firstName = kb.observable(person, 'firstName');
this.lastName = kb.observable(person, 'lastName');
this.fullName = ko.computed((function () {
return "" + (this.firstName()) + " " + (this.lastName());
}), this);
};
var personViewModel = new PersonViewModel(model);
//binding
ko.applyBindings(personViewModel, $('#kb_observable')[0]);
//model
var PersonsModel = Backbone.Collection.extend({ model: PersonModel, url: '/MyApp/persons' });
var personsModel = new PersonsModel();
personsModel.fetch();
//viewmodel
var PersonsViewModel = function (persons) {
this.persons = kb.collectionObservable(persons)
};
var personsViewModel = new PersonsViewModel(personsModel);
//binding
ko.applyBindings(personsViewModel, $('#kb_collection_observable')[0]); });
I put together a very simple example. It assumes you already know how to use backbone and knockout so this just gives a quick example of how they can be used together
http://coder2.blogspot.com/2013/02/backbonejs-and-knockoutjs.html

Image saved in database cannot be updated

I have been googling for a solution to my problem for two days without any luck. Can any stars in MVC3 .NET help?
I am trying to build an .NET MVC3 application to update images saved in an database.
Here is the action method
[HttpPost]
public ActionResult Edit(myImage img, HttpPostedFileBase imageFile)
{
//var img = (from imga in db.myImages
// where imga.imageID == id
// select imga).First();
if (ModelState.IsValid)
{
if (img != null)
{
img.imageType = imageFile.ContentType;
img.Data = new byte[imageFile.ContentLength];
imageFile.InputStream.Read(img.Data, 0, imageFile.ContentLength);
}
// save the product
UpdateModel(img);
db.SubmitChanges();
return RedirectToAction("Index");
}
else
{
// there is something wrong with the data values
return View(img);
}
}
Here is the view
#model JackLing.Models.myImage
#{
ViewBag.Title = "Edit";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Edit</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("Edit", "Image",FormMethod.Post, new { enctype = "multipart/form-data" })){
#Html.ValidationSummary(true)
<fieldset>
<legend>myImage</legend>
#Html.EditorForModel();
<div class="editor-label">Image</div>
<div class="editor-field">
#if (Model.Data != null)
{
<img src="#Url.Action("show", new { id = Model.imageID })" height="150" width="150" />
}
else {
#:None
}
</div>
<p>
<span>Choose a new file</span> <input type="file" name="imgFile"/>
</p>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
When I run the application it throws an error saying "Object reference not set to an instance of an object."
Any suggestions on how to fix the problems will be appriciated! By the way, the create and details method are all working. I think it has to do with data binding, but I'm not sure... I have no clue how to fix it.
Finally fixed the problem based on the advice from Eulerfx
here is the working action.
[HttpPost]
public ActionResult Edit(myImage img, HttpPostedFileBase imageFile)
{
myImage imgToSave = (from imga in db.myImages
where imga.imageID == img.imageID
select imga).First();
if (ModelState.IsValid)
{
if (img != null)
{
imgToSave.imageType = imageFile.ContentType;
var binaryReader = new BinaryReader(imageFile.InputStream);
imgToSave.Data = binaryReader.ReadBytes(imageFile.ContentLength);
binaryReader.Close();
}
TryUpdateModel(imgToSave);
db.SubmitChanges();
return RedirectToAction("Index");
}
else
{
// there is something wrong with the data values
return View(img);
}
}
The problem may be that the name of the file input field in the HTML is imgeFile and the name of the file parameter in MVC is imageFile. Ensure that the input field name and the action method parameter names match.

Resources