ASP.NET MVC Ajax Post has no data - ajax

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

Related

Preflight request is ok, then, after auth, response does not contain allow cors header

Asp MVC 5 app deployed on IIS 8.5.
Need to enable ajax request from a number of clients.
Server-side I have In WebApiConfig.cs
config.EnableCors();
In controller:
[EnableCors(origins: "http://localhost:59901", headers: "*", methods: "*", SupportsCredentials = true)]
public class ItemController : Controller
Client side
$("#getItem").on("click", function (e) {
var myurl = "http://servername/item/details/1"
$.ajax({
url: myurl,
type: "GET",
dataType: "JSON",
xhrFields: {
withCredentials: true
},
contentType: "application/json; charset=utf-8",
error: function (jqXHR, textStatus, errorThrown) {
$('#result').text(jqXHR.responseText || textStatus);
},
success: function (result) {
$('#result').text(result);
}
});
});
Running client from VisualStudio Origin is http://localhost:59901.
Running the ajax request I get the following in fiddler:
1. Preflight request/response
OPTIONS http://vrtsrv01.webdev.local/item/details/1 HTTP/1.1
Host: vrtsrv01.webdev.local
Connection: keep-alive
Access-Control-Request-Method: GET
Origin: http://localhost:59901
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36
Access-Control-Request-Headers: content-type
Accept: */*
Referer: http://localhost:59901/Home/Index
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8,it;q=0.6,it-IT;q=0.4
HTTP/1.1 200 OK
Server: Microsoft-IIS/8.5
Access-Control-Allow-Origin: http://localhost:59901
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, MaxDataServiceVersion
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Credentials: true
X-Powered-By: ASP.NET
Date: Sat, 13 May 2017 15:34:54 GMT
Content-Length: 0
2. GET request without credentials/ 401 error response
GET http://vrtsrv01.webdev.local/item/details/1 HTTP/1.1
Host: vrtsrv01.webdev.local
Connection: keep-alive
Accept: application/json, text/javascript, */*; q=0.01
Origin: http://localhost:59901
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36
Content-Type: application/json; charset=utf-8
Referer: http://localhost:59901/Home/Index
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8,it;q=0.6,it-IT;q=0.4
HTTP/1.1 401 Unauthorized
Cache-Control: private
Content-Type: text/html
Server: Microsoft-IIS/8.5
X-AspNet-Version: 4.0.30319
WWW-Authenticate: Negotiate
WWW-Authenticate: NTLM
X-Powered-By: ASP.NET
Date: Sat, 13 May 2017 15:34:54 GMT
Content-Length: 1352
Proxy-Support: Session-Based-Authentication
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/>
<title>401 - Autorizzazione negata: accesso negato a causa di credenziali non valide.</title>
....
</head>
<body>
<div id="header"><h1>Errore del server</h1></div>
....
</body>
</html>
3. GET request with NTLM token for auth / response without Allow CORS header
GET http://vrtsrv01.webdev.local/item/details/1 HTTP/1.1
Host: vrtsrv01.webdev.local
Connection: keep-alive
Authorization: Negotiate <...NTLM TOKEN HERE ...>
Accept: application/json, text/javascript, */*; q=0.01
Origin: http://localhost:59901
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36
Content-Type: application/json; charset=utf-8
Referer: http://localhost:59901/Home/Index
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8,it;q=0.6,it-IT;q=0.4
HTTP/1.1 200 OK
Cache-Control: private
Content-Type: application/json; charset=utf-8
Server: Microsoft-IIS/8.5
X-AspNetMvc-Version: 5.2
X-AspNet-Version: 4.0.30319
Persistent-Auth: true
X-Powered-By: ASP.NET
Date: Sat, 13 May 2017 15:34:58 GMT
Content-Length: 8557
{"id":1, .....}
QUESTION
Why after enabling MVC app for CORS and seeing the right response to preflight request, the response obtained after NTLM authentication does not contain the expected Access-Control-Allow-Origin header?
I'm not sure that it will help you, but it might help someone else looking to have both NTLM and CORS enabled.
CORS enabling
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
var corsAttr = new EnableCorsAttribute("*", "*", "*") { SupportsCredentials = true };
//SupportsCredentials = true means that we will add Access-Control-Allow-Credentials to the response.
config.EnableCors(corsAttr);
}
}
SupportsCredentials = true means that we will add Access-Control-Allow-Credentials to the response.
Other solutions,
global.asax.cs - properly reply with headers that allow caller from another domain to receive data
protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
if (Context.Request.HttpMethod == "OPTIONS")
{
Context.Response.AddHeader("Access-Control-Allow-Origin", Context.Request.Headers["Origin"]);
Context.Response.AddHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept,MaxDataServiceVersion");
Context.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
Context.Response.AddHeader("Access-Control-Allow-Credentials", "true");
Context.Response.End();
}
}
SOLVED (...for now...)
The invoked action was a controller action returning Json. This does not work with CORS. I need to create an API controller, cannot use the existing controller. This leads to code duplication, but I have no time now to refactor the whole application to use a single controller both for MVC and API

WebApi HttpPost not working with parameters

I have a Web Api project with this route config
var config = GlobalConfiguration.Configuration;
config.Routes.MapHttpRoute(
"DefaultApiRoute",
"api/v1/{controller}/{action}");
I have two post method
[HttpPost]
public IHttpActionResult RetrieveTestNoParam()
{
return new JsonResult<string>("This is a test", new JsonSerializerSettings(), Encoding.UTF8, this);
}
[HttpPost]
public IHttpActionResult RetrieveTest(string input)
{
return new JsonResult<string>(input, new JsonSerializerSettings(), Encoding.UTF8, this);
}
The first one is working but the second one gives this respone
{
"Message": "No HTTP resource was found that matches the request URI 'http://test.dev.local/api/v1/NewsApi/RetrieveTest'.",
"MessageDetail": "No action was found on the controller 'NewsApiController' that matches the request."
}
This is what I see in fiddler
POST http://test.dev.local/api/v1/NewsApi/RetrieveTest HTTP/1.1
Host: test.dev.local
Connection: keep-alive
Content-Length: 261
Cache-Control: no-cache
Origin: chrome-extension://fhbjgbiflinjbdggehcddcbncdddomop
Content-Type: application/javascript
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.84 Safari/537.36
Postman-Token: c2ba631b-4bfd-9379-bf40-0ca1a6a8a3bc
Accept: */*
DNT: 1
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.8,nl;q=0.6
Cookie: ASP.NET_SessionId=4kgfwd2u3pwusfdvdsrkt2vt; SC_ANALYTICS_GLOBAL_COOKIE=ddd9185a3e8940c9823e81b7d38cdf20|False; sc_expview=0
------WebKitFormBoundaryxdYhzJ7A8WnI8qaa
Content-Disposition: form-data; name="input"
Dit is de input
------WebKitFormBoundaryxdYhzJ7A8WnI8qaa
Content-Disposition: form-data; name="czczcsdcsdf"
sdfsfsdfsdff
------WebKitFormBoundaryxdYhzJ7A8WnI8qaa--
Any ideas?
Other questions I have about Web Api:
Can a controller contain multiple get or post methods?
Do I need the actionname attribute and what does this attribute do?
Regards
Danny

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

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

