.Net properties are missing in the response got from AngularJs Ajax call to Asp.Net Web Api - ajax

I am making an ajax call using AngularJS $http to Asp.Net Web Api.
$http({
method: 'GET',
url: '/api/PatientCategoryApi/PatCat',
params: dataTemp,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
}).then(function successCallback(response) {
$scope.modelObject.resultData = response.data;
alert(JSON.stringify(response.data));
}, function errorCallback(response) {
$scope.modelObject.result = response;
});
The web api action has the following signature
public PaginatedList<PatientCategory> PatCat(PaginatedRequestCommand cmd){...}
The PaginatedList type is as follows.
public class PaginatedList<T> : List<T>
{
public int PageIndex { get; private set; }
public int PageSize { get; private set; }
public int TotalCount { get; private set; }
public int TotalPageCount { get; private set; }
public bool HasPreviousPage
{
get
{
return (PageIndex > 1);
}
}
public bool HasNextPage
{
get
{
return (PageIndex < TotalPageCount);
}
}
}
I have removed the ctor as its not required here. So its just a wrapper to a list of T and in this case T is PatientCategory.
I am able to access the list from the response object after the ajax call. But I am not able to find the properties of the PaginatedList such as
PageIndex, PageSize and so on in the response object. Even as I use fiddler, I can clearly see the array of PatientCategory objects but as the properties of the PaginatedList are missing.
[{"Id":1,"Code":"H05120000003","Name":"Regular","Description":"The Regular Patient Category","ModifiedTime":"2015-10-01T19:34:33.727","History":null,"MyXmlColumn":null},{"Id":2,"Code":"BH130000001","Name":"STAFF_CHGD_TO_REGULAR","Description":null,"ModifiedTime":"2015-10-01T19:46:07.093","History":null,"MyXmlColumn":null},{"Id":3,"Code":"BH130000001","Name":"STAFF_CHGD_TO_REGULAR","Description":null,"ModifiedTime":"2015-10-01T19:52:03.773","History":null,"MyXmlColumn":null}]
So how can I access those properties as well in the response?
The request and response that show up in Fiddler are as follows.
Request
GET http://localhost:50849/api/PatientCategoryApi/PatCat?Page=1&Take=3 HTTP/1.1
Host: localhost:50849
Connection: keep-alive
Accept: application/json, text/plain, */*
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36
Referer: http://localhost:50849/PatientCategory/Index
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
Response
HTTP/1.1 200 OK
Content-Length: 479
Content-Type: application/json; charset=utf-8
Server: Microsoft-IIS/8.0
X-SourceFiles: =?UTF-8?B?RDpcQlZIXEF2YmhIaXNcQXZiaEhpcy5XZWJcYXBpXFBhdGllbnRDYXRlZ29yeUFwaVxQYXRDYXQ=?=
X-Powered-By: ASP.NET
Date: Thu, 15 Oct 2015 01:43:57 GMT
[{"Id":1,"Code":"H05120000003","Name":"Regular","Description":"The Regular Patient Category","ModifiedTime":"2015-10-01T19:34:33.727","History":null,"MyXmlColumn":null},{"Id":2,"Code":"BH130000001","Name":"STAFF_CHGD_TO_REGULAR","Description":null,"ModifiedTime":"2015-10-01T19:46:07.093","History":null,"MyXmlColumn":null},{"Id":3,"Code":"BH130000001","Name":"STAFF_CHGD_TO_REGULAR","Description":null,"ModifiedTime":"2015-10-01T19:52:03.773","History":null,"MyXmlColumn":null}]

Asp.net web api use NewtonJson.dll to make a Javascript serialization. When newtonjson find a class implement IEnumerable, it will serialize this object to an Javascript object like this [{},{}], it seems newtonjson only serialize the IEnumebrable object, other properties are ignored. Also you can add the NewtonSoft.Json.JsonObject to the class PagenatedList, this attribute will tell newtonjson serialize the data to a javascript plain object like this {p1: "", p2: ""}, but you will find the IEnumebrable data lost. To solve this, you should custom a new CustomJsonConverter inherited from JsonConverter, and add the attribute to your PagenatedList like this:
[Newtonsoft.Json.JsonConverter(typeof(CustomJsonConverter))
public class PagenatedList<T>:List<T>
//your class code

Related

issue posting multipart/form-data via html5 FormData to c# Api

My issue is that my c# api controller is kicking back theFormData Post request when I check for multi-part data here: IsMimeMultipartContent(), which then throws the message back to the UI:
415 (Unsupported Media Type)
[HttpPost]
[Route("MediaUpload")]
public async Task<HttpResponseMessage> MediaUpload([FromUri]string sessionId, [FromUri]string patientId)
{
if (!Request.Content.IsMimeMultipartContent())
{ // *** ALWAYS THROWS ERROR ***
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
//access form data
var provider = await Request.Content.ReadAsMultipartAsync(new InMemoryMultipartFormDataStreamProvider());
NameValueCollection formData = provider.FormData;
//... additional code omitted
var response = Request.CreateResponse(HttpStatusCode.OK);
response.Headers.Add("UploadPath", fullPath);
response.Headers.Add("Access-Control-Allow-Origin", "*");
return response;
}
My front end payload looks like this:
REQUEST HEADERS
POST /api/import/MediaUpload?sessionID=c83f9589-742e-40e3-8cf5-7ffff141c3d7&patientId=5981 HTTP/1.1
Host: localhost:56703
Connection: keep-alive
Content-Length: 6545
Accept: application/json, text/plain, */*
Origin: http://localhost:4200
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36
Content-Type: multipart/form-data
Referer: http://localhost:4200/
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
REQUEST PAYLOAD
------WebKitFormBoundaryVrKSHPqdT9c6JkKv
Content-Disposition: form-data; name="enctype"
multipart/form-data
------WebKitFormBoundaryVrKSHPqdT9c6JkKv
Content-Disposition: form-data; name="MediaInfo"
[{"PatientID":5981,"PatientLastName":"Hobo","PatientFirstName":"John","DeviceID":"123","InstanceID":89,"PatientDOB":"1/3/1970","FileName":"image2.jpg","FileSize":5880,"ExamDate":"5/30/2018","PatientID":66665981,"SessionID":"sessionID=9999141c3d7"}]
------WebKitFormBoundaryVrKSHPqdT9c6JkKv
Content-Disposition: form-data; name="files[]"; filename="image2.jpg"
Content-Type: image/jpeg
ÿØÿàJFIFÿÛC
------WebKitFormBoundaryVrKSHPqdT9c6JkKv--
My front end is sending in FormData, generated in the following TypeScript method, then calling the importService further below:
save() {
let params = { patientID: ''};
let exDate = new Date(this.defaultDate).toLocaleDateString();
// Populate MediaInfo object
let minfo = this.SetMediaArray();
params.pID = minfo[0].PID;
const formData = new FormData();
formData.set("enctype", "multipart/form-data" ); // doesn't make a difference..
formData.append("MedInfo", JSON.stringify(minfo));
for(var i=0; i<this.importImages.length; i++){
// append images to the files[] array, then send formData object to impService
formData.append("files[]", this.dataURItoBlob(this.importImages[i].TnUrl), this.importImages[i].name);
}
let endpoint = this.selectedObj.Url;
this.importService.saveImportObjects(formData, params, endpoint).subscribe(
data=> {
console.log(data);
},
err => {
console.log(err);
}
);
}
So basically I would like to know exactly what http option I'm missing for this to work.
thank you.
I removed the multipart/boundary header attribute, and let the browser take care of it for you. The upload worked.

