2016-12-18 21 views
5

Praca nad nowym projektem przy użyciu serwera zaplecza WebAPI i mam problemy z publikowaniem w kontrolerze z rzeczywistej strony internetowej, mimo że Postman nie ma problemów z publikowaniem w kontrolerze. Otrzymuję o błędzie 415, rejestrowanie konsoli Przeglądarka:Błąd 415 podczas publikowania w ASP.Net Core WebAPI przy użyciu XMLHttpRequest

HTTP415: UNSUPPORTED MEDIA TYPE - The server is refusing to service the request because the entity of the request is in a format not supported by the requested resource for the requested method. 
(XHR)OPTIONS - http://localhost:5000/api/Users 

Choć dziennik z Kestrel jest

info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1] 
     Request starting HTTP/1.1 OPTIONS http://localhost:5000/api/Users 0 
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 OPTIONS http://localhost:5000/api/Users 0 
info: Microsoft.AspNetCore.Mvc.StatusCodeResult[1] 
     Executing HttpStatusCodeResult, setting HTTP status code 415 
Microsoft.AspNetCore.Mvc.StatusCodeResult:Information: Executing HttpStatusCodeResult, setting HTTP status code 415 
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2] 
     Executed action SchoolsChat.Controllers.UserContoller.Post (SchoolsChat) in 2.5323ms 
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Executed action SchoolsChat.Controllers.UserContoller.Post (SchoolsChat) in 2.5323ms 
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2] 
     Request finished in 6.6615ms 415 
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 6.6615ms 415 

Staram się pisać następujące JSON:

{ 
    UserDOB: "2016-12-18", 
    UserFirstName: "asdf", 
    UserLastName: "asasdf", 
    UserName: "asdf", 
    UserSecret: "asdf" 
} 

za pomocą tego TypeScript class

/** 
* JsonPost 
*/ 
class JsonPost { 
    private _response: number; 
    public get Reponse(): number { 
     return this._response; 
    } 
    constructor(link: string, data: Object) { 
     let request = new XMLHttpRequest(); 
     request.withCredentials = true; 

     request.open("POST", APIUri + link, true); 
     request.setRequestHeader("content-type", "application/json"); 
     request.setRequestHeader("cache-control", "no-cache"); 
     request.onreadystatechange =() => this._response = request.status; 
     console.log(request); 
     request.send(JSON.stringify(data)); 
    } 
} 

T on model Użytkownika jest

public class User 
    { 
     [KeyAttribute] 
     public int UserId { get; set; } 
     [RequiredAttribute] 
     public int SchoolId { get; set; } 
     [RequiredAttribute] 
     public string UserName { get; set; } 
     [RequiredAttribute] 
     [DataTypeAttribute(DataType.Password)] 
     public string UserSecret { get; set; } // Unnecessary due to school linking? 
     [RequiredAttribute] 
     public virtual School UserSchool { get; set; } 
    } 

Podczas gdy kontroler do delegowania jest proste, wystarczy wyprowadzania imię

[HttpPost] 
    public IActionResult Post([FromBody]User user) 
    { 
     Console.WriteLine(user.UserName); 
     return StatusCode(200); 
    } 

Edycja Chociaż odpowiedź od Nemec był helpeful w rozwiązaniu problemu, znalazłem dla interfejsu WebAPI najlepszą rozdzielczością było tylko konfigurowanie cors przy użyciu appuseCors jako services.AddCors w wielu przypadkach w rzeczywistości nie zawierało niezbędnych nagłówków w odpowiedzi.

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
     { 
      app.UseCors(options => options.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod().AllowCredentials()); 
      loggerFactory.AddConsole(Configuration.GetSection("Logging")); 
      loggerFactory.AddDebug(); 
      app.UseMvc(); 
     } 
+3

Zobacz http: // stackoverflow.com/questions/8153832/xmlhttprequest-changes-post-to-option, dlaczego widzisz żądanie 'OPCJE' zamiast' POST'. –

Odpowiedz

5

Jak Evan wspomniał w swoim komentarzu, Twój POST zamienia się w OPTIONS podczas dokonywania żądania ajax cross-origin. Ze względu na zasady bezpieczeństwa dotyczące różnych źródeł przeglądarek przeglądarka internetowa musi poinformować przeglądarkę/js, że twoja witryna może wysyłać żądania ajax wobec niej.

https://docs.microsoft.com/en-us/aspnet/core/security/cors

Aby CORS konfiguracji dla aplikacji pakietu Microsoft.AspNetCore.Cors dodać do swojego projektu.

Dodaj usługi Cors w Startup.cs:

public void ConfigureServices(IServiceCollection services) 
{ 
    services.AddCors(); 
} 

Jeśli zastosujemy się do instrukcji związanych, można nawet użyć IApplicationBuilder.UseCors dalszego dostosowywania, które witryny są dozwolone.

Na przykład:

app.UseCors(builder => 
    builder.WithOrigins("http://example.com") 
      .AllowAnyHeader() 
); 

Postman to aplikacja, a więc ma możliwość zwolnienia się z zasadami cross-pochodzenia.

+0

Dziękuję za tak głęboką odpowiedź – bsizzle

24

W moim przypadku problem polegał na tym, że umieściłem atrybut FromBody przed moim parametrem akcji.

Od:

[HttpPost("Contact")] 
public async Task<IActionResult> NewContact([FromBody]Contact contact) 

Do:

[HttpPost("Contact")] 
public async Task<IActionResult> NewContact(Contact contact) 
+0

dzięki. który rozwiązał ten problem w moim przypadku. – MovGP0

+4

Ja też. Ale dlaczego? –

Powiązane problemy