Why the Symfony form is "not submitted" after data is correctly sent through AJAX?

I want to sent a Symfony form through AJAX (AngularJS).
However, even if data is clearly sent, the form is said by Symfony to be "not submitted" (no error actually, but some debug show that isSubmitted returns false)
Here is a test on FOSUserBundle registration form.
EDIT: although pictures appear small, they are sufficiently resolved so that they are perfectly readable if displayed at their full size.
Here are the logs when I use a standard submission from an HTTP form:
Here are the logs when I use AJAX submission:
I have disabled CSRF token
The method I use from AJAX is "post" so it should be ok since it is the default Symfony expects (and FOSUserBundle does not override that default AFAIK).
Other forms (outside of FOSUserBundle scope) are correctly sent with AJAX
Would you have any idea on the matter? Any pointer? Or any other log I could check?
EDIT:
I use the default FOSUserBundle registration controller.
I almost use the default FOSUserBundle registration form, but I have added a (currently) empty child form which I'll need it further in the development.
namespace NONG\SecurityBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
class UserRegistrationType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options) {}
public function getParent() {
return 'fos_user_registration';
}
public function getName() {
return 'nong_user_registration';
}
}
Headers and data sent with the HTML form (NB. added a dot before star in Accept so that the coloration stays correct):
POST /server/web/testfosuser/register/ HTTP/1.1
Host: mywebsite.com
Connection: keep-alive
Content-Length: 229
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/.*;q=0.8
Origin: http://mywebsite.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.111 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Referer: http://mywebsite.com/server/web/testfosuser/register/
Accept-Encoding: gzip, deflate
Accept-Language: fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4
Cookie: PHPSESSID=xxxxxxxxxxxxxxxxxxxxxxxxx
fos_user_registration_form%5Bemail%5D=bidon%40bidon.com&
fos_user_registration_form%5Busername%5D=bidon&
fos_user_registration_form%5BplainPassword%5D%5Bfirst%5D=bidon&
fos_user_registration_form%5BplainPassword%5D%5Bsecond%5D=bidon
Headers sent with the AJAX request: (NB. added a dot before star in Accept so that the coloration stays correct):
POST /server/web/testfosuser/register HTTP/1.1
Host: mywebsite.com
Connection: keep-alive
Content-Length: 229
Accept: application/json, text/plain, */.*
Origin: http://mywebsite.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.111 Safari/537.36
Content-Type: application/json;charset=UTF-8 application/x-www-form-urlencoded; charset=UTF-8
Referer: http://mywebsite.com/client/
Accept-Encoding: gzip, deflate
Accept-Language: fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4
Cookie: PHPSESSID=xxxxxxxxxxxxxxxxxxxxxxxxx
fos_user_registration_form%5Bemail%5D=bidonqdsfqsdf%40qsdf&
fos_user_registration_form%5Busername%5D=charles222&
fos_user_registration_form%5BplainPassword%5D%5Bfirst%5D=bidon&
fos_user_registration_form%5BplainPassword%5D%5Bsecond%5D=bidon
I had similar problems and i changed the following inside of the controller:
$user = new User();
$form = $this->createForm(
new UserRegistrationType(),
$user,
array(
'attr' => array('novalidate' => 'novalidate'),
'action' => $this->generateUrl('user_registration')
)
);
Turning of the html5 error bubbles and setting the action URL directly worked for me. If this is not working, show your JS code.
I finally managed to find the correction:
The correct URL is ...../register/ with a final / that I forgot when I did the AJAX request.
However, I'm not sure what are the mechanisms at stake here. The deepest I could go debuging (when using the wrong URL) was in HttpFoundationRequestHandler, where the $request->getMethod() call returned GET (instead of POST), thus not submitting the form.

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.

Resources