ASP.NET MVC Ajax Post has no data

I've struggled with this one for too long, maybe I'm missing something simple. I've been trying to use an ajax form to avoid reloading the whole page after submitting a form. Everything is looking fine, and Chrome DevTools is showing a good post holding all of my data. When I get to my action in the controller, my view model is empty and in its initialized state. So my though is it has something to do with the way the values are getting mapped to my model on the server side.
This is sort of my code, I was aiming for more than this but I've stripped a lot of it away while trying to trouble shoot. I feel like this is the most basic possible form of Ajax form post. I tried making the names and variables generic to try and simplify, so if something don't add up that might be why.
Please help I'm going crazy.
View:
#model EmiExpress.Web.Areas.Reports.Models.TurnkeyLiability.AddNewReportFormVm
#using (Ajax.BeginForm("NewReport", "Reports",
new AjaxOptions { HttpMethod = "POST" } ))
{
<div>
#Html.TextBoxFor(model => model.GroupId)
</div>
<div>
#Html.DevExpress().CheckBoxFor(
model => model.Save,
s =>
{
s.Text = "Save Values?";
}
).GetHtml()
</div>
<div>
<input type="submit" value="Submit Data" id="btnSubmit" />
</div>
}
Controller Action:
[HttpPost]
public ActionResult NewReport(AddNewReportFormVm viewModel)
{
int x = 5;
if (ModelState.IsValid)
{
x = 10; //just some junk while I try to get this working
}
return PartialView("Controls/_cbpReportRunLoading", x);
}
Model:
public class AddNewReportFormVm
{
public AddNewReportFormVm()
{
GroupId = "";
Save = false;
}
[Required]
public string GroupId{ get; private set; }
public bool Save{get; set;}
}
Network Response Headers:
Cache-Control: private
Content-Length: 1130
Content-Type: text/html; charset=utf-8
Date: Tue, 12 Jun 2018 02:41:05 GMT
Persistent-Auth: true
Server: Microsoft-IIS/10.0
X-AspNet-Version: 4.0.30319
X-AspNetMvc-Version: 5.2
X-Powered-By: ASP.NET
X-SourceFiles: =?UTF-8?B?QzpcVXNlcnNcc3RlZmFudG91YmlhXHNvdXJjZVxyZXBvc1xFbWlFeHByZXNzXEVtaUV4cHJlc3MuV2ViXFJlcG9ydHNcVHVybmtleUxpYWJpbGl0eVxSdW5OZXdSZXBvcnQ=?=
Request Headers:
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Connection: keep-alive
Content-Length: 2300
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
DXCss: 0_2312,1_50,1_53,1_51,0_2317,1_40,1_17,0_2214,1_16,0_2219,0_2221,0_2225,1_18,1_4,0_2257,18_3,18_11,18_7,0_2261,0_2313,1_34,0_2273,16_3,16_11,16_7,0_2277,1_44,0_2192,24_359,24_364,24_360,1_20,9_12,9_15,0_2338,9_1,0_2342,9_4,1_7,15_0,15_4,/Content/Site.css,/Areas/Reports/Content/TurnkeyLiability.css
DXScript: 1_228,1_226,1_227,1_225,1_304,1_211,1_185,1_221,1_188,1_182,1_280,1_293,1_271,1_287,1_290,1_184,17_42,17_3,1_286,1_189,17_8,1_298,1_193,17_10,1_288,1_195,1_194,17_11,1_209,1_217,1_296,1_279,1_302,1_254,1_235,1_247,1_303,1_222,17_12,1_297,17_41,1_190,1_223,1_291,1_289,1_196,1_256,1_263,1_262,1_255,1_252,1_259,1_253,1_261,1_258,1_257,1_248,1_244,1_242,1_251,1_250,1_249,1_246,1_245,1_260,1_241,1_238,1_239,1_240,1_243,17_15,17_17,1_272,1_273,17_19,1_274,1_275,17_20,17_21,1_224,17_14,1_277,17_24,17_28,1_281,17_25,1_294,17_27,1_292,1_295,17_32,1_299,17_36,17_40,1_192,1_285,18_36,18_38,18_33,18_42,18_37,18_35,17_31,1_208,1_206,1_212,1_201,1_215,1_203,1_205,1_204,1_284,1_198,1_213,17_1,1_197,17_0,1_199,17_2,1_200,17_4,1_202,1_219,17_7,17_23,1_207,17_9,1_276,1_216,17_22,1_214,1_218,17_38,1_220,16_52,16_152,16_47,16_36,16_153,16_28,16_27,16_48,16_50,16_32,16_41,16_159,16_154,16_34,16_51,16_54,16_40,16_158,16_43,16_44,16_33,16_162,16_46,16_45,16_55,16_49,16_31,16_38,16_37,16_39,16_53,16_42,16_26,16_29,16_30,17_35,16_160,16_35,10_11,10_10,10_12,10_13,10_14,17_6,1_236,17_16,1_229,24_401,24_400,24_402,24_403,24_406,24_407,24_408,24_404,24_405,1_230,24_379,24_380,9_45,9_36,24_388,24_398,9_38,9_37,17_30,9_46,17_44,9_42,9_39,9_31,17_29,9_41,9_32,9_44,9_43,9_40,15_16,15_14,15_10,15_11,15_13,20_0,1_237,9_48,9_47
Host: localhost:57144
Origin: http://localhost:57144
Referer: http://localhost:57144/Reports/TurnkeyLiability
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.79 Safari/537.36
X-Requested-With: XMLHttpRequest
Form Data:
GroupId: abc
Save: C
DXScript: 1_228,1_226,1_227,1_225,1_304,1_211,1_185,1_221,1_188,1_182,1_280,1_293,1_271,1_287,1_290,1_184,17_42,17_3,1_286,1_189,17_8,1_298,1_193,17_10,1_288,1_195,1_194,17_11,1_209,1_217,1_296,1_279,1_302,1_254,1_235,1_247,1_303,1_222,17_12,1_297,17_41,1_190,1_223,1_291,1_289,1_196,1_256,1_263,1_262,1_255,1_252,1_259,1_253,1_261,1_258,1_257,1_248,1_244,1_242,1_251,1_250,1_249,1_246,1_245,1_260,1_241,1_238,1_239,1_240,1_243,17_15,17_17,1_272,1_273,17_19,1_274,1_275,17_20,17_21,1_224,17_14,1_277,17_24,17_28,1_281,17_25,1_294,17_27,1_292,1_295,17_32,1_299,17_36,17_40,1_192,1_285,18_36,18_38,18_33,18_42,18_37,18_35,17_31,1_208,1_206,1_212,1_201,1_215,1_203,1_205,1_204,1_284,1_198,1_213,17_1,1_197,17_0,1_199,17_2,1_200,17_4,1_202,1_219,17_7,17_23,1_207,17_9,1_276,1_216,17_22,1_214,1_218,17_38,1_220,16_52,16_152,16_47,16_36,16_153,16_28,16_27,16_48,16_50,16_32,16_41,16_159,16_154,16_34,16_51,16_54,16_40,16_158,16_43,16_44,16_33,16_162,16_46,16_45,16_55,16_49,16_31,16_38,16_37,16_39,16_53,16_42,16_26,16_29,16_30,17_35,16_160,16_35,10_11,10_10,10_12,10_13,10_14,17_6,1_236,17_16,1_229,24_401,24_400,24_402,24_403,24_406,24_407,24_408,24_404,24_405,1_230,24_379,24_380,9_45,9_36,24_388,24_398,9_38,9_37,17_30,9_46,17_44,9_42,9_39,9_31,17_29,9_41,9_32,9_44,9_43,9_40,15_16,15_14,15_10,15_11,15_13,20_0,1_237,9_48,9_47
DXCss: 0_2312,1_50,1_53,1_51,0_2317,1_40,1_17,0_2214,1_16,0_2219,0_2221,0_2225,1_18,1_4,0_2257,18_3,18_11,18_7,0_2261,0_2313,1_34,0_2273,16_3,16_11,16_7,0_2277,1_44,0_2192,24_359,24_364,24_360,1_20,9_12,9_15,0_2338,9_1,0_2342,9_4,1_7,15_0,15_4,/Content/Site.css,/Areas/Reports/Content/TurnkeyLiability.css
DXMVCEditorsValues: {"Save":true}
X-Requested-With: XMLHttpRequest

