Dopo aver lottato per un'intera serata, ho finalmente fatto funzionare tutto questo. Dopo un po 'di debug ho scoperto che il problema che stavo affrontando era che il mio client stava inviando una cosiddetta richiesta di opzioni di verifica preliminare per verificare se all'applicazione era consentito inviare una richiesta di post con l'origine, i metodi e le intestazioni fornite. Non volevo usare Owin o un APIController, quindi ho iniziato a scavare e ho trovato la seguente soluzione con solo un ActionFilterAttribute. Soprattutto la parte "Accesso-Controllo-Consenti-Intestazioni" è molto importante, poiché le intestazioni qui menzionate devono corrispondere alle intestazioni inviate dalla richiesta.
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MyNamespace
{
public class AllowCrossSiteJsonAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
HttpRequest request = HttpContext.Current.Request;
HttpResponse response = HttpContext.Current.Response;
// check for preflight request
if (request.Headers.AllKeys.Contains("Origin") && request.HttpMethod == "OPTIONS")
{
response.AppendHeader("Access-Control-Allow-Origin", "*");
response.AppendHeader("Access-Control-Allow-Credentials", "true");
response.AppendHeader("Access-Control-Allow-Methods", "GET, PUT, POST, DELETE");
response.AppendHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, X-RequestDigest, Cache-Control, Content-Type, Accept, Access-Control-Allow-Origin, Session, odata-version");
response.End();
}
else
{
HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
HttpContext.Current.Response.Cache.SetNoStore();
response.AppendHeader("Access-Control-Allow-Origin", "*");
response.AppendHeader("Access-Control-Allow-Credentials", "true");
if (request.HttpMethod == "POST")
{
response.AppendHeader("Access-Control-Allow-Methods", "GET, PUT, POST, DELETE");
response.AppendHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, X-RequestDigest, Cache-Control, Content-Type, Accept, Access-Control-Allow-Origin, Session, odata-version");
}
base.OnActionExecuting(filterContext);
}
}
}
}
Infine, il mio metodo di azione MVC è simile al seguente. Importante qui è anche menzionare le Opzioni HttpVerbs, perché altrimenti la richiesta di verifica preliminare fallirà.
[AcceptVerbs(HttpVerbs.Post | HttpVerbs.Options)]
[AllowCrossSiteJson]
public async Task<ActionResult> Create(MyModel model)
{
return Json(await DoSomething(model));
}