SOAP service exception after second call - soap

I created a SOAP service that fetches some data from a remote server.
After second call I always get an exception:
stackTrace: org.w3c.dom.DOMException: WRONG_DOCUMENT_ERR: A node is used in a different document than the one that created it.
Any ideas what could be wrong?
function getInstance () {
return LocalServiceRegistry.createService('SaveNewCustomerService', new SaveNewCustomerServiceObject());
}
function SaveNewCustomerServiceObject() {};
SaveNewCustomerServiceObject.prototype.initServiceClient = function() {
this.webReference = webreferences.CustomerWS;
return this.webReference.getDefaultService();
}
SaveNewCustomerServiceObject.prototype.createRequest = function(svc, params) {
return params;
}
SaveNewCustomerServiceObject.prototype.execute = function(svc, requestObject) {
var customerRequestObjTest = new webreferences.CustomerWS.SaveNewCustomer();
if (requestObject != null) {
setObj(); //reduced
}
var result;
try{
result = svc.serviceClient.saveNewCustomer(customerRequestObjTest);
var a =result;
}catch(ex){
var e = ex; //
if(e.faultString == "Import error"){
log.info("Import error" + e.faultDetail);
}else{
log.info(e.faultDetail);
}
}
return result;
}
SaveNewCustomerServiceObject.prototype.parseResponse = function(svc, responseObject) {
return responseObject;
}

Related

Using Post Request return a multiple values in Unity

