WebAPI服务中的批处理请求支持

时间:2017-05-05 05:16:55

标签: c# json ajax asp.net-web-api asp.net-web-api2

我已在webapiconfig.cs中注册了批量WebAPI和WebAPI服务,如下所示

config.Routes.MapHttpBatchRoute(
                routeName: "WebApiBatch",
                routeTemplate: "api/$batch",
                batchHandler: new DefaultHttpBatchHandler(GlobalConfiguration.DefaultServer));

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

webAPI服务如下

员工类

public class Employee
    {
        public int EmployeeID { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }

        public Employee()
        {

        }
        public Employee(int id, string LN, string FN)
        {
            this.EmployeeID = id;
            this.LastName = LN;
            this.FirstName = FN;

        }
    }

员工界面

interface IEmployeeRepository
    {
        IEnumerable<Employee> GetAll();
        Employee Get(int EmployeeID);
        Employee Add(Employee emp);
        void Remove(int EmployeeID);
        bool Update(Employee emp);
    }

员工存储库

public class EmployeeRepository : IEmployeeRepository
    {
        private List<Employee> emp = new List<Employee>();

        public EmployeeRepository()
        {
            emp.Add(new Employee(1, "Davolio", "Nancy"));
            emp.Add(new Employee(2, "Fuller", "Andrew"));
            emp.Add(new Employee(3, "Leverling", "Janet"));
            emp.Add(new Employee(4, "Peacock", "Margaret"));
            emp.Add(new Employee(5, "Buchanan", "Steven"));
        }

        public IEnumerable<Employee> GetAll()
        {
            return emp;
        }

        public Employee Get(int id)
        {
            return emp.Find(p => p.EmployeeID == id);
        }

        public Employee Add(Employee eObj)
        {
            if (eObj == null)
            {
                throw new ArgumentNullException("eObj");
            }
            emp.Add(eObj);
            return eObj;
        }

        public void Remove(int id)
        {
            emp.RemoveAll(p => p.EmployeeID == id);
        }

        public bool Update(Employee eObj)
        {
            if (eObj == null)
            {
                throw new ArgumentNullException("eObj");
            }
            int index = emp.FindIndex(p => p.EmployeeID == eObj.EmployeeID);
            if (index == -1)
            {
                return false;
            }
            emp.RemoveAt(index);
            emp.Add(eObj);
            return true;
        }
    }

WebAPI控制器

public class EmployeeController : ApiController
    {
        static readonly IEmployeeRepository repository = new EmployeeRepository();
        // GET api/<controller>
        [HttpGet]
        public object Get()
        {


            var queryString = HttpContext.Current.Request.QueryString;
            var data = repository.GetAll().ToList();
            return new { Items = data, Count = data.Count() };
        }

        public Employee GetEmployee(int id)
        {
            Employee emp = repository.Get(id);
            if (emp == null)
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }
            return emp;
        }

        // POST api/<controller>
        public HttpResponseMessage PostEmployee(Employee emp)
        {
            emp = repository.Add(emp);
            var response = Request.CreateResponse<Employee>(HttpStatusCode.Created, emp);

            string uri = Url.Link("Employee", new { id = emp.EmployeeID });
            response.Headers.Location = new Uri(uri);
            return response;
        }
         [HttpPut]
        // PUT api/<controller>
        public void PutEmployee(Employee emp)
        {
            if (!repository.Update(emp))
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }

        }
        [HttpDelete]
         public void Delete(int id)
        {
          //  int empID = int32
            Employee emp = repository.Get(id);
            if (emp == null)
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }

            repository.Remove(id);
        }
    }

我已经从客户端提出了ajax请求,以便按如下方式访问服务 我在ajax的数据字段中设置了批处理请求

--batch_ec79f662-862e-4016-a19a-1dbff86d7120
Content-Type: multipart/mixed; boundary=changeset_eb327bfc-5424-47b6-becf-416c43e13899

--changeset_eb327bfc-5424-47b6-becf-416c43e13899
Content-Type: application/http
Content-Transfer-Encoding: binary 

POST /api/Employee HTTP/1.1
Content-Id: 0
Content-Type: application/json; charset=utf-8 

{"EmployeeID":6,"FirstName":"angel","LastName":"dsfs"}

--changeset_eb327bfc-5424-47b6-becf-416c43e13899
Content-Type: application/http
Content-Transfer-Encoding: binary 

PUT /api/Employee HTTP/1.1
Content-Id: 1
Content-Type: application/json; charset=utf-8 