WebApi 2.1 PUT throw error 415

I'm trying to update data using WebApi PUT method. My code working fine before, but suddenly I start to get this error.
"Message":"The request contains an entity body but no Content-Type header. The inferred media type 'application/octet-stream' is not supported for this resource.","ExceptionMessage":"No MediaTypeFormatter is available to read an object of type 'xEmployee' from content with media type 'application/octet-stream'.","ExceptionType":"System.Net.Http.UnsupportedMediaTypeException".
This is headers:
Response Header.
HTTP/1.1 415 Unsupported Media Type
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/7.5
Set-Cookie: Role=D65520F37D105E39C1A92C15CD482E378F32A769592AC7D8305285A5B9B90362F7F2F13F14E6DC220E44D26940B06B52E7460EF13184F245805AF9523D1072464F4BD06AFB4F8AEB8B7D8BF607A8922C6041A3A4C636BF3B26388E606A94FE43; expires=Tue, 07-Oct-2014 09:49:56 GMT; path=/
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Tue, 07 Oct 2014 09:19:56 GMT
Content-Length: 809
Request Header:
PUT /api/xemployees/2110481232 HTTP/1.1
Host: guideonline.ilvestour.office
Connection: keep-alive
Content-Length: 229
Accept: application/json, text/javascript, */*; q=0.01
Origin: http://guideonline.ilvestour.office
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36
Content-Type: application/json; charset=UTF-8"
Referer: http://guideonline.ilvestour.office/account
Accept-Encoding: gzip,deflate,sdch
Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4
Cookie: .ASPXAUTH=215C424A0A023F5B42775B7A73B08FEC8CB36E7200FBA430EADF2F300A84500571F8B5EE980C3EF2913FE160978973CDBC50BDD216E16FC342EF0B566D0944ECFD901DF471DEF9F6E5D272B52F2450CC0A1FB96BCC6B3B6E7A7C07343D4DFBD66; Role=DE678EE89D7089B8CD74B202E00C53CA9AE9E4C40B506C5C4EEF56E7962F38ED86F6BFD34E5FD3A6DD6ECCCF61AF768CAB0C1D7C5F15A8638F9454B24DF3208F021EB638235420574C6420CA5A19F0B6BD07BAC303FF79612D6C1AF246563A7
Request Payloadview source
{"Kod":2110481232, "Сотрудник": "Lena", "Telephon": "088-6734227", "Password":"rimosa57", "email":"samoylova-elena#mail.ru", "CrWho":"OMEGA.Administrator", "CrWhen":"2014-10-07T09:20:05.735Z"}
Nothing special in Controller code:
[Authorize(Roles = "Admin, User")]
public async Task<IHttpActionResult> PutxEmployee(int id, xEmployee xEmployee)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
if (id != xEmployee.Kod)
{
return BadRequest();
}
try
{
var user = db.xEmployee.Find(id);
user.Сотрудник = xEmployee.Сотрудник;
user.Telephon = xEmployee.Telephon;
user.Password = xEmployee.Password;
user.email = xEmployee.email;
await db.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!xEmployeeExists(id))
{
return NotFound();
}
else
{
throw;
}
}
catch (DbEntityValidationException e)
{
foreach (var eve in e.EntityValidationErrors)
{
var path = "C:/error.txt";
using (StreamWriter sw = File.CreateText(path))
{
sw.WriteLine("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:",
eve.Entry.Entity.GetType().Name, eve.Entry.State);
}
using (StreamWriter sw1 = File.CreateText("C:/error1.txt"))
foreach (var ve in eve.ValidationErrors)
{
sw1.WriteLine("- Property: \"{0}\", Error: \"{1}\"",
ve.PropertyName, ve.ErrorMessage);
}
}
throw;
}
return StatusCode(HttpStatusCode.NoContent);
}
Same as WebApiConfig:
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
var json = config.Formatters.JsonFormatter;
json.SerializerSettings.Culture = new CultureInfo("ru-RU");
config.Formatters.Remove(config.Formatters.XmlFormatter);
}
There seems to be a typo (last ") in the request's Content-Type header:
Content-Type: application/json; charset=UTF-8"
When this header is missing or malformed, the server will automatically use application/octet-stream by default, as described by this post.
I were facing similar problem. Though i have a Content-Type declare it was still sending same error.
What I did is added Accept Header and it started working.
Accept: application/json
Content-Type: application/json
Also, make sure there's only one header Content-Type. In my case, my rest client was implicitly sending the empty Content-Type which got overridden by Content-Type: application/json hence the error.

Asp.Net WebApi OData with DataJs throws an error

I just created a really simple ASP.Net WebApi project. I used NuGet to download the latest OData in WebAPI – RC release. I also download DataJs and Knockout via NuGet. All my dependencies are up to date. I created a simple "Books" class and wired everything together using HttpConfiguration.EnableOData(IEdmModel). I also added the [Queryable] attribute to my Get action in the controller. There is not database involved, I hard-coded the data I want returned. Basically, I did the minimum amount of changes to run my project with WebApi and OData.
When I try to query the OData service using DataJs, I get a 500 Internal Server Error in the response, but if I browse to the URL directly I can see the XML data. I've included the request, response, my C# class, the Javascript code, and the Global.asax code. What am I missing to get this to work?
REQUEST
Response Headers
Cache-Control private
Content-Length 966
Content-Type application/json; odata=fullmetadata; charset=utf-8
DataServiceVersion 3.0;
Date Fri, 21 Dec 2012 22:13:27 GMT
Server Microsoft-IIS/8.0
X-AspNet-Version 4.0.30319
X-Powered-By ASP.NET
X-SourceFiles =?UTF-8?B?YzpcdXNlcnNcanVzdGluXGRvY3VtZW50c1x2aXN1YWwgc3R1ZGlvIDIwMTJcUHJvamVjdHNcRGF0YUpzU3Bpa2VcRGF0YUpzU3Bpa2VcYXBpXEJvb2tz?=
Request Headers
Accept application/atomsvc+xml;q=0.8, application/json;odata=fullmetadata;q=0.7, application/json;q=0.5, */*;q=0.1
Accept-Encoding gzip, deflate
Accept-Language en-US,en;q=0.5
Connection keep-alive
Cookie glimpseState=null; glimpseLatestVersion=0.87; glimpseOptions=null; glimpseClientName=null
Host localhost:31652
MaxDataServiceVersion 3.0
Referer http://{localhost}/
User-Agent Mozilla/5.0 (Windows NT 6.2; WOW64; rv:17.0) Gecko/20100101 Firefox/17.0
RESPONSE
{
"odata.error":{
"code":"","message":{
"lang":"en-US","value":"An error has occurred."
},"innererror":{
"message":"The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json; odata=fullmetadata; charset=utf-8'.","type":"System.InvalidOperationException","stacktrace":"","internalexception":{
"message":"The related entity set could not be found. The related entity set is required to serialize the payload.","type":"System.Runtime.Serialization.SerializationException","stacktrace":" at System.Web.Http.OData.Formatter.Serialization.ODataFeedSerializer.WriteObject(Object graph, ODataMessageWriter messageWriter, ODataSerializerContext writeContext)\r\n at System.Web.Http.OData.Formatter.ODataMediaTypeFormatter.<>c__DisplayClass8.<WriteToStreamAsync>b__7()\r\n at System.Threading.Tasks.TaskHelpers.RunSynchronously(Action action, CancellationToken token)"
}
}
}
}
C# Class
namespace DataJsSpike.Models
{
public class Book
{
public string ISBN { get; set; }
public string Title { get; set; }
public string Author { get; set; }
public string Publisher { get; set; }
}
}
Javascript Code
// the URL of the first page to retrieve
var startPage = "api/Books";
var viewModel = new Object();
viewModel.books = ko.observable();
// On initialization, make a request for the first page
$(document).ready(function () {
LoadDataJs();
function LoadDataJs() {
OData.read(startPage, function (data) {
viewModel.books(data.results);
ko.applyBindings(viewModel);
});
}
});
Global.asax
public class WebApiApplication : HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
var modelBuilder = new ODataConventionModelBuilder();
EntityTypeConfiguration<Book> bookConfiguration = modelBuilder.Entity<Book>();
bookConfiguration.HasKey(x => x.ISBN);
modelBuilder.EntitySet<Book>("Books");
IEdmModel model = modelBuilder.GetEdmModel();
GlobalConfiguration.Configuration.EnableOData(model, "api");
}
}
EnableOData actually registers a route for you, but since you registered routes before it ran, those routes take precedence. If you remove this line:
RouteConfig.RegisterRoutes(RouteTable.Routes);
I think it should work out. The request needs to come in on an OData route for the OData formatting to work because the route parses the OData path and gives the formatter information about things like the Entity Set that's being accessed.

GWT: Getting 404 when submitting AJAX request in my GWTTestCase

I'm using Eclipse Indigo on win XP and trying to write a GWT test case for my GWT 2.4 application. Specifically, I'm trying to test an AJAX request, but I'm getting a 404. I thought GWT will spin up its own server in hosted mode? My code is
public class GetHtmlTest extends GWTTestCase {
public void gwtSetUp() {
...
submitButton = new Button();
DOM.setElementAttribute(submitButton.getElement(), "id", Productplus_gwt.SUBMIT_BUTTON_ID);
...
}
#Test
public void testSuccessEvent() {
nameField.setText(VALID_ID);
submitButton.click();
Timer timer = new Timer() {
public void run() {
final Element contentDiv = DOM.getElementById(Productplus_gwt.CONTENT_DIV_ID);
final String divText = contentDiv.getInnerText();
assertNotNull(divText);
assertEquals(-1, divText.toLowerCase().indexOf("error") );
finishTest();
}
};
timer.schedule(100);
delayTestFinish(2000);
} // testSuccessEvent
Ultimately, clicking the button causes this AJAX call ...
productPlusService.getHtml(docId, new AsyncCallback<String>() {
public void onFailure(Throwable caught) {
submitButtonElement.setAttribute("enabled", Boolean.TRUE.toString());
contentDiv.setInnerHTML("<span>Error: " + caught.getMessage() + "</span>");
}
public void onSuccess(String result) {
submitButtonElement.setAttribute("enabled", Boolean.TRUE.toString());
contentDiv.setInnerHTML(result);
// Format tabs
postHtmlProcessing();
}
});
I run the test by right clicking on it, selecting "Run As" and "GWT Test Case". The error in the console was
[WARN] 404 - POST /com.myco.clearing.productplus.Productplus_gwt.JUnit/getHtml (10.40.70.197) 1444 bytes
Request headers
Host: 10.40.70.197:2084
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.19) Gecko/2010031422 Firefox/3.0.19
Accept-Language: en-us
Accept: */*
Connection: Keep-Alive
Referer: http://10.40.70.197:2084/com.myco.clearing.productplus.Productplus_gwt.JUnit/junit-standards.html?gwt.codesvr=10.40.70.197:2080
X-GWT-Permutation: HostedMode
X-GWT-Module-Base: http://10.40.70.197:2084/com.myco.clearing.productplus.Productplus_gwt.JUnit/
Content-Type: text/x-gwt-rpc; charset=utf-8
Content-Length: 217
Response headers
Content-Type: text/html; charset=iso-8859-1
Content-Length: 1444
Any ideas what's going wrong? Thanks, - Dave
For JUnit tests, you have to declare your servlets in your module's gwt.xml using the <servlet path="..." class="..." /> element.

Resources