我在索引页面上有一个搜索表单,可以在外部数据库中搜索可用的客房和酒店。提交表单后,用户将被重定向到包含可用酒店列表的新页面(稍后将提供客房)。
提交表单后,将搜索参数放入单个字符串中,然后将其通过ModelManager传递到TcpConnectionManager类,在此该字符串被序列化为json并通过套接字发送到外部Java服务器。服务器反序列化json,将字符串元素放在SQL查询中,然后SQL查询数据库并返回所有可用的hotel对象。然后将这些酒店对象放置在HotelList对象中,序列化为json并通过套接字发送回TcpConnectionManager类。
我最大的问题是在HotelController中实现GET方法。试图将HotelList对象存储在TcpConnectionManager类中,但是GET方法始终返回空对象。
到目前为止,我已经可以通过实现一个单例类TempHotelsStorage来实现我想要的目标,该类具有存储和检索HotelList对象的方法,但是我最大的担心是在这种情况下这是否是一种好/正确的方法?如果没有,那么如何改善呢?
HomeController.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();
}
}
}
HotelController.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();
}
}
TcpConnectionManager.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;
}
}
}
}
TempHotelsStorage.cs:
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>"
);
}
}
});
}
jQuery列出所有酒店:
<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>
HTML标记:
cd c:\Users\LOrdBenche\source\repos\parsingTest\parsingTest\producedJSON
答案 0 :(得分:2)
您可以省去一些麻烦,并允许依赖项注入来处理服务的寿命。您可以通过声明服务的接口和实现,在id
类的ConfigureServices
方法中注册服务,例如:
Startup
然后只需将所述服务添加为控制器的构造器参数即可。
同样,您的services.AddTransient<ITcpConnectionManager, TcpConnectionManager>();
类在这里似乎有些多余。如果仅在TempHotelsStorage
方法中使用return JsonConvert.DeserializeObject<HotelList>(DataReceived);
,则可以完全避免使用它。
通常,我也建议不要使用相同的方法来管理连接和检索数据,但这可能超出了此特定问题的范围。
关于使用单例对象-通常在需要在应用程序的整个生命周期中保持对象(例如,保持某些状态)的情况下使用它们。这里不是这种情况。
答案 1 :(得分:0)
按照Marchyello的建议,首先使用依赖项注入在Startup类中注册了单例服务:
flask.cli.NoAppException: While importing "run", an ImportError was raised:
Traceback (most recent call last):
File "/home/eric/Documents/coding/venv/lib/python3.6/site-packages/flask/cli.py", line 235, in locate_app
__import__(module_name)
File "/home/eric/Documents/coding/adminsystem/run.py", line 3, in <module>
from app import create_app
File "/home/eric/Documents/coding/adminsystem/app/__init__.py", line 16, in <module>
from .home.views import check_role
File "/home/eric/Documents/coding/adminsystem/app/home/__init__.py", line 5, in <module>
from . import views
File "/home/eric/Documents/coding/adminsystem/app/home/views.py", line 9, in <module>
from ..auth.forms import MemberRegistrationForm
File "/home/eric/Documents/coding/adminsystem/app/auth/__init__.py", line 5, in <module>
from . import views
File "/home/eric/Documents/coding/adminsystem/app/auth/views.py", line 4, in <module>
from ..home.views import check_role
ImportError: cannot import name 'check_role'
然后将单例服务添加为每个控制器的构造函数参数,如下所示:
services.AddSingleton<IModelManager, ModelManager>();
ModelManager类只是模型的基础,它是api控制器通过调用GET和POST方法存储和检索数据的访问点。
HomeController:
private readonly IModelManager _modelManager;
public HotelController(IModelManager modelManager)
{
_modelManager = modelManager;
}
HotelController:
[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");
}
ModelManager:
[HttpGet]
public ActionResult<HotelList> Get()
{
return _modelManager.ReturnQuery();
}
ModelManager是单例的,因为Hotel控制器需要访问Home控制器将查询字符串存储到的ModelManager实例,然后再重定向到Hotel视图。此外,下一步将是基于酒店选择列出可用的房间,并且房间控制器的GET方法将需要访问与酒店控制器相同的HotelList对象。