feat: enhance Hanvon HTTP client for face push and log parsing
Face-only upload, timeout config, enrollid-based attendance parse.main
parent
2719e53338
commit
e5cbed083e
|
|
@ -3,6 +3,7 @@ using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Configuration;
|
using System.Configuration;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Web.Script.Serialization;
|
using System.Web.Script.Serialization;
|
||||||
|
|
@ -32,7 +33,8 @@ namespace HanvonF710XAttendanceService
|
||||||
public static HanvonHttpApiClient ForMachine(AttendanceMachine machine)
|
public static HanvonHttpApiClient ForMachine(AttendanceMachine machine)
|
||||||
{
|
{
|
||||||
int httpPort = GetIntSetting("DEVICE_HTTP_PORT", 80);
|
int httpPort = GetIntSetting("DEVICE_HTTP_PORT", 80);
|
||||||
return new HanvonHttpApiClient(machine.MachineIp, httpPort, MachineScope.GetDevicePassword());
|
int timeoutMs = MachineUserDeleteSettings.GetHttpTimeoutMs();
|
||||||
|
return new HanvonHttpApiClient(machine.MachineIp, httpPort, MachineScope.GetDevicePassword(), timeoutMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool TryLogin(out string error)
|
public bool TryLogin(out string error)
|
||||||
|
|
@ -311,6 +313,78 @@ namespace HanvonF710XAttendanceService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool TrySetFacePhotoOnly(int enrollId, string faceBase64, out string error)
|
||||||
|
{
|
||||||
|
error = null;
|
||||||
|
if (string.IsNullOrWhiteSpace(faceBase64))
|
||||||
|
{
|
||||||
|
error = "face photo is empty";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var resp = Post(new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
{ "cmd", "setuserinfo" },
|
||||||
|
{ "password", _password },
|
||||||
|
{ "enrollid", enrollId },
|
||||||
|
{ "face", faceBase64 }
|
||||||
|
});
|
||||||
|
if (IsSuccess(resp)) return true;
|
||||||
|
error = GetMsg(resp) ?? "setuserinfo face push failed";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
error = ex.Message;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool TrySetUserWithFacePhoto(int enrollId, string name, string faceBase64, out string error)
|
||||||
|
{
|
||||||
|
error = null;
|
||||||
|
if (string.IsNullOrWhiteSpace(faceBase64))
|
||||||
|
{
|
||||||
|
error = "face photo is empty";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var resp = Post(new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
{ "cmd", "setuserinfo" },
|
||||||
|
{ "password", _password },
|
||||||
|
{ "enrollid", enrollId },
|
||||||
|
{ "name", name ?? enrollId.ToString() },
|
||||||
|
{ "department", "" },
|
||||||
|
{ "shiftid", 1 },
|
||||||
|
{ "admin", 0 },
|
||||||
|
{ "pwd", 0 },
|
||||||
|
{ "card", 0 },
|
||||||
|
{ "zoneid", 0 },
|
||||||
|
{ "groupid", 0 },
|
||||||
|
{ "access_times", 0 },
|
||||||
|
{ "verifymode", 8 },
|
||||||
|
{ "birthday", "" },
|
||||||
|
{ "starttime", "" },
|
||||||
|
{ "endtime", "" },
|
||||||
|
{ "userprofile", "" },
|
||||||
|
{ "face", faceBase64 }
|
||||||
|
});
|
||||||
|
if (IsSuccess(resp)) return true;
|
||||||
|
error = GetMsg(resp) ?? "setuserinfo face push failed";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
error = ex.Message;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public bool TryGetFaceRecord(int enrollId, out string recordBase64, out string name, out string error)
|
public bool TryGetFaceRecord(int enrollId, out string recordBase64, out string name, out string error)
|
||||||
{
|
{
|
||||||
recordBase64 = null;
|
recordBase64 = null;
|
||||||
|
|
@ -346,6 +420,145 @@ namespace HanvonF710XAttendanceService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool TryGetUserProfile(int enrollId, out string faceflag, out string photourl, out string name, out string error)
|
||||||
|
{
|
||||||
|
faceflag = null;
|
||||||
|
photourl = null;
|
||||||
|
name = null;
|
||||||
|
error = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var resp = Post(new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
{ "cmd", "getuserinfo" },
|
||||||
|
{ "password", _password },
|
||||||
|
{ "enrollid", enrollId }
|
||||||
|
});
|
||||||
|
if (!IsSuccess(resp))
|
||||||
|
{
|
||||||
|
error = GetMsg(resp) ?? "getuserinfo failed";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
name = GetString(resp, "name");
|
||||||
|
faceflag = GetString(resp, "faceflag");
|
||||||
|
photourl = GetString(resp, "photourl");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
error = ex.Message;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool ProfileIndicatesFaceEnrolled(string faceflag, string photourl)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrWhiteSpace(photourl))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(faceflag))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.Equals(faceflag, "0", StringComparison.OrdinalIgnoreCase)
|
||||||
|
|| string.Equals(faceflag, "false", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (int.TryParse(faceflag.Trim(), out int flagValue))
|
||||||
|
{
|
||||||
|
return flagValue > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool UserHasFacePhoto(int enrollId, out string faceflag, out string photourl, out string error)
|
||||||
|
{
|
||||||
|
faceflag = null;
|
||||||
|
photourl = null;
|
||||||
|
error = null;
|
||||||
|
if (!TryGetUserProfile(enrollId, out faceflag, out photourl, out _, out error))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ProfileIndicatesFaceEnrolled(faceflag, photourl))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = "no face enrolled";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool TryUploadDbToDeviceTemplate(int enrollId, string name, DbToDeviceUploadPlan plan, out string error)
|
||||||
|
{
|
||||||
|
error = null;
|
||||||
|
if (plan == null || !plan.HasUploadPayload)
|
||||||
|
{
|
||||||
|
error = "template payload is empty";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int delayMs = GetIntSetting("TEMPLATE_DEVICE_DELAY_MS", 300);
|
||||||
|
|
||||||
|
if (string.Equals(plan.PushMode, "face", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
if (!TryEnsureUser(enrollId, name, out error))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (delayMs > 0)
|
||||||
|
{
|
||||||
|
System.Threading.Thread.Sleep(delayMs);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TrySetFacePhotoOnly(enrollId, plan.Payload, out error);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!TryEnsureUser(enrollId, name, out error))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (delayMs > 0)
|
||||||
|
{
|
||||||
|
System.Threading.Thread.Sleep(delayMs);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!TrySetFaceTemplateRecord(enrollId, plan.Payload, plan.PushMode, out error))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool VerifyDbToDeviceTemplate(int enrollId, DbToDeviceUploadPlan plan, out string faceflag, out string photourl, out string error)
|
||||||
|
{
|
||||||
|
faceflag = null;
|
||||||
|
photourl = null;
|
||||||
|
error = null;
|
||||||
|
if (plan != null && plan.UseProfileVerification)
|
||||||
|
{
|
||||||
|
return UserHasFacePhoto(enrollId, out faceflag, out photourl, out error);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UserHasFaceTemplate(enrollId, out error))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public bool TryRestoreUserWithFaceTemplate(int enrollId, string name, string templatePayload, string pushMode, out string error)
|
public bool TryRestoreUserWithFaceTemplate(int enrollId, string name, string templatePayload, string pushMode, out string error)
|
||||||
{
|
{
|
||||||
error = null;
|
error = null;
|
||||||
|
|
@ -383,33 +596,255 @@ namespace HanvonF710XAttendanceService
|
||||||
return TryGetFaceRecord(enrollId, out _, out _, out error);
|
return TryGetFaceRecord(enrollId, out _, out _, out error);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Dictionary<string, object> Post(Dictionary<string, object> payload)
|
public HttpExchangeResult PostDetailed(Dictionary<string, object> payload)
|
||||||
{
|
{
|
||||||
string body = _json.Serialize(payload);
|
var result = new HttpExchangeResult
|
||||||
var req = (HttpWebRequest)WebRequest.Create(_baseUrl);
|
|
||||||
req.Method = "POST";
|
|
||||||
req.ContentType = "application/json; charset=utf-8";
|
|
||||||
req.Timeout = _timeoutMs;
|
|
||||||
req.ReadWriteTimeout = _timeoutMs;
|
|
||||||
req.KeepAlive = false;
|
|
||||||
byte[] bytes = Encoding.UTF8.GetBytes(body);
|
|
||||||
req.ContentLength = bytes.Length;
|
|
||||||
using (var stream = req.GetRequestStream())
|
|
||||||
{
|
{
|
||||||
stream.Write(bytes, 0, bytes.Length);
|
Url = _baseUrl,
|
||||||
|
Method = "POST",
|
||||||
|
RequestContentType = "application/json; charset=utf-8"
|
||||||
|
};
|
||||||
|
|
||||||
|
string body = _json.Serialize(payload ?? new Dictionary<string, object>());
|
||||||
|
result.RequestBodySanitized = HanvonHttpDiagnostics.SanitizeJsonBody(body);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var req = (HttpWebRequest)WebRequest.Create(_baseUrl);
|
||||||
|
req.Method = "POST";
|
||||||
|
req.ContentType = result.RequestContentType;
|
||||||
|
req.Timeout = _timeoutMs;
|
||||||
|
req.ReadWriteTimeout = _timeoutMs;
|
||||||
|
req.KeepAlive = false;
|
||||||
|
byte[] bytes = Encoding.UTF8.GetBytes(body);
|
||||||
|
req.ContentLength = bytes.Length;
|
||||||
|
using (var stream = req.GetRequestStream())
|
||||||
|
{
|
||||||
|
stream.Write(bytes, 0, bytes.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
using (var resp = (HttpWebResponse)req.GetResponse())
|
||||||
|
using (var reader = new StreamReader(resp.GetResponseStream(), Encoding.UTF8))
|
||||||
|
{
|
||||||
|
result.StatusCode = (int)resp.StatusCode;
|
||||||
|
result.ResponseHeaders = FormatResponseHeaders(resp);
|
||||||
|
string text = reader.ReadToEnd();
|
||||||
|
result.ResponseBody = HanvonHttpDiagnostics.SanitizeJsonBody(text);
|
||||||
|
result.ParsedResponse = ParseResponseBody(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (WebException wex)
|
||||||
|
{
|
||||||
|
result.Error = wex.Message;
|
||||||
|
if (wex.Response is HttpWebResponse errResp)
|
||||||
|
{
|
||||||
|
result.StatusCode = (int)errResp.StatusCode;
|
||||||
|
result.ResponseHeaders = FormatResponseHeaders(errResp);
|
||||||
|
using (var reader = new StreamReader(errResp.GetResponseStream() ?? Stream.Null, Encoding.UTF8))
|
||||||
|
{
|
||||||
|
string text = reader.ReadToEnd();
|
||||||
|
result.ResponseBody = HanvonHttpDiagnostics.SanitizeJsonBody(text);
|
||||||
|
result.ParsedResponse = ParseResponseBody(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
result.Error = ex.Message;
|
||||||
}
|
}
|
||||||
|
|
||||||
using (var resp = (HttpWebResponse)req.GetResponse())
|
return result;
|
||||||
using (var reader = new StreamReader(resp.GetResponseStream(), Encoding.UTF8))
|
}
|
||||||
|
|
||||||
|
public void DiagnoseDbToDeviceEmployee(
|
||||||
|
int enrollId,
|
||||||
|
string empId,
|
||||||
|
string displayName,
|
||||||
|
string templatePayload,
|
||||||
|
string pushMode,
|
||||||
|
TextWriter logWriter)
|
||||||
|
{
|
||||||
|
if (logWriter == null) throw new ArgumentNullException(nameof(logWriter));
|
||||||
|
|
||||||
|
logWriter.WriteLine($"[DB_TO_DEVICE] DIAG emp={empId} enrollid={enrollId} target={_baseUrl}");
|
||||||
|
logWriter.WriteLine($"[DB_TO_DEVICE] DIAG template {HanvonHttpDiagnostics.DescribeTemplatePayload(templatePayload, pushMode)}");
|
||||||
|
|
||||||
|
var login = PostDetailed(new Dictionary<string, object>
|
||||||
{
|
{
|
||||||
string text = reader.ReadToEnd();
|
{ "cmd", "login" },
|
||||||
if (string.IsNullOrWhiteSpace(text))
|
{ "username", MachineScope.GetDeviceUsername() },
|
||||||
{
|
{ "password", _password },
|
||||||
return new Dictionary<string, object>();
|
{ "rememberMe", false }
|
||||||
}
|
});
|
||||||
return _json.Deserialize<Dictionary<string, object>>(text)
|
HanvonHttpDiagnostics.WriteExchange(logWriter, "LOGIN", empId, login);
|
||||||
?? new Dictionary<string, object>();
|
|
||||||
|
var listBefore = PostDetailed(new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
{ "cmd", "getuserlist" },
|
||||||
|
{ "password", _password },
|
||||||
|
{ "stn", 1 }
|
||||||
|
});
|
||||||
|
HanvonHttpDiagnostics.WriteExchange(logWriter, "USERLIST_BEFORE", empId, listBefore);
|
||||||
|
|
||||||
|
var profileBefore = PostDetailed(new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
{ "cmd", "getuserinfo" },
|
||||||
|
{ "password", _password },
|
||||||
|
{ "enrollid", enrollId }
|
||||||
|
});
|
||||||
|
HanvonHttpDiagnostics.WriteExchange(logWriter, "VERIFY_PROFILE_BEFORE", empId, profileBefore);
|
||||||
|
|
||||||
|
var recordBefore = PostDetailed(new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
{ "cmd", "getuserinfo" },
|
||||||
|
{ "password", _password },
|
||||||
|
{ "enrollid", enrollId },
|
||||||
|
{ "backupnum", GetIntSetting("DEVICE_FACE_BACKUPNUM", 50) }
|
||||||
|
});
|
||||||
|
HanvonHttpDiagnostics.WriteExchange(logWriter, "VERIFY_RECORD_BEFORE", empId, recordBefore);
|
||||||
|
|
||||||
|
var ensurePayload = new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
{ "cmd", "setuserinfo" },
|
||||||
|
{ "password", _password },
|
||||||
|
{ "enrollid", enrollId },
|
||||||
|
{ "name", displayName ?? enrollId.ToString() },
|
||||||
|
{ "department", "" },
|
||||||
|
{ "shiftid", 1 },
|
||||||
|
{ "admin", 0 },
|
||||||
|
{ "pwd", 0 },
|
||||||
|
{ "card", 0 },
|
||||||
|
{ "zoneid", 0 },
|
||||||
|
{ "groupid", 0 },
|
||||||
|
{ "access_times", 0 },
|
||||||
|
{ "verifymode", 0 },
|
||||||
|
{ "birthday", "" },
|
||||||
|
{ "starttime", "" },
|
||||||
|
{ "endtime", "" },
|
||||||
|
{ "userprofile", "" }
|
||||||
|
};
|
||||||
|
var ensure = PostDetailed(ensurePayload);
|
||||||
|
HanvonHttpDiagnostics.WriteExchange(logWriter, "SEND ensure_user setuserinfo", empId, ensure);
|
||||||
|
|
||||||
|
var templatePayloadReq = new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
{ "cmd", "setuserinfo" },
|
||||||
|
{ "password", _password },
|
||||||
|
{ "enrollid", enrollId }
|
||||||
|
};
|
||||||
|
string templateField;
|
||||||
|
if (string.Equals(pushMode, "face", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
templatePayloadReq["face"] = templatePayload;
|
||||||
|
templateField = "face";
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
templatePayloadReq["backupnum"] = GetIntSetting("DEVICE_FACE_BACKUPNUM", 50);
|
||||||
|
templatePayloadReq["record"] = templatePayload;
|
||||||
|
templateField = "record";
|
||||||
|
}
|
||||||
|
logWriter.WriteLine($"[DB_TO_DEVICE] emp={empId} SEND template_field={templateField} enrollid={enrollId} employee_number={displayName}");
|
||||||
|
var push = PostDetailed(templatePayloadReq);
|
||||||
|
HanvonHttpDiagnostics.WriteExchange(logWriter, "SEND template setuserinfo", empId, push);
|
||||||
|
|
||||||
|
int delayMs = GetIntSetting("TEMPLATE_DEVICE_DELAY_MS", 300);
|
||||||
|
if (delayMs > 0) System.Threading.Thread.Sleep(delayMs);
|
||||||
|
|
||||||
|
var profileAfter = PostDetailed(new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
{ "cmd", "getuserinfo" },
|
||||||
|
{ "password", _password },
|
||||||
|
{ "enrollid", enrollId }
|
||||||
|
});
|
||||||
|
HanvonHttpDiagnostics.WriteExchange(logWriter, "VERIFY profile getuserinfo (no backupnum)", empId, profileAfter);
|
||||||
|
|
||||||
|
var recordAfter = PostDetailed(new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
{ "cmd", "getuserinfo" },
|
||||||
|
{ "password", _password },
|
||||||
|
{ "enrollid", enrollId },
|
||||||
|
{ "backupnum", GetIntSetting("DEVICE_FACE_BACKUPNUM", 50) }
|
||||||
|
});
|
||||||
|
HanvonHttpDiagnostics.WriteExchange(logWriter, "VERIFY record getuserinfo backupnum=50", empId, recordAfter);
|
||||||
|
|
||||||
|
var listAfter = PostDetailed(new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
{ "cmd", "getuserlist" },
|
||||||
|
{ "password", _password },
|
||||||
|
{ "stn", 1 }
|
||||||
|
});
|
||||||
|
HanvonHttpDiagnostics.WriteExchange(logWriter, "USERLIST_AFTER", empId, listAfter);
|
||||||
|
|
||||||
|
var users = GetUserList(out string listErr);
|
||||||
|
var match = users.FirstOrDefault(u =>
|
||||||
|
string.Equals(u.DeviceUserId, empId, StringComparison.OrdinalIgnoreCase)
|
||||||
|
|| string.Equals(u.SerialNumber, empId, StringComparison.OrdinalIgnoreCase)
|
||||||
|
|| string.Equals(u.Name, empId, StringComparison.OrdinalIgnoreCase));
|
||||||
|
|
||||||
|
string recordValue = GetString(recordAfter.ParsedResponse, "record");
|
||||||
|
HanvonHttpDiagnostics.WriteResultSummary(
|
||||||
|
logWriter,
|
||||||
|
empId,
|
||||||
|
match != null,
|
||||||
|
match?.DeviceUserId,
|
||||||
|
match?.Name,
|
||||||
|
null,
|
||||||
|
IsSuccess(profileAfter.ParsedResponse),
|
||||||
|
GetString(profileAfter.ParsedResponse, "faceflag"),
|
||||||
|
GetString(profileAfter.ParsedResponse, "photourl"),
|
||||||
|
!string.IsNullOrWhiteSpace(recordValue),
|
||||||
|
recordValue?.Length ?? 0,
|
||||||
|
HanvonHttpDiagnostics.DescribeTemplatePayload(templatePayload, pushMode));
|
||||||
|
|
||||||
|
logWriter.WriteLine($"[DB_TO_DEVICE] emp={empId} SEND_OK_MEANS ensure_result={IsSuccess(ensure.ParsedResponse)} template_result={IsSuccess(push.ParsedResponse)} (Hanvon JSON result=true only, not proof of stored face)");
|
||||||
|
logWriter.WriteLine($"[DB_TO_DEVICE] emp={empId} VERIFY_FAIL_REASON={(string.IsNullOrWhiteSpace(recordValue) ? "getuserinfo backupnum=50 returned empty record field" : "record present")}");
|
||||||
|
if (!string.IsNullOrWhiteSpace(listErr))
|
||||||
|
{
|
||||||
|
logWriter.WriteLine($"[DB_TO_DEVICE] getuserlist_err={listErr}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Dictionary<string, object> Post(Dictionary<string, object> payload)
|
||||||
|
{
|
||||||
|
var detailed = PostDetailed(payload);
|
||||||
|
if (detailed.ParsedResponse != null && detailed.ParsedResponse.Count > 0)
|
||||||
|
{
|
||||||
|
return detailed.ParsedResponse;
|
||||||
|
}
|
||||||
|
if (!string.IsNullOrWhiteSpace(detailed.Error) && detailed.StatusCode == 0)
|
||||||
|
{
|
||||||
|
throw new IOException(detailed.Error);
|
||||||
|
}
|
||||||
|
return detailed.ParsedResponse ?? new Dictionary<string, object>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Dictionary<string, object> ParseResponseBody(string text)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(text))
|
||||||
|
{
|
||||||
|
return new Dictionary<string, object>();
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return new JavaScriptSerializer { MaxJsonLength = int.MaxValue }
|
||||||
|
.Deserialize<Dictionary<string, object>>(text) ?? new Dictionary<string, object>();
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return new Dictionary<string, object>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string FormatResponseHeaders(HttpWebResponse resp)
|
||||||
|
{
|
||||||
|
if (resp?.Headers == null) return "";
|
||||||
|
var pairs = new List<string>();
|
||||||
|
foreach (string key in resp.Headers.AllKeys)
|
||||||
|
{
|
||||||
|
pairs.Add(key + "=" + resp.Headers[key]);
|
||||||
|
}
|
||||||
|
return string.Join("; ", pairs);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool IsSuccess(Dictionary<string, object> resp)
|
private static bool IsSuccess(Dictionary<string, object> resp)
|
||||||
|
|
@ -463,12 +898,12 @@ namespace HanvonF710XAttendanceService
|
||||||
string name = GetString(row, "name") ?? "";
|
string name = GetString(row, "name") ?? "";
|
||||||
string timeStr = GetString(row, "time") ?? "";
|
string timeStr = GetString(row, "time") ?? "";
|
||||||
if (!DateTime.TryParse(timeStr, out DateTime time)) return;
|
if (!DateTime.TryParse(timeStr, out DateTime time)) return;
|
||||||
string acNo = !string.IsNullOrWhiteSpace(name) ? name.Trim() : enroll.Trim();
|
string acNo = enroll.Trim();
|
||||||
if (string.IsNullOrWhiteSpace(acNo)) return;
|
if (string.IsNullOrWhiteSpace(acNo)) return;
|
||||||
list.Add(new HttpLogRecord
|
list.Add(new HttpLogRecord
|
||||||
{
|
{
|
||||||
EnrollId = enroll,
|
EnrollId = enroll.Trim(),
|
||||||
Name = name,
|
Name = name.Trim(),
|
||||||
AcNo = acNo,
|
AcNo = acNo,
|
||||||
CheckTime = time,
|
CheckTime = time,
|
||||||
Mode = GetInt(row, "mode"),
|
Mode = GetInt(row, "mode"),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue