NET Core 2 MVC - Хранение объектов для метода GET - PullRequest
0 голосов
/ 21 ноября 2018

У меня есть поисковая форма на моей странице индекса для поиска доступных номеров и отелей во внешней базе данных.После отправки формы пользователь перенаправляется на новую страницу со списком доступных отелей (номера появятся позже).

После отправки формы параметры поиска помещаются в одну строку, которая затем передается в класс TcpConnectionManager через ModelManager, где эта строка сериализуется в json и отправляется через сокет на внешний Java-сервер.Сервер десериализует json, помещает строковые элементы в запрос SQL, который, в свою очередь, проверяет базу данных и возвращает все доступные объекты отелей.Эти гостиничные объекты затем помещаются в объект HotelList, сериализуются в json и отправляются обратно через сокет в класс TcpConnectionManager.

Моя самая большая проблема заключалась в реализации метода GET внутри HotelController.Попытка сохранить объект HotelList внутри класса TcpConnectionManager, но метод GET всегда возвращал нулевой объект.

До сих пор мне удавалось добиться того, чего я хочу, реализовав одноэлементный класс TempHotelsStorage, в котором есть методы для хранения и извлечения объекта HotelList, но меня больше всего беспокоит, является ли это правильным / правильным подходом в этомситуация?Если нет, то как это можно улучшить?

HomeController.cs:

namespace NETCoreWebApp.Controllers
{
public class HomeController : Controller
{
    private readonly IModelManager iModelManager = new ModelManager();

    public IActionResult Index()
    {
        return View();
    }

    public IActionResult Hotel()
    {
        return View();
    }

    [HttpPost]
    public IActionResult Index(SearchRoomsModel model)
    {
        string query = string.Format("{0},{1} 12:00,{2} 12:00,{3},{4}", model.Location, model.CheckIn, model.CheckOut, model.NumAdults, model.NumChild);

        iModelManager.GetAvailableRooms(query);

        return RedirectToAction("Hotel");
    }

    [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
    public IActionResult Error()
    {
        return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
    }
}
}

HotelController.cs:

namespace NETCoreWebApp.Controllers
{
[Route("api/hotel")]
[ApiController]
public class HotelController : Controller
{
    public TempHotelsStorage hotelsStorage = TempHotelsStorage.Instance;

    [HttpGet]
    public ActionResult<HotelList> Get()
    {            
        return hotelsStorage.GetHotelsFromStorage(); 
    }
}
}

TcpConnectionManager.cs:

public class TcpConnectionManager
{
    public TempHotelsStorage hotelStorage = TempHotelsStorage.Instance;

    public void GetAvailableRooms(string query)
    {
        //Sending json to other server

        TcpClient clientSocket = new TcpClient();

        clientSocket.Connect("127.0.0.1", 6767);

        NetworkStream ns = clientSocket.GetStream();

        string jsonRequest = query;

        string jsonToSend = JsonConvert.SerializeObject(jsonRequest);

        byte[] dataBytes = Encoding.UTF8.GetBytes(jsonToSend);

        ns.Write(dataBytes, 0, dataBytes.Length);

        //Receiving json from other server

        byte[] buffer = new byte[clientSocket.ReceiveBufferSize];

        int bytesRead = ns.Read(buffer, 0, clientSocket.ReceiveBufferSize);

        string DataReceived = Encoding.UTF8.GetString(buffer, 2, bytesRead);

        HotelList hotelList = JsonConvert.DeserializeObject<HotelList>(DataReceived);

        hotelStorage.SaveHotels(hotelList);

        clientSocket.Close();
        ns.Close();
    }
}

TempHotelsStorage.cs:

namespace NETCoreWebApp.Models
{
public class TempHotelsStorage
{
    private static readonly TempHotelsStorage instance = new TempHotelsStorage();

    static TempHotelsStorage() { }
    private TempHotelsStorage() { }

    public HotelList hotelList { get; set; } = new HotelList();

    public void SaveHotels(HotelList hList)
    {
        for (int i = 0; i < hList.Size(); i++)
        {
            hotelList.AddHotel(hList.GetHotelByIndex(i));
        }
    }

