2014-02-16 3 views
1

Как реализовать пакетное обновление по службе REST, если у нас есть несколько измененных свойств?Пакетное обновление с ServiceStack webservice

Допустим, у нас есть администратор, который управляет 100 клиентскими компьютерами в своем программном обеспечении. Некоторые из компьютеров изменили свое местоположение, а некоторые были удалены. Другие получили новое описание и т. Д. Так что это не только set location = 1 for ids {1,5,8}.

Нужно ли делать несколько вызовов обслуживания для каждого типа изменения или есть возможность, которую я не вижу прямо сейчас?

Обновление:
Это не просто обновление одной или нескольких записей для заданного значения, но и комбинация различных сценариев обновления.

  • Update компьютеры с ids [1,5,8] к locationId=4
  • Delete компьютер с ids [7,9]
  • Create новый компьютер с id [10] и locationId=7

Это не редкость, если клиентская программа управляет кучу записей (здесь компьютеры) и клики на «сохранить», например.

ответ

3

я не хотел бы сделать это следующим образом:

[Route("/computer/{ComputerId}", "POST")] 
public class UpdateComputerRequest : IReturnVoid 
{ 
    public int LocationId { get; set; } 
    public int ComputerId { get; set; } 
} 

[Route("/computer/{ComputerId}", "DELETE")] 
public class DeleteComputerRequest : IReturnVoid 
{ 
    public int ComputerId { get; set; } 
} 

[Route("/computers", "POST")] 
public class BatchRequest : IReturnVoid 
{ 
    public List<UpdateComputerRequest> UpdateRequests { get; set; } 
    public List<DeleteComputerRequest> DeleteRequests { get; set; } 
} 

public class ComputerLocationService : Service 
{ 
    public void Post(UpdateComputerRequest request) 
    { 
     PostImpl(request); 
    } 

    public void Post(DeleteComputerRequest request) 
    { 
     DeleteImpl(request); 
    } 

    public void Post(BatchRequest request) 
    { 
     request.UpdateRequests.ForEach(PostImpl); 
     request.DeleteRequests.ForEach(DeleteImpl); 
    } 

    private void PostImpl(UpdateComputerRequest request) 
    { 
     // do stuff... 
    } 

    private void DeleteImpl(DeleteComputerRequest deleteComputerRequest) 
    { 
     // delete 
    } 
} 

там не создавать, но должно быть понятно, как это сделать ...

+0

Это совершенно разумно! Спасибо! – TheBert

3

Если вы хотите учесть этот сценарий, вам необходимо написать службу, которая принимает массив идентификаторов в запросе, а затем обрабатывает «пакет», например, ниже. Я написал два маршрута, и они принимают одно обновление или пакет обновлений.

// Update a location with single computer 
[Route("/Location/{LocationId}", "POST")] 
public class UpdateLocationRequest : IReturnVoid 
{ 
    public int LocationId { get; set; } 
    public int ComputerId { get; set; } 
} 

// Update a location with multiple computers 
[Route("/Location/{LocationId}/Multiple", "POST")] 
public class UpdateMultipleLocationsRequest : IReturnVoid 
{ 
    public int LocationId { get; set; } 
    public int[] ComputerIds { get; set; } 
}  

public class ComputerLocationService : Service 
{ 
    public void Post(UpdateLocationRequest request) 
    { 
     UpdateLocation(request.LocationId, request.ComputerId); 
    } 

    public void Post(UpdateMultipleLocationsRequest request) 
    { 
     // Multiple computers updated by calling the handler many times. 
     foreach(int computerId in request.ComputerIds) 
      UpdateLocation(request.LocationId, computerId); 
    } 

    // Method for handling updating one location 
    private void UpdateLocation(int locationId, int computerId) 
    { 
     // Logic to perform the update 
    } 
} 

Таким образом, чтобы сделать одно обновление, я бы POST этот JSON в/Location/1

{ "ComputerId": 10 } 

Но сделать пакетное обновление, я бы POST этот JSON в/Location/1/Multiple

{ "ComputerIds": [1,5,8] } 

Надеюсь, что это поможет.

+0

Нет, дело не в этом, я боюсь. Что бы вы сделали, чтобы обновить идентификаторы [1,5,8] до location = 4 И удалить [7,9] И вставить новый элемент {id = 10, locationId = 7} в один запрос. – TheBert

+1

@TheBert Это не функция, поддерживаемая из коробки.Вам нужно будет создать какой-то прокси-запрос. – Scott

+0

Конечно, нет, я понимаю. Но я все еще искал этот шаблон, который вы описали как «вид прокси-запроса». – TheBert

0
$.ajax({ 
     url: "/api/Keywords/Multiple", 
     data: JSON.stringify({ "ComputerIds": [1,5,8] }), 
     contentType: 'application/json; charset=utf-8', 
     type: "POST", 
     success: function (data) { 
      // 
     }, 
     error: function (XMLHttpRequest, textStatus, errorThrown) { 
      // 
     } 
    }) 

[Route("/api/Keywords/Multiple", "POST")] 
public class UpdateMultipleLocationsRequest : IReturn<Response> 
{ 
    public int[] ComputerIds { get; set; } 
} 

public Response Post(UpdateMultipleLocationsRequest request) 
     { 
      return new Response { Result = 1, Message = "..." }; 
     } 

этот код работает хорошо.

1

Javascrit Код:

 // send AJAX request 
     var data = new Array(); 
     var checkedKeyword = { 
      "Keyword": "1", 
      "TotalNum": 100, 
      "State": "stop crawl", 
      "Updatetime": "2015-02-15 23:22:06", 
      "IsChecked": true 
     }; 
     data.push(checkedKeyword); 

     $.ajax({ 
      url: "/api/keywords/processchecked", 
      data: JSON.stringify({ "CheckedKeywords": data }), 
      contentType: 'application/json; charset=utf-8', 
      type: "POST", 
      success: function (data) { 
       // 
      }, 
      error: function (XMLHttpRequest, textStatus, errorThrown) { 
       // 
      } 
     }) 

    }); 

C# Код:

[Route("/api/keywords/processchecked", "POST")] 
public class RequestCheckedKeywords : IReturn<Response> 
{ 
    public List<CheckedKeyword> CheckedKeywords { get; set; } 
} 

public class CheckedKeyword 
{ 
    public string Keyword { get; set; } 
    public int TotalNum { get; set; } 
    public string State { get; set; } 
    public string Updatetime { get; set; } 
    public bool IsChecked { get; set; } 
} 

public class KeywordsServices : Service 
{ 
    public Response Post(RequestCheckedKeywords request) 
    { 
     return new Response { Result = 1, Message = "" }; 
    } 
} 

Javascript код и C# код работает очень хорошо. Я могу получить значение запроса RequestCheckedKeywords, это прямо из javascript.

+0

две очень полезные ссылки: Binding сложный объект для запроса DTO https://groups.google.com/forum/#!topic/servicestack/77EXmIjkrBY Как отправить массив в servicestack с JavaScript? https://groups.google.com/forum/#!topic/servicestack/OmFN4zeH48Q –

Смежные вопросы