एक पूरी शाम के लिए संघर्ष करने के बाद आखिरकार मुझे यह काम करना पड़ा। कुछ डिबगिंग के बाद मुझे पता चला कि मैं जिस समस्या में चल रहा था, वह यह था कि मेरा क्लाइंट एक तथाकथित प्रीफ्लाइट ऑप्शन रिक्वेस्ट भेज रहा था ताकि यह जांचा जा सके कि आवेदन को मूल, विधियों और हेडर के साथ पोस्ट अनुरोध भेजने की अनुमति दी गई थी या नहीं। मैं Owin या APIController का उपयोग नहीं करना चाहता था, इसलिए मैंने खुदाई शुरू की और सिर्फ ActionFilterAttribute के साथ निम्नलिखित समाधान के साथ आया। विशेष रूप से "एक्सेस-कंट्रोल-अनुमति-हेडर्स" भाग बहुत महत्वपूर्ण है, क्योंकि वहाँ उल्लिखित हेडर को आपके अनुरोध भेजने वाले हेडर से मिलान करना होगा।
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);
}
}
}
}
अंत में, मेरी MVC एक्शन विधि इस तरह दिखती है। यहां महत्वपूर्ण विकल्प HttpVerbs का भी उल्लेख करना है, क्योंकि अन्यथा प्रीफ़लाइट अनुरोध विफल हो जाएगा।
[AcceptVerbs(HttpVerbs.Post | HttpVerbs.Options)]
[AllowCrossSiteJson]
public async Task<ActionResult> Create(MyModel model)
{
return Json(await DoSomething(model));
}