    public HotelList GetHotelsFromStorage()
    {
        return hotelList;
    }

    public static TempHotelsStorage Instance
    {
        get
        {
            return instance;
        }
    }
}
}

jПросить список всех отелей:

function getData() {
$.ajax({
    type: "GET",
    url: uri,
    cache: false,
    dataType: 'json',
    success: function (data) {

        const hotelListContainer = $('#hotelListContainer');          

        for (var i = 0; i < data.hotelList.length; i++)
        {
            hotelListContainer
                .append(
                    "<div class='col-md-12' id='hotelListItem'>" +
                    "<div class='col-md-3' id='hotelItemPicture'>ID:" + data.hotelList[i].hid + "</div>" +
                    "<div class='col-md-9' id='hotelItemDescription'>NAME:" + data.hotelList[i].name + "</div>" +
                    "</div>"
                );
        }
    }
});
}

HTML-разметка:

<div class="container-fluid" id="hotelListArea">
<div class="row">
    <div class="col-md-2"></div>
    <div class="col-md-8" id="centerHotelListArea">            
        <div id="hotelListContainer">
            <div id="hotelContainerItem"></div>
        </div>
    </div>
    <div class="col-md-2"></div>
</div>

Ответы [ 2 ]

0 голосов
/ 23 ноября 2018

Следуя совету Марчиелло, используя внедрение зависимостей, я сначала зарегистрировал одноэлементную службу в классе запуска:

services.AddSingleton<IModelManager, ModelManager>();

А затем добавил одноэлементную службу в качестве параметра конструктора для каждого контроллера, например:

    private readonly IModelManager _modelManager;

    public HotelController(IModelManager modelManager)
    {
        _modelManager = modelManager;
    }

Класс ModelManager, который является просто фасадом модели, выступает в качестве точки доступа для контроллеров API для хранения и извлечения данных путем вызова методов GET и POST.

HomeController:

    [HttpPost]
    public IActionResult Index(SearchRoomsModel model)
    {
        string _query = string.Format("{0},{1} 12:00,{2} 12:00,{3},{4}", model.Location, model.CheckIn, model.CheckOut, model.NumAdults, model.NumChild);

        _modelManager.SaveQuery(_query);

        return RedirectToAction("Hotel");
    }

HotelController:

    [HttpGet]
    public ActionResult<HotelList> Get()
    {
        return _modelManager.ReturnQuery();
    }

ModelManager:

    private readonly TcpConnectionManager _tcpManager = new TcpConnectionManager();
    public string _query;

    public void SaveQuery(string query)
    {
        _query = query;
    }

    public HotelList ReturnQuery()
    {
        HotelList hotelList = _tcpManager.ReturnHotelList(_query);

        return hotelList;
    }

ModelManager является одиночным, потому что контроллеру отеля необходим доступтот же экземпляр ModelManager, в котором контроллер Home хранит строку запроса перед перенаправлением в представление Hotel.Кроме того, следующим шагом будет перечисление доступных номеров на основе выбора отеля, а для метода GET контроллеров комнат потребуется доступ к тому же объекту HotelList, который есть у контроллера отеля.

0 голосов
/ 21 ноября 2018

Вы можете избавить себя от головной боли и позволить внедрению зависимостей управлять сроком службы ваших сервисов.Вы можете зарегистрировать сервис в методе ConfigureServices вашего класса Startup, объявив его интерфейс и реализацию, такую ​​как:
services.AddTransient<ITcpConnectionManager, TcpConnectionManager>();
Затем просто добавьте упомянутую службу в качестве параметра construtor для вашего контроллера.
Также ваш TempHotelsStorage класс кажется здесь несколько избыточным.Вы могли бы избежать его использования полностью, если бы вы просто return JsonConvert.DeserializeObject<HotelList>(DataReceived); в вашем GetAvailableRooms методе.В целом, я бы также не советовал управлять подключением и извлекать данные одним и тем же способом, но это может поставить за рамки этого конкретного вопроса.

Относительно использования одноэлементных объектов - вы обычно используете их в тех случаях, когда вам нужносохранить объект в течение всего времени жизни вашего приложения, например, сохранить некоторое состояние.Здесь дело не в этом.

...