I am new to Unity i have created a Post Request from that i want to return the Authentication-Token Header and authorization header and some required json data here is my code
private IEnumerator BasketId()
{
string url = "http://hololens5.northeurope.cloudapp.azure.com/INTERSHOP/rest/WFS/inSPIRED-inTRONICS-Site/-/baskets/";
using (UnityWebRequest request = UnityWebRequest.Post(url, "Hello"))
{
yield return request.SendWebRequest();
string token = request.GetResponseHeader("Authentication-token");
if (request.isNetworkError || request.isHttpError)
{
Debug.Log(request.error);
}
else
{
string jsonResut = System.Text.Encoding.UTF8.GetString(request.downloadHandler.data);
obj = JsonConvert.DeserializeObject<BasketId>(jsonResut);
Debug.Log(obj.Uri);
Debug.Log("Authentication-Token: " + token);
yield return obj.Title;
yield return token;
}
}
}
so i could i return the values. Please help me.
Because Coroutine is not immediate (blocking) so you won't be able to return the response directly. What you need to do is to have an event or callback that will be called when your request completed.
Here is how you can achieve it by passing the callback as argument:
private IEnumerator GetBasketId(System.Action<string, BasketId> callback)
{
string url = "http://hololens5.northeurope.cloudapp.azure.com/INTERSHOP/rest/WFS/inSPIRED-inTRONICS-Site/-/baskets/";
using (UnityWebRequest request = UnityWebRequest.Post(url, "Hello"))
{
yield return request.SendWebRequest();
if (request.isNetworkError || request.isHttpError)
{
Debug.Log(request.error);
if (callback != null)
{
callback(null, null);
}
// callback?.Invoke(null, null); // for short
}
else
{
if (callback != null)
{
string token = request.GetResponseHeader("Authentication-token");
string jsonResut = System.Text.Encoding.UTF8.GetString(request.downloadHandler.data);
obj = JsonConvert.DeserializeObject<BasketId>(jsonResut);
if (callback != null)
{
callback(token, obj);
}
// callback?.Invoke(token, obj); // for short
}
}
}
}
so when you want to start the request simply call something like:
StartCoroutine(GetBasketId((token, basketId) =>
{
if (string.IsNullOrEmpty(token))
{
// Handle error
}
else
{
// Handle success
Debug.Log("Token: " + token);
Debug.Log(basketId.Title);
}
});

mybatis interceptor sql log process

i make mybatis sqllog intercepor in my project.
in case. #{__frch_CUST_0} #{__frch_CUST_1} ~~~ #{__frch_CUST_N}
how can i get parameters value "__frch_CUST_n" ?
// mybatis interceptor sql log function
public String getSqlLog(StatementHandler handler)
{
String sql = handler.getBoundSql().getSql();
Object param = handler.getParameterHandler().getParameterObject();
List<ParameterMapping> paramMapping = handler.getBoundSql().getParameterMappings();
// change \? value to replace point
for(ParameterMapping mapping:paramMapping)
{
sql = sql.replaceFirst("\\?", "#{"+mapping.getProperty()+"}");
}
for(ParameterMapping mapping:paramMapping)
{
String sqlparam = "#{"+mapping.getProperty()+"}";
String sqlparamname = mapping.getProperty();
Object sqlparamvalue = ((Map) param).get(sqlparamname);
if( !sqlparamname.startsWith("__frch_") )
{
if(isNull(sqlparamvalue))
{
sql = sql.replace(sqlparam, "NULL");
}
else
{
if(sqlparamvalue instanceof String)
{
try
{
sql = sql.replace(sqlparam, "'"+getSQLString(sqlparamvalue.toString())+"'");
}
catch(Exception e)
{
sql = sql.replace(sqlparam, "'"+getSQLString(sqlparamvalue.toString())+"'");
}
}
else
{
sql = sql.replace(sqlparam, sqlparamvalue.toString());
}
}
}
else
{
**// HOW CAN I DO HERE?**
}
}
return sql;
}
thank you for read my question..
i resolve my self.
mybatis make new arrayList parameter. and use it.
example list value
DATE = ['20180101','20180102','20180103'];
STEP = ['PLAN', 'MAKE', 'SETUP'];
__frch_DATE_0
__frch_DATE_1
__frch_DATE_2
__frch_STEP_3
__frch_STEP_4
__frch_STEP_5
mybatis __frch_ = ['20180101','20180102','20180103','PLAN', 'MAKE', 'SETUP']
so i use it. my question is resolved..
public String getSqlLog(StatementHandler handler)
{
String sql = handler.getBoundSql().getSql();
Object param = handler.getParameterHandler().getParameterObject();
List<ParameterMapping> paramMapping = handler.getBoundSql().getParameterMappings();
List foreachlist = new ArrayList();
for(ParameterMapping mapping:paramMapping)
{
sql = sql.replaceFirst("\\?", "#{"+mapping.getProperty()+"}");
}
for(ParameterMapping mapping:paramMapping)
{
String sqlparam = "#{"+mapping.getProperty()+"}";
String sqlparamname = mapping.getProperty();
Object sqlparamvalue = ((Map) param).get(sqlparamname);
if( !sqlparamname.startsWith("__frch_") )
{
if(isNull(sqlparamvalue))
{
sql = sql.replace(sqlparam, "NULL");
}
else
{
if(sqlparamvalue instanceof String)
{
try
{
sql = sql.replace(sqlparam, "'"+getSQLString(sqlparamvalue.toString())+"'");
}
catch(Exception e)
{
sql = sql.replace(sqlparam, "'"+getSQLString(sqlparamvalue.toString())+"'");
}
}
else
{
sql = sql.replace(sqlparam, sqlparamvalue.toString());
}
}
}
else
{
if( foreachlist.size() == 0 )
{
Map parammap = (Map)param;
Iterator iterator = parammap.keySet().iterator();
while(iterator.hasNext())
{
String key = iterator.next().toString();
Object value = (Object)parammap.get(key);
if( value instanceof List )
{
List valuelist = (List)value;
for(int i=0;i<valuelist.size();i++)
{
foreachlist.add(valuelist.get(i));
}
}
}
}
String buff = sqlparamname.split("__frch_")[1];
int index = Integer.parseInt(buff.substring(buff.lastIndexOf("_")+1));
try
{
sql = sql.replace(sqlparam, "'"+getSQLString((String)foreachlist.get(index))+"'");
}
catch(Exception e)
{
;
}
}
}
return sql;
}

opcua session was closed by client

I have written the attached OpcUaConnector class for opc-ua connection related activities.
But it is not handling session. For example:
In opc ua configuration disabled the endpoint
In kepserver configuration did runtime > reinitializing
The windows service is throwing:
Source : system.Reactive.Core
InnerException : The session was closed by client
and stopping the windows service, as this error goes unhandled.
Can some one suggest how to handle session in opc-ua?
public class OpcUaConnector
{
private static SimplerAES simplerAES = new SimplerAES();
private DataContainer dataCointainer = null;
private UaTcpSessionChannel channel;
private string opcServerName = string.Empty;
private string opcUserId = string.Empty;
private string opcPassword = string.Empty;
private static ILog LogOpcStore;
private static System.IDisposable token;
private static uint id;
public OpcConnector(ILog Log)
{
IntializeLogOpcStore(Log);
}
private static void IntializeLogOpcStore(ILog Log)
{
LogOpcStore = Log;
}
public async Task OpenOpcConnection()
{
try
{
if ((!string.IsNullOrEmpty(this.opcServerName) & (this.opcServerName != AppMain.MyAppSettings.OpcServer)) ||
(!string.IsNullOrEmpty(this.opcUserId) & (this.opcUserId != AppMain.MyAppSettings.OpcUserId)) ||
(!string.IsNullOrEmpty(this.opcPassword) & (this.opcPassword != AppMain.MyAppSettings.OpcPassword)))
{
await channel.CloseAsync();
this.opcServerName = AppMain.MyAppSettings.OpcServer;
this.opcUserId = AppMain.MyAppSettings.OpcUserId;
this.opcPassword = AppMain.MyAppSettings.OpcPassword;
}
if (channel==null || (channel != null && (channel.State == CommunicationState.Closed || channel.State == CommunicationState.Faulted)))
{
var appDescription = new ApplicationDescription()
{
ApplicationName = "MyAppName",
ApplicationUri = $"urn:{System.Net.Dns.GetHostName()}:MyAppName",
ApplicationType = ApplicationType.Client,
};
//application data won't be deleted when uninstall
var certificateStore = new DirectoryStore(
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), MyAppName", "pki"),
true, true
);
//if the Ethernet cable unplugs or the Wifi drops out,
//you have some timeouts that can keep the session open for a while.
//There is a SessionTimeout (default of 2 min).
this.channel = new UaTcpSessionChannel(
appDescription,
certificateStore,
SignInOpc,
AppMain.MyAppSettings.OpcServer,
null,
options: new UaTcpSessionChannelOptions { SessionTimeout = 120000 });
await channel.OpenAsync();
//LogOpcStore.Info(String.Format("Opc connection sucessful"));
}
this.opcServerName = AppMain.MyAppSettings.OpcServer;
this.opcUserId = AppMain.MyAppSettings.OpcUserId;
this.opcPassword = AppMain.MyAppSettings.OpcPassword;
}
catch (Exception ex)
{
ServiceException serviceException = new ServiceException(ex.HResult + " " + ex.Message, "C052");
throw serviceException;
}
}
private static async Task RecursivelyFindNode(UaTcpSessionChannel channel, NodeId nodeid)
{
BrowseRequest browseRequest = new BrowseRequest
{
NodesToBrowse = new BrowseDescription[] { new BrowseDescription { NodeId = nodeid, BrowseDirection = BrowseDirection.Forward, ReferenceTypeId = NodeId.Parse(ReferenceTypeIds.HierarchicalReferences), NodeClassMask = (uint)NodeClass.Variable | (uint)NodeClass.Object, IncludeSubtypes = true, ResultMask = (uint)BrowseResultMask.All } },
};
BrowseResponse browseResponse = await channel.BrowseAsync(browseRequest);
foreach (var rd1 in browseResponse.Results[0].References ?? new ReferenceDescription[0])
{
uint chid = AppMain.MyTagDatabase.GetClientHandleByTag(rd1.DisplayName.ToString());
if (chid > 0)
{
AppMain.MyTagDatabase.UpdateNodeByClientHandle(chid, rd1.NodeId.ToString());
}
await RecursivelyFindNode(channel, ExpandedNodeId.ToNodeId(rd1.NodeId, channel.NamespaceUris));
}
}
public async Task CreateSubscription(DataContainer dc)
{
double curReadingValue;
try
{
dataCointainer = dc;
await RecursivelyFindNode(channel, NodeId.Parse(ObjectIds.RootFolder));
if (AppMain.MyTagDatabase.GetCntTagsNotInOpcServer() == AppMain.MyTagDatabase.GetTagCount())
{
//no need to create subscription
return;
}
//subscription timeout that is the product of PublishingInterval * LifetimeCount:
var subscriptionRequest = new CreateSubscriptionRequest
{
RequestedPublishingInterval = 1000f,
RequestedMaxKeepAliveCount = 30,
RequestedLifetimeCount = 30 * 3,
PublishingEnabled = true,
};
var subscriptionResponse = await channel.CreateSubscriptionAsync(subscriptionRequest);
id = subscriptionResponse.SubscriptionId;
var itemsToCreate = new MonitoredItemCreateRequest[AppMain.MyTagDatabase.GetTagHavingNodeCount()];
int i = 0;
foreach (var item in AppMain.MyTagDatabase.GetMyTagDatabase())
{
var itemKey = item.Key;
var itemValue = item.Value;
itemsToCreate[i] = new MonitoredItemCreateRequest { ItemToMonitor = new ReadValueId { NodeId = NodeId.Parse(itemValue.NodeId), AttributeId = AttributeIds.Value }, MonitoringMode = MonitoringMode.Reporting, RequestedParameters = new MonitoringParameters { ClientHandle = itemKey, SamplingInterval = -1, QueueSize = 0, DiscardOldest = true } };
i++;
}
var itemsRequest = new CreateMonitoredItemsRequest
{
SubscriptionId = id,
ItemsToCreate = itemsToCreate,
};
var itemsResponse = await channel.CreateMonitoredItemsAsync(itemsRequest);
token = channel.Where(pr => pr.SubscriptionId == id).Subscribe(pr =>
{
// loop thru all the data change notifications
// receiving data change notifications here
var dcns = pr.NotificationMessage.NotificationData.OfType<DataChangeNotification>();
foreach (var dcn in dcns)
{
foreach (var min in dcn.MonitoredItems)
{
MyTag MyTag = new MyTag();
bool hasValue = AppMain.MyTagDatabase.GetMyTag(min.ClientHandle, out MyTag);
if (hasValue)
{
if (double.TryParse(min.Value.Value.ToString(), out curReadingValue))
{
//LogOpcStore.Info(String.Format("ClientHandle : {0} TagName : {1} SourceTimestamp : {2} ServerTimeStamp : {3} curReadingValue : {4}", min.ClientHandle, MyTag.TagName, min.Value.SourceTimestamp, min.Value.ServerTimestamp, curReadingValue));
AddDataPointToContainer(1, MyTag.TagName, min.Value.SourceTimestamp, curReadingValue);
}
}
}
}
});
}
catch (Exception ex)
{
//If the interruption lasts longer than these timeouts then the SessionChannel and Subscriptions will need to be recreated.
channel = null;
FatalServiceException fatalserviceException = new FatalServiceException(ex.Message, "C052");
throw fatalserviceException;
}
}
public async Task DeleteSubscription()
{
try
{
var request = new DeleteSubscriptionsRequest
{
SubscriptionIds = new uint[] { id }
};
await channel.DeleteSubscriptionsAsync(request);
token.Dispose();
}
catch (Exception ex)
{
ServiceException serviceException = new ServiceException(ex.Message, "C052");
throw serviceException;
}
}
private static async Task<IUserIdentity> SignInOpc(EndpointDescription endpoint)
{
IUserIdentity userIdentity = null;
if (endpoint.UserIdentityTokens.Any(p => p.TokenType == UserTokenType.Anonymous))
{
userIdentity = new AnonymousIdentity();
}
else if (endpoint.UserIdentityTokens.Any(p => p.TokenType == UserTokenType.UserName))
{
var userName = AppMain.MyAppSettings.OpcUserId;
var password = simplerAES.Decrypt(AppMain.MyAppSettings.OpcPassword);
userIdentity = new UserNameIdentity(userName, password);
}
return userIdentity;
}
private void AddDataPointToContainer(int dataType, string source, DateTime SourceTimestampUTC, double value)
{
ConditionValue conditionValue = new ConditionValue();
long timestamp = AppMain.ServerSyncTimeStore.ConvertDateTimeToTimeStampUTC(SourceTimestampUTC);
conditionValue.dataType = dataType;
conditionValue.source = source;
conditionValue.timestamp = timestamp;
conditionValue.SourceTimestampUTC = SourceTimestampUTC;
conditionValue.LocalTime = SourceTimestampUTC.ToLocalTime();
conditionValue.value = value;
//LogOpcStore.Info(String.Format("TagName : {0} SourceTimestampUTC : {1} timestamp : {2} LocalTime : {3} curReadingValue : {4}", source, SourceTimestampUTC, timestamp, SourceTimestampUTC.ToLocalTime(), value));
dataCointainer.AddDataPoint(conditionValue);
}
}
I see you are using the project https://github.com/convertersystems/opc-ua-client.
When a server closes the session and socket (as happens when you reinitialize Kepware) the client receives immediate notification that causes the client channel to fault. A faulted channel cannot be reopened, it should be aborted and a new channel should be created.
I made this standalone test, to show that you may have to catch an exception and recreate the channel and subscription. The point of this test is to subscribe to the CurrentTime node and collect 60 datachanges. The test should last a minute. If you re-init the Kepware server in the middle of the test, the code catches the exception and recreates the channel and subscription.
[TestMethod]
public async Task OpcConnectorTest()
{
var count = 0;
UaTcpSessionChannel channel = null;
while (count < 60)
{
try
{
channel = new UaTcpSessionChannel(
this.localDescription,
this.certificateStore,
new AnonymousIdentity(),
EndpointUrl,
SecurityPolicyUris.None,
loggerFactory: this.loggerFactory);
await channel.OpenAsync();
// create the keep alive subscription.
var subscriptionRequest = new CreateSubscriptionRequest
{
RequestedPublishingInterval = 1000f,
RequestedMaxKeepAliveCount = 30,
RequestedLifetimeCount = 30 * 3,
PublishingEnabled = true,
};
var subscriptionResponse = await channel.CreateSubscriptionAsync(subscriptionRequest).ConfigureAwait(false);
var id = subscriptionResponse.SubscriptionId;
var token = channel.Where(pr => pr.SubscriptionId == id).Subscribe(pr =>
{
// loop thru all the data change notifications
var dcns = pr.NotificationMessage.NotificationData.OfType<DataChangeNotification>();
foreach (var dcn in dcns)
{
foreach (var min in dcn.MonitoredItems)
{
Console.WriteLine($"sub: {pr.SubscriptionId}; handle: {min.ClientHandle}; value: {min.Value}");
count++;
}
}
});
var itemsRequest = new CreateMonitoredItemsRequest
{
SubscriptionId = id,
ItemsToCreate = new MonitoredItemCreateRequest[]
{
new MonitoredItemCreateRequest { ItemToMonitor = new ReadValueId { NodeId = NodeId.Parse("i=2258"), AttributeId = AttributeIds.Value }, MonitoringMode = MonitoringMode.Reporting, RequestedParameters = new MonitoringParameters { ClientHandle = 12345, SamplingInterval = -1, QueueSize = 0, DiscardOldest = true } }
},
};
var itemsResponse = await channel.CreateMonitoredItemsAsync(itemsRequest);
while (channel.State == CommunicationState.Opened && count < 60)
{
await Task.Delay(1000);
}
}
catch (Exception ex)
{
Console.WriteLine($"Exception: {ex.GetType()}. {ex.Message}");
}
}
if (channel != null)
{
Console.WriteLine($"Closing session '{channel.SessionId}'.");
await channel.CloseAsync();
}
}
I know this is an old post, but I stumbled upon this problem as well. For those interested:
The problem is related to the subscription(s).
When the following code is run:
token = channel.Where(pr => pr.SubscriptionId == id).Subscribe(pr =>
{
// loop thru all the data change notifications
// receiving data change notifications here
var dcns = pr.NotificationMessage.NotificationData.OfType<DataChangeNotification>();
foreach (var dcn in dcns)
{
foreach (var min in dcn.MonitoredItems)
{
MyTag MyTag = new MyTag();
bool hasValue = AppMain.MyTagDatabase.GetMyTag(min.ClientHandle, out MyTag);
if (hasValue)
{
if (double.TryParse(min.Value.Value.ToString(), out curReadingValue))
{
//LogOpcStore.Info(String.Format("ClientHandle : {0} TagName : {1} SourceTimestamp : {2} ServerTimeStamp : {3} curReadingValue : {4}", min.ClientHandle, MyTag.TagName, min.Value.SourceTimestamp, min.Value.ServerTimestamp, curReadingValue));
AddDataPointToContainer(1, MyTag.TagName, min.Value.SourceTimestamp, curReadingValue);
}
}
}
}
});
Observable.subscribe() takes multiple arguments. You should include what to do in case of an error. For example:
token = channel.Where(pr => pr.SubscriptionId == id).Subscribe(
pr => { code to run normally... },
ex => { Log.Info(ex.Message); },
() => { }
);
See http://reactivex.io/documentation/operators/subscribe.html for more information.

How can I get all post ids for a Facebook page?

I am using https://graph.facebook.com/v2.4/page_id/posts?fields=id to get all post ids from a Facebook page, but I am running into an infinite loop issue with pagination due to paging.next property always returning a url. It looks like the last page points to the first page. How would I know I have reached the end of results.
Here is a code example:
public static Dictionary<string,string> GetPagePostIds(string accessToken, string pageId)
{
Dictionary<string, string> postIds = new Dictionary<string, string>();
StringBuilder sb = new StringBuilder(graphAPIURL);
sb.Append("/").Append(pageId).Append("/posts/?access_token=").Append(accessToken);
sb.Append("&fields=id");
string url = sb.ToString();
int pages = 0;
int rows = 0;
while (url != null)
{
System.Net.WebRequest req = System.Net.WebRequest.Create(url);
System.Net.WebResponse response = req.GetResponse();
string json = null;
using (System.IO.StreamReader sr = new System.IO.StreamReader(response.GetResponseStream()))
{
json = sr.ReadToEnd();
Console.WriteLine(json);
}
if (json != null)
{
pages++;
Dictionary<string, dynamic> data = (Dictionary<string, dynamic>)Newtonsoft.Json.JsonConvert.DeserializeObject(json, typeof(Dictionary<string, dynamic>));
if (data.ContainsKey("data"))
{
Newtonsoft.Json.Linq.JArray a = (Newtonsoft.Json.Linq.JArray)data["data"];
foreach (Newtonsoft.Json.Linq.JObject o in a)
{
rows++;
postIds.Add(o["id"].ToString(), o["id"].ToString());
}
}
if (data.ContainsKey("paging"))
{
try
{
if (data["paging"]["next"] == url)
{
//otherwise we will be stuck in the infinite loop, as next url of the last page is not null
break;
}
//if next link is present, there are more pages available
url = null;
url = data["paging"]["next"];
}
catch (Exception)
{
}
}
}
}
return postIds;
}
You can break the loop, if you reach to the point, where you only receive empty results.
So you just simply extend your while loop with a second condition. Here is some simple pseudocode:
while (url != null && resultsOnPage) {
[...]
if (data.ContainsKey("data") && data['data'].Count > 0 ) {
[...]
} else {
resultsOnPage = false;
}
[...]
}
Just leave the rest as it is.

Handling concurrency exceptions when passing the objects ids and timestamps using jQuery

I have the following business scenario inside my Asp.net MVC 4 asset management system :-
Scenario 1) A user selects multiple servers , then he selects a Rack Tag ,and click on
assign . so the selected servers will be assigned to the new Rack.
Scenario 2) And i want to check for any concurrency exception , if for example the selected
servers have been modified by another user since they were retrieved .
so i have wrote the following jQuery which will send the object ids+timestamps to the action method:-
$('body').on("click", "#transferSelectedAssets", function () {
var boxData = [];
$("input[name='CheckBoxSelection']:checked").each(function () {
boxData.push($(this).val());
});
var URL = "#Url.Content("~/Server/TransferSelectedServers")";
$.ajax({
type: "POST",
url: URL,
data: { ids: boxData.join(","), rackTo: $("#rackIDTo").val()}
,
success: function (data) {
addserver(data); })});
and inside the action method i have the following code:-
public ActionResult TransferSelectedServers(string ids, int? rackTo)
{
if (ModelState.IsValid)
{
try
{
var serverIDs = ids.Split(',');
int i = 0;
foreach (var serverinfo in serverIDs)
{
var split = serverinfo.Split('~');
var name = split[0];
//System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
byte[] bytearray = Encoding.Default.GetBytes(split[1]);
i++;
var server = repository.FindServer_JTechnology(Int32.Parse(name));
if (server == null)
return Json(new { IsSuccess = false, reload = true, description = " Some Servers might have been deleted, Transferre process has been cancelled .", rackid = rackFrom }, JsonRequestBehavior.AllowGet);
server.RackID = rackTo;
server.timestamp = bytearray;
string ADusername = User.Identity.Name.Substring(User.Identity.Name.IndexOf("\\") + 1);
repository.InsertOrUpdateServer(server, ADusername, server.Technology.IT360ID.Value, server.IT360SiteID, new bool(), server.Technology);
}
repository.Save();
return Json(new { IsSuccess = true, description = i + " Server/s Transferred Successfully To Rack " + }, JsonRequestBehavior.AllowGet);
}
catch (DbUpdateConcurrencyException e)
{
return Json(new { IsSuccess = false, reload = true, description = "records has been modified by antoehr user" }, JsonRequestBehavior.AllowGet);
}
catch (Exception e)
{
return Json(new { IsSuccess = false, reload = true, description = " Server/s Can not Be Transferred to the Selected Rack " }, JsonRequestBehavior.AllowGet);
}
}
return RedirectToAction("Details", new { id = rackTo });
}
and the repository method looks as follow:-
public void InsertOrUpdateServer(TMSServer server, string username, long assetid, long? siteid = 0, bool isTDMHW = false, Technology t = null)
{
server.IT360SiteID = siteid.Value;
tms.Entry(server).State = EntityState.Modified;
var technology = tms.Technologies.Single(a => a.TechnologyID == server.TMSServerID);
technology.IsManaged = t.IsManaged;
tms.Entry(technology).State = EntityState.Modified;
InsertOrUpdateTechnologyAudit(auditinfo);
}
}
but currently if two users selects the same servers and assign them to tow different racks , no concurrency exception will be raised ?
Can anyone advice ? baring in mind that if two users edit single object then one of them will get an concurrent exception message. so my timestamp column is defined correctly.
Thanks