{"EmployeeID":2,"FirstName":"kalai","LastName":"selvi"}


--changeset_eb327bfc-5424-47b6-becf-416c43e13899
Content-Type: application/http
Content-Transfer-Encoding: binary 

PUT /api/Employee HTTP/1.1
Content-Id: 2
Content-Type: application/json; charset=utf-8 

{"EmployeeID":3,"FirstName":"Janet","LastName":"Leverling"}


--changeset_eb327bfc-5424-47b6-becf-416c43e13899
Content-Type: application/http
Content-Transfer-Encoding: binary 

DELETE /api/Employee(3) HTTP/1.1
Content-Id: 3
Content-Type: application/json; charset=utf-8 

--changeset_eb327bfc-5424-47b6-becf-416c43e13899--
--batch_ec79f662-862e-4016-a19a-1dbff86d7120--

整个ajax请求

$.ajax{
Content-type: "multipart/mixed; charset=UTF-8;boundary=batch_ec79f662-862e-4016-a19a-1dbff86d7120",
data:"--batch_ec79f662-862e-4016-a19a-1dbff86d7120↵Content-Type: multipart/mixed; boundary=changeset_eb327bfc-5424-47b6-becf-416c43e13899↵↵--changeset_eb327bfc-5424-47b6-becf-416c43e13899↵Content-Type: application/http↵Content-Transfer-Encoding: binary ↵↵POST /api/Employee HTTP/1.1↵Content-Id: 0↵Content-Type: application/json; charset=utf-8 ↵↵{"EmployeeID":6,"FirstName":"angel","LastName":"dsfs"}↵↵--changeset_eb327bfc-5424-47b6-becf-416c43e13899↵Content-Type: application/http↵Content-Transfer-Encoding: binary ↵↵PUT /api/Employee HTTP/1.1↵Content-Id: 1↵Content-Type: application/json; charset=utf-8 ↵↵{"EmployeeID":2,"FirstName":"kalai","LastName":"selvi"}↵↵↵--changeset_eb327bfc-5424-47b6-becf-416c43e13899↵Content-Type: application/http↵Content-Transfer-Encoding: binary ↵↵PUT /api/Employee HTTP/1.1↵Content-Id: 2↵Content-Type: application/json; charset=utf-8 ↵↵{"EmployeeID":3,"FirstName":"Janet","LastName":"Leverling"}↵↵↵--changeset_eb327bfc-5424-47b6-becf-416c43e13899↵Content-Type: application/http↵Content-Transfer-Encoding: binary ↵↵DELETE /api/Employee(3) HTTP/1.1↵Content-Id: 3↵Content-Type: application/json; charset=utf-8 ↵↵--changeset_eb327bfc-5424-47b6-becf-416c43e13899--↵--batch_ec79f662-862e-4016-a19a-1dbff86d7120--",
type:"POST",
url:"/api/Employee"
}

提出请求后,我收到了一条异常消息

1.  {Message: "The request entity's media type 'multipart/mixed' is not supported for this resource.",…}
1.  ExceptionMessage:"No MediaTypeFormatter is available to read an object of type 'Employee' from content with media type 'multipart/mixed'."
2.  ExceptionType:"System.Net.Http.UnsupportedMediaTypeException"
3.  Message:"The request entity's media type 'multipart/mixed' is not supported for this resource."
StackTrace:"   at System.Net.Http.HttpContentExtensions.ReadAsAsync[T](HttpContent content, Type type, IEnumerable`1 formatters, IFormatterLogger formatterLogger, CancellationToken cancellationToken)
↵   at System.Net.Http.HttpContentExtensions.ReadAsAsync(HttpContent content, Type type, IEnumerable`1 formatters, IFormatterLogger formatterLogger, CancellationToken cancellationToken)
↵   at System.Web.Http.ModelBinding.FormatterParameterBinding.ReadContentAsync(HttpRequestMessage request, Type type, IEnumerable`1 formatters, IFormatterLogger formatterLogger, CancellationToken cancellationToken)"

我犯了什么错误

1 个答案:

答案 0 :(得分:0)

确保您正在调用您配置的实际批处理路由,而不是直接调用EmployeeController上的端点。当你这样做时(我看到你的ajax调用有url:“/ api / Employee”)然后你会得到那条消息,因为这些端点不支持混合模式。如果你改为调用批处理路由(/ api / batch),那么应该这样做。我使用的端点没有美元符号,但我将其配置为api / batch:

                routeName: "batch",
            routeTemplate: "api/batch",